Approval Workflow
A developer hits a policy, model, or budget limit and wants a bounded, temporary way past it. This page explains the request → approve → grant → expire/revoke lifecycle that handles that, and when a decision needs more than one approver.
The lifecycle
Every request an admin can approve goes through the same four stages:
- Request — a developer submits a request (from the Builder Portal, Claude Code, or the API), naming what they need and why. AIControls immediately notifies the approver audience.
- Approve or deny — an admin reviews the request in Security → Approvals and decides. A denial ends the lifecycle; an approval moves to the next stage.
- Grant — approval takes effect immediately: a policy exception is granted, a model becomes usable, or a session's budget increases, depending on the request type (see Request types below).
- Expire or revoke — grants that carry an expiry date lapse automatically with no admin action required. An admin can also revoke a still-active grant early; see Revoke a granted exception — there is no dedicated admin UI for this yet, so it's done via the admin API.
Each stage fires a notification (see Notifications) so the requester and approvers stay in sync without polling the UI.
Single- vs multi-approver co-sign
Most requests need only one approver — whoever reviews it first decides its outcome. Higher-risk requests can require co-sign: two or more specific approvers must all approve before the grant is final. While co-sign is pending, the request shows as Under Review in the Approvals list with a checklist of who has and hasn't decided yet.
The first approver's decision (the one who names the additional required co-signers) creates the grant immediately — it's live and enforced for the rest of the review window, not just once every co-signer has decided. Co-sign is a review-and-veto period on an already-active grant, not a hold before one exists. This is why a later denial (below) revokes rather than simply declining to create.
Co-sign resolves as follows:
- Any approver denies → the request is immediately denied, regardless of how the other approvers were leaning, and the grant created when co-sign started is revoked — access reverts as if it had never been granted.
- Every required approver approves → the request is marked approved; the grant created when co-sign started remains in effect unchanged.
- Some approvers still pending → the request stays Under Review; the grant stays active and nothing else happens until the quorum is reached one way or the other.
Only the approver named in a decision can record it — the request/approve/deny API rejects a decision submitted by anyone else, so approvers can't act on each other's behalf.
Because two co-signers can act within moments of each other, AIControls guarantees the request completes exactly once no matter how close together the deciding decisions land — you'll never see a double approval, a double revoke, or a duplicate notification from a co-sign race.
Request types
| Request type | What approving it does | Durability |
|---|---|---|
| Exception | Grants a time-bounded exception to a named policy for the requesting developer | Expires at the configured time, or until revoked |
| Model access | Grants the requested model to that developer via the same config-target exception mechanism a policy exception uses, on top of their team/org ceiling | No expiry is set from the Approvals UI today, so the grant persists until revoked (admin API only — see Revoke a granted exception). (Grants approved before this mechanism shipped are separate, durable per-developer overrides — still revocable via the admin API DELETE /api/v1/developers/{id}/model-overrides.) |
| Session budget top-up | Adds a one-time dollar amount to the requesting developer's current session's spend cap only | Ephemeral — scoped to that one session; see Grant a session budget top-up |
| Extend session | Extends the requesting developer's current session by the requested number of hours | Applies once, to that session |
| Resume session | Reactivates a paused session (e.g. after an anomaly auto-pause) | Applies once |
"Session budget top-up" here is a different mechanism from the durable, org-wide budget top-up described in Set a Budget → Exceptions, which raises a team or user's rolling monthly cap via a config-targeted exception rather than a single session's cap. Use this workflow when a developer just needs a bit more headroom to finish what they're doing right now; use the Cost Governance exception flow for a durable, month-over-month adjustment.
Policy exceptions are the request type most often needed at scale — see Policies, Set a Budget, and Restrict Network Egress for the policy-, budget-, and egress-specific exception mechanics each of those pages documents in more depth.
Notifications
| Event | Fires when | Recipient |
|---|---|---|
exception_approval_requested | A request is submitted and needs approver action | Admins |
exception_granted | A grant is created — single-approver decision or the final co-sign approval | The requesting developer |
exception_denied | A request is denied — by a single approver or any co-signer | The requesting developer |
exception_expired | A granted exception's expiry time passes | The requesting developer |
exception_revoked | An admin revokes a still-active grant early | The developer, plus an admin audit copy |
Configure which channels (in-app, email, Slack/Teams/webhook) carry each of these from Settings → Notifications → Routing — see the Generic Webhook event type table for the full list of event types AIControls can deliver.