SWIRLS_
Access

Access

Declare who can run what. role blocks derive roles from verified identity attributes, and policy grants map those roles to agents, workflows, and tools.

What it is. Who may reach in: the roles and grants that decide which people can talk to which agents and start which workflows. The mirror image of connections, which govern what your system reaches out to.

Use it when you want to control who can talk to an agent or start a workflow, or you have an org chart and want the system to respect it.

Works with the Portal's project Access page (assign attributes to members), OIDC federation (your IdP's claims as the facts), and agents and workflows (the targets of grants).

By default, every member of your organization can run everything in a deployment. role and policy blocks change that. Declare roles derived from verified identity attributes, attach grants to them, and the project flips to deny by default: a principal can only reach what a matched role grants.

Access control lives in your .swirls files, so every change to who can run what is reviewed, versioned, and deployed like the rest of the system.

The model: identity asserts facts, the file decides what they mean

The identity source never assigns a Swirls role. It only asserts facts about the principal: a Swirls user carries their organization role and any attributes assigned in the Portal, and a federated user carries the verified claims from their identity provider's JWT. Your role blocks decide which facts to trust and what they mean. The claim keys named in match rules are the only attributes the policy engine ever reads; anything else the identity source sends is inert.

The role block

A top-level block that derives a named role from attribute values:

role finance {
  description: "Finance team"
  match {
    department: "finance"
  }
}

role exec {
  match {
    org_role: [ "owner", "admin" ]
  }
}
FieldTypeRequiredNotes
descriptionstringNoHuman-readable description of the role.
matchblockYesAttribute conditions, one per line.

Match semantics:

  • A scalar value is an equality test: department: "finance" matches when the principal's department is finance.
  • A list value is a membership test: org_role: [ "owner", "admin" ] matches either value.
  • Multiple conditions in one match block must all hold (AND). Declare separate roles for OR.
  • A principal whose attribute is itself a list (for example, groups) matches when any of its values intersects the condition.
  • An empty match block matches no one.

The policy block

A top-level block that attaches grants to role names:

policy {
  allow finance -> agent accountant {
    workflows: [ brex, quickbooks ]
  }
  deny finance -> agent ceo_pa
  allow exec -> agent *
}

Each grant is allow or deny, a role name, and a target agent. agent * targets every agent in the deployment.

  • An omitted body grants all of the agent's workflows and tools. workflows: and tools: narrow the grant.
  • deny always wins over allow for the same agent, across every role the principal matched.
  • A principal matching multiple roles gets the union of their grants.
  • Declaring any grant flips the project to deny by default. Principals matching no granting role cannot run the deployment. Remove every policy block to return to the open posture.

Roles without a policy are inert. Define them first, deploy, and confirm who matches in the Portal before adding grants.

Where attributes come from

Swirls users

Members of your organization carry two kinds of attributes:

  • org_role: the organization role (owner, admin, or member), managed on the Members page in the Portal. Use it for org-wide rules like an admin role.
  • Project attributes: facts like department or group, assigned per project in the Portal under your project → Access. The page reads the active deployment, offers only the attribute keys your deployed role blocks reference, and previews which roles each member matches as you assign values. Assignments in one project never affect another.

Only organization owners and admins can assign project attributes.

Federated users (OIDC)

Principals authenticating through OIDC Federation carry the verified claims from the JWT they exchanged. Your identity provider is the attribute source: put department, groups, or any other fact in the token, and match rules evaluate it directly. See map identity claims to access roles for provider setup.

Enforcement

Access is evaluated when a run starts, bound to the principal who triggered it. A principal matching no granting role cannot start a run on a deny-by-default deployment. During the run, each agent invocation is checked against the granted agent set, so a workflow can never reach an agent its principal was not granted. Runs started by schedules and triggers evaluate as the principal who owns the trigger.

Enforcement applies at the agent boundary today. workflows: and tools: narrowing is declared in the grant and recorded on the execution, with enforcement at those finer boundaries rolling out next. Use agent profiles to restrict an agent's tools in the meantime.

Enforcement fails closed. A deployment that declares a policy refuses to run unenforced, and a policy that cannot be read denies rather than falling open.

role is not profile

These are different layers. A top-level role controls who may invoke an agent. An agent's profile controls what the agent may do when it runs: its tools, system prompt, and sandbox. Use both: a role grants the accountant agent to the finance team, and a profile keeps the accountant agent scoped to read-only tools for routine work.

Example: map an org chart

The CEO and CFO reach every agent. The accountant reaches the accountant agent's bookkeeping workflows. HR reaches the HR agent.

role exec {
  match {
    title: [ "ceo", "cfo" ]
  }
}

role accounting {
  match {
    department: "accounting"
  }
}

role hr {
  match {
    department: "hr"
  }
}

policy {
  allow exec -> agent *
  allow accounting -> agent accountant {
    workflows: [ brex, quickbooks ]
  }
  allow hr -> agent hr_assistant
}

Deploy with git push or swirls deploy, then assign title and department to members on the project's Access page, or include them as claims in your identity provider's JWTs.

On this page