# Profiles, grants, groups and denies A membership's home roles are where its authority starts. Profiles and grants add roles at other nodes, groups share grants among memberships, and denies take roles and operations away. All of them are read on every request ([How authorization works](authorization.md)). ## Profiles A **profile** is a named set of role keys from your `[authenticate] roles` vocabulary. A grant names a profile and never copies its roles, so changing a profile changes the authority of everyone it is granted to. ### Base profiles, in your repository `config/profiles.toml` declares the profiles every node of your product can use: ```toml [profiles.admin] roles = ["admin", "staff", "customer"] [profiles.staff] roles = ["staff"] [profiles.customer] roles = ["customer"] ``` `aircloud generate authentication` writes one profile per role of the vocabulary: the first role's profile (`admin` by convention) holds every role, as your product's first admin does, and each other profile holds its own role. Edit them as your product needs. Every role a profile names must be in the vocabulary (`profile.role_undeclared`). The release active in production carries them: its activation creates or updates them at the root (`/`). A declared profile you remove from the file is deleted when no grant references it; while one does, the profile is kept and the activation reports it, so you revoke those grants first. ### Runtime profiles, at a node ```sh aircloud profiles list aircloud profiles list --node /acme aircloud profiles put --node /acme --name auditor --roles viewer,exporter aircloud profiles remove --node /acme --name auditor ``` A runtime profile is defined at a node below the root and is visible there and at every node below it, never at a sibling or above. Whoever holds `tenant:org` defines profiles at its node or below, holding only roles it holds itself. A profile is removed only once no grant references it. The root holds the declared profiles only: change those in `config/profiles.toml`. ## Grants ```sh aircloud members grant 0198a3c4-… --path /acme/sales --profile editor --profile-node / --expires-at 2027-01-31T00:00:00Z aircloud members grants 0198a3c4-… aircloud members revoke 0198a3c4-… 0198a3c5-… ``` A **grant** confers a profile, named by its node and name (`--profile-node`, `--profile`), to one membership at one node (`--path`), until `--expires-at` or for good. Its node is at or below the membership's home. You grant only profiles whose every role you hold at that node, at a node at or below your own. An expired grant stops counting at its expiry, with nothing to run. `members invite --profile` makes the profile the new membership's non-expiring grant at its home — the way to give a client's admin their roles: ```sh aircloud members invite ada@example.com --path /acme --scopes tenant:org --profile admin --profile-node / ``` **The roles a membership holds at a record's node** are its home roles (when the node is at or below its home), plus the roles of each of its unexpired grants at that node or above, plus the roles of its groups' grants (below), minus every role a deny removes there. A grant at `/acme/sales` therefore reaches the records of `/acme/sales` and below, and nothing at `/acme/ops`. ## Groups ```sh aircloud groups create --node /acme --name night-shift aircloud groups add 0198a3c4-… --node /acme --name night-shift aircloud groups grant --node /acme --name night-shift --path /acme --profile editor --profile-node / aircloud groups list aircloud groups members --node /acme --name night-shift aircloud groups grants --node /acme --name night-shift aircloud groups remove 0198a3c4-… --node /acme --name night-shift aircloud groups revoke 0198a3c5-… --node /acme --name night-shift aircloud groups delete --node /acme --name night-shift ``` A **group** is defined at a node and holds memberships homed at or below that node. Each member holds every role the group's grants confer, at or below both the grant's node and the member's own home — never beyond the home. Adding a member to a group confers the group's roles, so you add one only when you hold every role the group's grants carry. A group is deleted only when it has no member and no grant. ## Denies ```sh aircloud denies create --path /acme --ops entity.delete --entity orders aircloud denies create --path /acme/interns --roles admin aircloud denies list aircloud denies delete 0198a3c6-… ``` A **deny** is a guardrail laid over a node and everything below it. `--roles` removes those roles from everyone acting there; `--ops` refuses those operations (`entity.read`, `entity.create`, `entity.update`, `entity.delete`) on one entity with `--entity`, or on every entity. A deny binds every actor at or below its node — members, group members, functions acting there, elevated aggregates, and you — and no grant, profile, owner rule or `write_roles` below can re-allow what it refuses. A deny is laid strictly below the node of whoever lays it, so a member can never deny a peer at its own node; you, acting at the root, may also deny at `/`. Only someone above the deny's node, or you, lifts it. ## Asking why `aircloud authz explain` names the grant, group, deny or record rule that decided a request, and `aircloud members review` lists the grants about to expire, the profiles nobody uses and the empty groups ([How authorization works](authorization.md#asking-why)). --- Rendered from aircloud 0.1.12 at commit d84a0ce6dae53629277f656d96d81549df36807e.