Agent Policy
Versioned policy rules for your agent workforce, enforced at credential verification, the OAuth token mint, introspection, and JIT task creation. The org document is the ceiling; each accountable operator may add a layer that only tightens it — the vocabulary has no allow or exempt disposition, so no rule can ever widen access.
Documents & versioning
- One active version per scope. Org level: PUT /v1/agent-policy (org admin). Operator level: PUT /v1/me/agent-policy (requires an admin-linked operator credential) or PUT /v1/agent-policy/operators/{operator_ref} (org admin). Every PUT writes a new immutable version; superseded versions are retained for audit, and every decision stamps the versions that produced it.
- Opt-in by authoring. With no active document, behavior is exactly the legacy advisory/block scope-enforcement mode. DELETE /v1/agent-policy deactivates and reverts instantly — that is the rollback.
- Effective view. GET /v1/verifications/agents/{agent_id}/effective-policy returns the org ceiling, the operator layer, and the legacy mode.
Rule shape
A rule is {id, match, disposition, require?}. Match sections AND together; list fields are membership tests; an empty match applies to every request.
- match.scope — any_of (scope list) or outside_permitted (legacy semantics: the requested scope is outside the declared/delegated set; never fires for agents with no declared scopes).
- match.agent — trust tier floors, verification product, lifecycle, environment, autonomy, access mode, data classification, sub-agent spawning, disclosure level, JIT mode.
- match.operator — missing anchor, credential expiring within N days, org operator-verified state.
- match.context — time windows (IANA timezone, inside or outside), cloud attestation (provider, freshness), caller-supplied claims.
- match.custom_unsatisfied — fires while any listed custom requirement is unsatisfied.
Dispositions & required controls
- block — refuse. Verify returns valid=false (reason scope_not_authorized for scope rules, policy_blocked otherwise); the mint narrows per-scope or refuses with invalid_grant policy_blocked:; introspection reports a live token active:false on the next call; JIT task creation refuses with POLICY_BLOCKED.
- flag — allow, audit, and fire the agent.policy_violation webhook; responses carry policy_decision and the matched rule ids.
- escalate — allow only while every required control is satisfied: jit_task_active, post_task_attestation (optionally max-age), min_trust_level, verified_operator (an anchored operator in an organization that has passed Organization Verification), qa_readiness_attested (a current production-readiness attestation from Testing & QA — normally written for you by the production gate on Settings → Agent testing), or custom_requirement. Unmet → policy_escalation_required with the unmet controls listed (machine-readable remediation).
Custom requirements
Declare org-specific (industry) requirements at PUT /v1/agent-policy/requirements, then reference them from rules. Satisfaction comes from data, never code: agent_declaration (an enrollment metadata field), operator_attestation (recorded at POST /v1/agent-policy/attestations, revocable, freshness-bounded), or context_claim (asserted by your platform on the verify/mint call). A requirement that is deactivated while still referenced evaluates as unsatisfied — fail closed.
Migrating from advisory/block
GET /v1/agent-policy with no authored policy returns your current mode synthesized as rules (source: legacy_scope_enforcement). Promote them verbatim as v1 — one click in Settings → Agent policy, or PUT the same payload — then extend. While a policy is active the legacy advisory/block knobs are inert; deleting the policy restores them unchanged. Legacy scope-mode writes now require an org-admin dashboard session (API keys receive ADMIN_REQUIRED).
Related: Security model · Quickstart