Explorar el Código

dev: document auth and permissions

KernelDeimos hace 4 días
padre
commit
3290440f4b
Se han modificado 2 ficheros con 242 adiciones y 0 borrados
  1. 63 0
      src/backend/doc/A-and-A/auth.md
  2. 179 0
      src/backend/doc/A-and-A/permission.md

+ 63 - 0
src/backend/doc/A-and-A/auth.md

@@ -0,0 +1,63 @@
+# Authentication Documentation
+
+## Concepts
+
+### Actor
+
+An "Actor" is an entity that can be authenticated. The following types of
+actors are currently supported by Puter:
+- **UserActorType** - represents a user and is identified by a user's UUID
+- **AppUnderUserActorType** - represents an app running in an iframe from a
+  `puter.site` domain or another origin and is identified by a user's UUID
+  and an app's UUID together.
+- **AccessTokenActorType** - not widely currently, but Puter supports
+  a concept called "access tokens". Any user can create an access token and
+  then grant any permissions they want to that access token. The access
+  token will have those permissions granted provided that the user who
+  created the access token does as well (via permission cascade)
+- **SiteActorType** - represents a `puter.site` website accessing Puter's API.
+- **SystemActorType** - internal representation of the actor during a privileged
+  backend operation. This actor cannot be authenticated in a request.
+  This actor does not represent the `system` user.
+
+### Token
+
+- **Legacy** - legacy tokens result in an error response
+- **Session** - this token is a JWT with a claim for the UUID of an entry in
+  server memory or the database that we call a "session". This entry associates
+  the token to a user and some metadata for security auditing purposes.
+  Revoking the session entry disables the token.
+  This type of token resolves to an actor with **UserActorType**.
+- **AppUnderUser** - this token is a JWT with a claim for an app UUID and a
+  claim for a session UUID.
+  Revoking the session entry disables the token.
+  This type of token resolves to an actor with **AppUnderUserActorType**.
+- **AccessToken** - this token is a JWT with three claims:
+  - A session UUID
+  - An optional App UUID
+  - A UUID representing the access token for permission associations
+  The session or session+app creates a **UserActorType** or
+  **AppUnderUserActorType** actor respectively. This actor is called
+  the "authorizor". This actor is aggregated by an **AccessTokenActorType**
+  actor which becomes the effective actor for a request.
+- **ActorSite** - this token is a JWT with a claim for a site UID.
+  The site UID is associated with an origin, generally a `puter.site`
+  subdomain.
+
+## Components
+
+### Auth Middleware
+
+There have so far been three iterations of the authentication middleware:
+- `src/backend/src/middleware/auth.js`
+- `src/backend/src/middleware/auth2.js`
+- `src/backend/src/middleware/configurable_auth.js`
+
+The newest implementation is `configurable_auth` and eventually the other
+two will be removed. There is no legacy behavior involved:
+- `auth` was rewritten to use `auth2`
+- `auth2` was rewritten to use `configurable_auth`
+
+The `configurable_auth` middleware accepts a parameter that can be specified
+if an endpoint is optionally authenticated. In this case, the request's
+`actor` will be `undefined` if there was no information for authentication.

+ 179 - 0
src/backend/doc/A-and-A/permission.md

@@ -0,0 +1,179 @@
+# Permission Documentation
+
+## Concepts
+
+### Permission
+
+A permission is a string composed of colon-delimited components which identifies
+a resource or functionality to which access can be controlled.
+
+For example, `fs:e8ac2973-287b-4121-a75d-7e0619eb8e87:read` is a permission which
+represents reading the file or directory with UUID `e8ac2973-287b-4121-a75d-7e0619eb8e87`.
+
+### Group
+
+A group has an owner and several member users. An owner decides what users are in the
+group and what users are not. Any user can grant permissions to the group.
+
+### Granting & Revoking
+
+Granting is the act of creating a permission association to a user or group from
+the current user. A permission association also holds an object called `extra`
+which holds additional claims associated with the permission association.
+These are arbitrary and can be used in any way by the subsystem or extension that
+is checking the permission. `extra` is usually just an empty object.
+
+Revoking is the act of removing a permission association.
+
+### Permission Options
+
+Permission options are an association between a permission and an actor that can not
+be revoked by another actor. For example, the user `ed` always has access to files
+under `/ed`. The user `system` always has all permissions granted. These can also be
+considered "terminals" because they will always be at
+the end of a pathway through granted permissions between users.
+This are also called "implied" permissions because they are implied by the system.
+
+### Permission Pathways
+
+A permission pathway is the path between users or groups that leads to a permission.
+
+For example, `ed` can grant the permission `a:b` to `fred`, then `fred` can grant
+that permission to the group `cool_group`, and then `alice` may be in the group
+`cool_group`. Assuming `ed` holds the implied permission `a:b`, a permission path
+exists between `alice` and `ed` via `cool_group` and `fred`:
+
+```
+alice <--<> cool_group <-- fred <-- ed (a:b)
+```
+
+If any link in this chain breaks the permission is effectively revoked from `alice`
+unless there is another pathway leading to a valid permission option for `a:b`.
+
+### Reading - AKA Permission Scan Result
+
+A permission reading is a JSON-serializable object which contains all the pathways
+a specified actor has to permissions options matching the specified permission strings.
+
+The following is an example reading for the user `ed3` on the permission
+`fs:24729b88-a4c5-4990-ad4e-272b87895732:read`. This file is owned by the
+user `admin` who shared it with `ed3`.
+
+```
+[
+  {
+    "$": "explode",
+    "from": "fs:24729b88-a4c5-4990-ad4e-272b87895732:read",
+    "to": [
+      "fs:24729b88-a4c5-4990-ad4e-272b87895732:read",
+      "fs:24729b88-a4c5-4990-ad4e-272b87895732:write",
+      "fs:24729b88-a4c5-4990-ad4e-272b87895732",
+      "fs"
+    ]
+  },
+  {
+    "$": "path",
+    "via": "user",
+    "has_terminal": true,
+    "permission": "fs:24729b88-a4c5-4990-ad4e-272b87895732:read",
+    "data": {},
+    "holder_username": "ed3",
+    "issuer_username": "admin",
+    "reading": [
+      {
+        "$": "explode",
+        "from": "fs:24729b88-a4c5-4990-ad4e-272b87895732:read",
+        "to": [
+          "fs:24729b88-a4c5-4990-ad4e-272b87895732:read",
+          "fs:24729b88-a4c5-4990-ad4e-272b87895732:write",
+          "fs:24729b88-a4c5-4990-ad4e-272b87895732",
+          "fs"
+        ]
+      },
+      {
+        "$": "option",
+        "permission": "fs:24729b88-a4c5-4990-ad4e-272b87895732:read",
+        "source": "implied",
+        "by": "is-owner",
+        "data": {}
+      },
+      {
+        "$": "option",
+        "permission": "fs:24729b88-a4c5-4990-ad4e-272b87895732:write",
+        "source": "implied",
+        "by": "is-owner",
+        "data": {}
+      },
+      {
+        "$": "option",
+        "permission": "fs:24729b88-a4c5-4990-ad4e-272b87895732",
+        "source": "implied",
+        "by": "is-owner",
+        "data": {}
+      },
+      {
+        "$": "time",
+        "value": 19
+      }
+    ]
+  },
+  {
+    "$": "time",
+    "value": 20
+  }
+]
+```
+
+Each object in the reading has a property named `$` which is the type for the object.
+The most fundamental types for permission readings are `path` and `option`. A path
+always contains another reading, which contains more paths or options. An option
+specifies the permission string, the name of the rule that granted the permission,
+and a data object which may hold additional claims.
+
+Readings begin with an `explode` if there are multiple strings that may grant the
+permission.
+
+Readings end with a `time` that repots how long the reading took to help manage
+the potential performance impact of complex permission graphs.
+
+## Permission Service
+
+### check(actor, permissions)
+
+Returns true if the current actor has a path to any permission options matching
+any of the permission strings specified by `permissions`. This is done by invoking
+`scan()` and returning `true` if there are more than 0 permission options.
+
+### scan(actor, permissions)
+
+Returns a "reading". A permission reading is a JSON-serializable structure.
+Readings are described above.
+
+## Permission Scan Sequence
+
+The `scan()` method of **PermissionService** invokes the permission scan sequence.
+The permission scan sequence is a [Sequence](https://github.com/HeyPuter/puter/blob/0e0bfd6d7c92eed5080518a099c9a66a2f2dc9ec/src/backend/src/codex/Sequence.js)
+that is defined in [scan-permission.js](src/backend/src/structured/sequence/scan-permission.js).
+It invokes many "permission scanners" which are defined in
+[permission-scanners.js](src/backend/src/unstructured/permission-scanners.js)
+
+The Permission Scan Sequence is as follows:
+- `grant_if_system` - if system user, push an option to the reading and stop
+- `rewrite_permission` - process the permission through any permission string
+  rewriters that were registered with PermissionService by other services.
+  For example, since path-based file permissions aren't currently supported
+  the FilesystemService regsiters a rewriter that converts any `fs:/`
+  permission into a corresponding UUID permission.
+- `explode_permission` - break the permission into multiple permissions
+  than are sufficient to grant the permission being scanned. For example if
+  there are multiple components, like `a.b.c`, having either permission `a.b` or
+  `a` granted implis having `a.b.c` granted. Other services can also register
+  "permission exploders" which handle non-hierarchical cases such as
+  `fs:AAAA:write` implying `fs:AAAA:read`.
+- `run_scanners` - run the permission scanners.
+
+Each permission scanner has a name, documentation text, and a scan function.
+The scan function has access to the scan sequence's context and can push
+objects onto the permission reading.
+
+For information on individual scanners, refer to permission-scanners.js.