Policy-gated exceptions
Policy-gated exceptions are a governed security workflow for blocked runtime actions. They are not a developer bypass, and they do not grant developers access to AgentKeeper.
Policy-gated exceptions are a governed security workflow for blocked runtime actions. They are not a developer bypass, and they do not grant developers access to AgentKeeper.
Exceptions are default closed. A blocked action is eligible for review only when the effective admin-authored policy marks that exact rule, detector, or policy reason as exceptionable.
How the lifecycle works
| Step | Developer experience | Admin experience |
|---|---|---|
| Block is not eligible | The runtime says the action is not eligible for exception review and shows a short event reference. | No intent, queue row, or notification is created. |
| Block is eligible | The runtime returns a request code, a CLI command, and a signed public agentkeeper.dev request URL. | Nothing is queued until the developer submits a reason. |
| Developer submits | The developer uses agentkeeper exception request <code> --reason "..." or the signed public form. | One submitted request appears in /exceptions and one notification is sent. |
| Admin reviews | The developer can check status through the CLI or signed status page. | The detail page shows eligibility source, deterministic evidence, requested scope, AI triage, timeline, and policy-bounded decision controls. |
| Admin approves | The developer retries the same action. | The approval becomes a scoped, expiring lease. |
| Lease matches | The exact blocked action downgrades to warn_by_exception until expiry. | Match and expiry events remain auditable. |
Developer request paths
Developers should not browse AgentKeeper queues, activity, policies, or request details. The runtime gives them only the information needed to ask for review.
Eligible block copy includes:
Blocked by AgentKeeper policy.
This action is eligible for security review.
Request an exception:
agentkeeper exception request ABC123 --reason "why you need this"
Or open:
https://agentkeeper.dev/request-exception/ABC123?token=...
Sandbox deployments use https://sandbox.agentkeeper.dev/request-exception/....
The public form shows redacted event context, request status, a reason field, requested duration, and optional context. It does not show raw prompt text, raw tool input, full policy internals, other exception requests, or dashboard links.
Developers can check status with:
agentkeeper exception status ABC123
Admin policy controls
Admins decide whether an exception path can ever appear. Use exception eligibility sparingly and prefer narrow rules.
| Mode | Behavior |
|---|---|
Never | No request path is shown. This is the default. |
Allow review | Matching non-hard-block rules can create request intents. |
Break-glass only | Matching rules can create request intents for explicitly approved emergency workflows. |
Eligibility should be attached to the smallest useful policy surface: detector, repository policy outcome, runtime rule, or gateway policy category. Hard-risk categories such as credential exfiltration, prompt injection, reverse shells, persistence, data exfiltration, and AgentKeeper control tampering should remain non-exceptionable unless the organization has a documented break-glass process.
Admin review workflow
Reviewers work from /exceptions and /exceptions/<request-id>.
The detail page should be read in this order:
- Eligibility source and policy bounds.
- Deterministic event evidence.
- Requested scope and duration.
- Developer reason and context.
- AI triage, when enabled.
- Lifecycle timeline.
- Decision controls.
Approvals cannot exceed the policy maximum duration, approved transform, or trustworthy scope. In v1 the transform is block -> warn_by_exception, not silent allow.
If a reviewer needs more information, use Request context. The developer can respond through the CLI or signed public form without dashboard access.
Enforcement rules
Approved exceptions are leases. They apply only when all of these are true:
- The request is approved and unexpired.
- The retry matches the original scoped action signature.
- The source, host, session, repository target, or other trustworthy scope still matches.
- The current effective policy still marks the rule as exception-eligible.
If policy eligibility is removed after approval, the lease stops applying. The runtime falls back to the normal policy block.
Gateway legacy Record exception entries are audit-only records. Gateway enforcement uses the governed exception_requests workflow only when a policy-gated request is created and matched by the runtime path.
Failure modes
| Failure | Required behavior |
|---|---|
| Token expired | The public page shows an expired state and creates no request. The developer retries the original action if still needed. |
| Token guessed or malformed | Generic 404 with no organization leak. |
| Duplicate submit | Return the existing open request and do not notify admins twice. |
| Policy changed after intent | Submission fails as policy-ineligible. |
| Policy changed after approval | Runtime ignores the approval and blocks normally. |
| AI triage fails | The request remains reviewable and deterministic evidence stays primary. |
| Notification fails | Request state persists and delivery failure is logged. |
| Runtime lookup fails | Runtime keeps the original block. It never broad-allows. |
| Context contains secrets | Redaction strips or summarizes before storage, notification, public display, and AI prompts. |
| Actor identity is unverified | Do not approve user or group scope; use only trustworthy host, session, source, or repository scope. |
Verification checklist
Before enabling exception review for a policy area:
- Confirm the default policy produces no request path.
- Enable eligibility only for the target detector or policy reason.
- Trigger an eligible block and confirm the runtime shows a request code and
agentkeeper.devURL. - Submit through CLI or public form without dashboard access.
- Confirm exactly one queue item and one notification.
- Approve for a bounded duration and scope.
- Retry the exact action and confirm it downgrades to warning with exception id and expiry.
- Retry a different action and confirm it remains blocked.
- Disable eligibility and confirm the approved lease no longer applies.
- Run expiry and confirm the request moves to expired and enforcement blocks again.
Use the internal sandbox E2E runbook before promoting a new exception lifecycle build.