Skip to main content

Review requests

When an agent hits a governance wall, it can file a review request instead of guessing or giving up. Review requests is where your team reads those requests and decides what happens next. It is the third tab of the Activity module, at /[tenantSlug]/activity/review-requests.

Review requests are admin and owner only. Editors and viewers do not see the tab, do not see its open-count badge, and get a not-found response if they navigate to the path directly — this is a steward surface, not a read-only report. The restriction runs deeper than hiding a link: for an unauthorized member the workspace never runs the request queries, so there is no count and no row to withhold.

If you have an older /[tenantSlug]/requests link, it still works — it redirects here and keeps any query string. That redirect is temporary; prefer the path above.

What a request is, and is notDirect link to What a request is, and is not

An agent calls request_access citing a specific prior authorization. The server re-evaluates that authorization against current published state and writes a workflow row. Nothing about your governance changes: no policy is edited, no deployment is published, no served decision is rewritten. Resolving a request does not change them either. The strongest thing you can do here is mint a subject-scoped, expiring exception for the one token that asked.

Review requests are also not the MCP request log. The Requests tab inside the MCP module (/[tenantSlug]/mcp?tab=requests, with its own CSV export at /[tenantSlug]/mcp/requests/export) is per-token telemetry of tool calls, and it stayed exactly where it was — it is not part of the Activity module and was not renamed. This tab is the steward inbox for access requests. Different things, unfortunately similar names.

The inboxDirect link to The inbox

The list shows every access request in the workspace, newest first, 25 to a page with a keyset pager.

A badge next to the section title counts requests that are currently open — "currently" meaning open and not past their expiry. The Review requests tab itself carries the same count whenever it is above zero, so an admin or owner sees a waiting queue from any Activity tab without opening this one. If the count cannot be read, both badges say so explicitly rather than showing a plausible zero.

The tab badge is restricted exactly as the tab is: editors and viewers never see it, because the count is never computed for them.

A status filter narrows the list to open, resolved, withdrawn, or expired. Each row carries:

  • When it was filed (relative, with the exact timestamp on hover).
  • What it is about — the asset key and the scenario key.
  • EligibilityException grantable or Not waiverable. This is derived from the fresh re-evaluation at filing time, not chosen by the agent, and it tells you up front whether granting is even a legal move.
  • Status — open, or the resolution once resolved.
  • Who asked — the actor name recorded at filing time. It survives token rotation and deletion.

If nothing has been filed yet, the empty state says so and points at the tool that creates them.

The request detail pageDirect link to The request detail page

The header repeats the asset, scenario, requesting actor and bound role, and the two badges. Below it, two cards sit side by side:

Evaluation snapshot — the fresh server re-evaluation as it was stored when the request was filed. State, decision, reason, conditions.

Current state (fresh preview) — the same question re-asked against what is published now. The page tells you which of three situations you are in: the current state matches the snapshot, it no longer does, or the underlying record is no longer available.

Read the two together before resolving. An estate moves; a request filed a week ago may already be answered by a republish, in which case the right resolution is usually to withdraw it or mark it a policy change rather than grant a waiver.

One caveat worth knowing: the preview is deliberately purpose-blind and role-blind — it runs with no bound role and no stated purpose. That makes it a conservative view. It is not a reproduction of what the requesting agent saw, and it is not meant to be; the stored snapshot is the record of that.

The page also shows:

  • Notes, when any exist — the agent's note and the steward's resolution note, each labelled. Notes are recorded only when your workspace has enabled the raw-text privacy switch, are visible only to admins and owners, and are never returned to any agent.
  • Consumed by — once an exception has been granted and used, the verified authorize_use retries that consumed it, reconstructed from the decision ledger rather than from anything the client claimed. The list shows the ten most recent; older consumptions remain on the ledger.
  • Prior requests for this asset and scenario — the history, so a pattern of repeated asks is visible.

Resolving a requestDirect link to Resolving a request

The resolution panel offers three outcomes.

Grant exceptionDirect link to Grant exception

Offered only when eligibility is Exception grantable. When it is not, the page says plainly that the cited answer state can never be exception-overridden, and points you at deny or policy change instead.

The only thing you choose is the lifetime, in whole days: the form defaults to 30 and the platform maximum is 90. Waivers are deliberately short-lived.

You do not choose the scope. The exception is bound to the requesting token and to exactly the asset, scenario, and purpose category of the request, copied server-side. There is no way to widen it from this form, and there is no wildcard purpose scope — a purpose-scoped exception verifies only for a call stating a purpose in that category, and an exception with no purpose scope matches only purposeless calls.

Once granted, the exception is immediately consumable: the agent reads it with check_request and cites it on a retry, where the server re-verifies subject, liveness, and scope in SQL before satisfying anything.

DenyDirect link to Deny

Terminal. The agent may re-file later — published state may legitimately change — and the detail page's history makes repeat asks visible.

Policy change requiredDirect link to Policy change required

The honest outcome for everything a waiver cannot fix: conflicted published state, missing or unresolved coverage, and hard denies. It records that the remedy is authoring and republishing. No exception exists or ever will for that request; the agent retries after the next publication.

Every resolution goes through a confirmation step, and every resolution writes exactly one audit event.

You may also attach a resolution note (up to 2,000 characters). Like the agent's note, it is recorded only under the privacy switch, is admin/owner-visible only, and is never returned to an agent.

Withdrawing and revokingDirect link to Withdrawing and revoking

Withdraw closes an open request as moot or duplicate. It is terminal, and only a steward can do it — there is deliberately no agent-facing withdraw tool. The agent may re-file.

Revoke exception appears on the detail page while a granted exception is still active. Revocation is immediate and terminal; there is no un-revoke. The next check_request reports the exception as revoked, and any retry citing it stops verifying — can_proceed_now returns to false.

Revoking does not rewrite history. Retries that already consumed the exception keep their recorded verified exception ids, because those records state what was true at the time. The "Consumed by" list continues to show them.

Guardrails you get for freeDirect link to Guardrails you get for free

  • Requests expire. Every request carries a server-set 30-day expiry, enforced at read time. An unattended inbox does not accumulate zombie asks forever.
  • Agents cannot flood you. A token may hold at most 100 live open requests; beyond that its submissions are refused with a typed reason.
  • Duplicates collapse. Re-submitting the same asset, scenario, and purpose while a request is already open absorbs into the existing request rather than creating a second one.
  • Nothing is caller-asserted. Eligibility, scope, purpose, and actor identity are all derived server-side. An agent cannot claim it is entitled to anything.
  • Token rotation resets the subject. Rotating a token mints a new subject id, so the new token cannot see the old one's requests or use its exceptions. Resolve or re-file after a rotation.

NotificationsDirect link to Notifications

This version sends no emails. The open-count badge is the notification, and agents learn outcomes by polling check_request. Plan a habit — a daily inbox check is usually enough given the 30-day request lifetime.

Seeing the whole loopDirect link to Seeing the whole loop

For an authorization that went through review, its audit receipt in the Audit trail tab renders a Review workflow timeline for admins and owners: six stages in fixed order — initial decision, request created, steward resolution, exception or policy-change outcome, authorization retried, and final decision — with an explicit "not recorded" for any stage without a durable record, and one of seven outcome labels: Exception granted, Denied, Policy change required, Withdrawn, Expired, Retried successfully, or Retried but still blocked.

Two honesty properties are worth knowing. Status polling is not a stage: check_request records nothing, so no timeline claims to reconstruct it. And when the cited root is a state a waiver could never override, the timeline says so and labels any later retry as a durable fact only — never as a successful override.

  • request_access and check_request — the agent's side
  • authorize_use — where a request starts, and where an exception is consumed
  • MCP tools in the app — issuing a token with the request scope
  • Activity — the module this tab belongs to; the Activity log tab records the events resolutions write, and the Audit trail tab holds the receipts they attach to