|
| 1 | +# Authz |
| 2 | + |
| 3 | +Package `authz` implements AuthoriZation for Coder. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Authorization defines what **permission** a **subject** has to perform **actions** to **objects**: |
| 8 | +- **Permission** is binary: *yes* (allowed) or *no* (denied). |
| 9 | +- **Subject** in this case is anything that implements interface `authz.Subject`. |
| 10 | +- **Action** here is an enumerated list of actions, but we stick to `Create`, `Read`, `Update`, and `Delete` here. |
| 11 | +- **Object** here is anything that implements `authz.Object`. |
| 12 | + |
| 13 | +## Permission Structure |
| 14 | + |
| 15 | +A **permission** is a rule that grants or denies access for a **subject** to perform an **action** on a **object**. |
| 16 | +A **permission** is always applied at a given **level**: |
| 17 | + |
| 18 | +- **site** level applies to all objects in a given Coder deployment. |
| 19 | +- **org** level applies to all objects that have an organization owner (`org_owner`) |
| 20 | +- **user** level applies to all objects that have an owner with the same ID as the subject. |
| 21 | + |
| 22 | +**Permissions** at a higher **level** always override permissions at a **lower** level. |
| 23 | + |
| 24 | +The effect of a **permission** can be: |
| 25 | +- **positive** (allows) |
| 26 | +- **negative** (denies) |
| 27 | +- **abstain** (neither allows or denies, not applicable) |
| 28 | + |
| 29 | +**Negative** permissions **always** override **positive** permissions at the same level. |
| 30 | +Both **negative** and **positive** permissions override **abstain** at the same level. |
| 31 | + |
| 32 | +This can be represented by the following truth table, where Y represents *positive*, N represents *negative*, and _ represents *abstain*: |
| 33 | + |
| 34 | +| Action | Positive | Negative | Result | |
| 35 | +|--------|----------|----------|--------| |
| 36 | +| read | Y | _ | Y | |
| 37 | +| read | Y | N | N | |
| 38 | +| read | _ | _ | _ | |
| 39 | +| read | _ | N | Y | |
| 40 | + |
| 41 | + |
| 42 | +## Permission Representation |
| 43 | + |
| 44 | +**Permissions** are represented in string format as `<sign>?<level>.<object>.<id>.<action>`, where: |
| 45 | + |
| 46 | +- `negated` can be either `+` or `-`. If it is omitted, sign is assumed to be `+`. |
| 47 | +- `level` is either `site`, `org`, or `user`. |
| 48 | +- `object` is any valid resource type. |
| 49 | +- `id` is any valid UUID v4. |
| 50 | +- `action` is `create`, `read`, `modify`, or `delete`. |
| 51 | + |
| 52 | +## Example Permissions |
| 53 | + |
| 54 | +- `+site.*.*.read`: allowed to perform the `read` action against all objects of type `devurl` in a given Coder deployment. |
| 55 | +- `-user.workspace.*.create`: user is not allowed to create workspaces. |
| 56 | + |
| 57 | +## Roles |
| 58 | + |
| 59 | +A *role* is a set of permissions. When evaluating a role's permission to form an action, all the relevant permissions for the role are combined at each level. Permissions at a higher level override permissions at a lower level. |
| 60 | + |
| 61 | +The following table shows the per-level role evaluation. |
| 62 | +Y indicates that the role provides positive permissions, N indicates the role provides negative permissions, and _ indicates the role does not provide positive or negative permissions. YN_ indicates that the value in the cell does not matter for the access result. |
| 63 | + |
| 64 | +| Role (example) | Site | Org | User | Result | |
| 65 | +|-----------------|------|-----|------|--------| |
| 66 | +| site-admin | Y | YN_ | YN_ | Y | |
| 67 | +| no-permission | N | YN_ | YN_ | N | |
| 68 | +| org-admin | _ | Y | YN_ | Y | |
| 69 | +| non-org-member | _ | N | YN_ | N | |
| 70 | +| user | _ | _ | Y | Y | |
| 71 | +| | _ | _ | N | N | |
| 72 | +| unauthenticated | _ | _ | _ | N | |
| 73 | + |
0 commit comments