Access policies
Every dashboard API request and every webhook delivery is checked against a chain of Cedar policies. Edit them at Org > Access (/org/access).
Levels
A request passes through the levels in order: instance, org, workspace, object. A level with no policies is skipped. A level with policies must permit the request, and a forbid at any level wins. A lower level can narrow access but never widen it.
Level | Scope fields | Governs |
|---|---|---|
| none | every org |
|
| the org's records |
|
| one workspace |
|
| one record |
The org is always the caller's own. No request field chooses it. Only an instance owner (an owner of org-sys) sees and edits instance policies.
Cross-org forbid
A principal never reaches a record outside its own org, and a principal with no org is refused everything. The engine enforces this before any policy runs, so it can't be edited or reset away. Denials name it instance-cross-org.
Shipped role policies
Every org is seeded with four org-level policies. Roles are owner, admin, developer and viewer. A workspace membership's role overrides the org role inside that workspace.
Policy | Roles | Grants |
|---|---|---|
| all four |
|
| developer, admin, owner |
|
| admin, owner | every action except deleting the org |
| owner | every action |
Don't give a stored policy a shipped ID: seeding and access reset --org overwrite those IDs with the shipped text.
Policy vocabulary
Actions: read, create, update, delete, approve, run, deliver, read_logs, read_secret, manage_members, manage_identities, manage_policies.
Entities are in the Archie namespace:
Archie::Identity, the principal. Attributesorgandrole. Its parent is its org, soprincipal in Archie::Org::"acme"works.Archie::Object, the resource. Attributesorg,workspaceandkind, plusownerandstatewhen the record has them.- Context:
addr(ipaddr),time(datetime),signature,run,step.
Resource kinds: org, workspace, source, event_type, mapping, binding, workflow, task, capture, secret, identity, policy, member, dashboard, event.
Each policy holds exactly one Cedar statement. Saving checks it against the schema and rejects it if it doesn't compile.
Saving and reloading
- A save or delete rebuilds the chain in archie-ui at once. Every process also reloads the stored policies every 30 seconds.
- A change that would leave any org with no owner able to manage its policies is refused with
409(access: change leaves no owner able to manage policies).
Webhook delivery rules
A delivery to a capture source is checked as the deliver action, with the sender's address in context.addr, against the instance policies and that source's object policies. Org, workspace and role policies don't apply, because a sender has no identity or role.
forbid(principal, action == Archie::Action::"deliver", resource)
unless { context.addr.isInRange(ip("10.0.0.0/8")) };A refused delivery gets 403. It isn't stored, but the refusal is counted against the source along with the sender's address. The capture_refusals health check degrades when a source refused more events than it accepted in the last hour.
When a policy fails to compile
Stored policies are compiled again at every load. A policy that no longer compiles makes its level refuse every request, and the access_policies health check names it with the error.
If the broken policy is at the instance level, every request is refused except an instance owner reading or managing policies. That way the owner can fix or delete it at Org > Access.
Before the policies load
Until archie-ui has loaded the stored policies, for example while the State Store is unreachable at startup:
- Dashboard API requests get
503, and browsers get a notice page with status503. /health/detailedreturns503with one degraded component,access_policies.- Webhook deliveries get
503, and no refusal is counted.
archie-ui retries every 30 seconds and serves normally once a load succeeds. Nothing's recorded as a denial, because no policy ran.
Recovery from the State Store host
archie-state-store access reset runs only on the State Store host and needs the State Store stopped first. Each reset is recorded as an audit event. The cross-org forbid survives any reset.
archie-state-store access reset --org <org> # restore the four shipped policies, remove the org's other org-level policies
archie-state-store access reset --instance # remove every stored instance policy