Attribute & relationship access control
Two extensions to agent RBAC, split cleanly across the platform’s two authority sides. Grants come from role bindings: a role with a condition document automatically applies its scopes to every matching agent. Restrictions come from new policy-rule predicates over the same attributes and relationships. A rule can only ever narrow — the policy engine still has no allow disposition, so nothing an operator or a condition matches can widen what the org restricted.
Attributes
Conditions match the agent’s enrollment-declared attributes (environment, autonomy level, access mode, data classification, framework, model, product, internal flag) and custom attribute tags — org-defined key/value labels (team=payments, data_classification=pii) with an optional closed value set. Tags are grant-affecting, so defining keys and tagging agents is restricted to admins and role admins — never the agent’s own operator (self-tagging into a bound role would be self-service privilege escalation).
The org chart
Your organization defines its own seniority ladder (Team & Access): named levels with an integer rank, larger = more senior, assigned per member. Seniority then works in both directions: a role binding can require operator.min_level (grant only to agents whose accountable operators are senior enough), and a policy rule can match operator_level_below — so an associate’s agent never gains access restricted to Vice Presidents. Seniority fails closed everywhere: an unleveled operator never passes a grant-side minimum and always matches a below-level restriction; a level deleted after a policy referenced it keeps the restriction matching.
Role bindings (grants)
An org-level role may carry one binding: agent-attribute conditions, tag conditions, and operator-relationship conditions (IdP group membership, org role, minimum seniority). All present sections must match; list values are any-of. The grammar is deliberately positive-only — no negations, no time windows — so evaluation is monotone: gaining an attribute can only add authority, and every granted scope is explainable by facts the agent has. Bindings are inert until an admin turns on the attribute/relationship role bindings policy (off by default).
- Governance vs liveness. The agent/tags part of a binding decides whether the agent is role-governed; the operator part is a live condition on the scopes. An operator losing the group, being demoted, or deactivating strips the binding’s scopes on the next verify, mint, or introspection — the agent stays role-governed, so a lapse narrows authority and never falls back to enrollment-time scopes.
- Everything is evaluated at read time — no assignment rows, no sync jobs. Editing a binding, a tag, a group, or the org chart lands on the very next call (the kill-switch contract every authority source follows).
- The binding editor previews which agents currently match (GET /v1/agent-roles/{id}/binding/matches), and refusal codes at authoring time include UNKNOWN_ATTRIBUTE, UNKNOWN_LEVEL and BINDING_ORG_ONLY.
Policy predicates (restrictions)
Agent policy rules gain matching vocabulary on both dimensions: agent (framework, model_name, is_internal, has_parent, tag predicates with present/equals/any_of/none_of) and operator relationships (operator_level_below, operator_group_any_of / none_of, operator_role_in). operator_group_none_of matches when no live operator holds the group — including agents with no operators at all — giving a fail-closed “require membership” form. Composition, dispositions, and the narrowing guarantee are unchanged.
Callers may also assert bounded context claims (policy_context on verify and validate) for rules matching on request context — a ticket id, a change window, a tenant. Claims are constraint-only by design: a rule written with present: true fails closed when the claim is absent, and no claim can ever widen authority.
Sub-agent ceiling
With the sub-agent authority ceiling policy on, a sub-agent’s permitted set is capped at its parent’s effective set — a sub-agent can never do more than the agent that spawned it. A child with no declared scopes inherits the parent set as its ceiling; a parent with no credential yields an empty ceiling. The cap is read live: a scope leaving the parent leaves the child on its next check.
Resource ownership
Register who owns a resource (POST /v1/resources/registrations: an operator, an IdP group, a minimum seniority level, or the agent itself/its parent), then set the enforcement mode. Grant requests on /v1/agents/credentials/validate naming a registered resource are refused (block, RESOURCE_RELATIONSHIP_NOT_SATISFIED) or flagged (advisory, audited + webhook) unless the agent’s live operators hold the relationship. Unregistered resources are never checked — adoption is opt-in per resource, and the mode is off by default.
Related: Agent RBAC (roles, exceptions, recertification), Agent policy engine (rule anatomy and enforcement surfaces), Operator continuity (the accountable-operator links these relationships traverse).