Skip to content

    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

    instance

    none

    every org

    org

    org_id

    the org's records

    workspace

    org_id, workspace_id

    one workspace

    object

    org_id, object_kind, object_id

    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

    org-role-read

    all four

    read, read_logs

    org-role-edit

    developer, admin, owner

    create, update, run

    org-role-admin

    admin, owner

    every action except deleting the org

    org-role-owner

    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. Attributes org and role. Its parent is its org, so principal in Archie::Org::"acme" works.
    • Archie::Object, the resource. Attributes org, workspace and kind, plus owner and state when 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 status 503.
    • /health/detailed returns 503 with 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