Documentation

Review workflows.

Review plans

What it is. The approval policy attached to a datasource — it decides how a submitted query gets from "submitted" to "executed". Use it to require AI scoring, one or more human sign-offs, or both, and to auto-approve low-risk reads. Each plan is a sequence of stages; each stage names approvers (by role or specific user) and a minimum number of approvals before the query advances.

Configure it. Build plans at /admin/review-plans — start from a built-in template or from scratch:

Review plans admin page with the create-from-template dropdown open, listing four templates — Strict (writes need 2 approvals), Lenient (reads auto-approved), AI-only (no human approval), and Standard (AI plus one reviewer).
/admin/review-plans → caret next to Add review plan exposes four built-in templates that prefill the create modal.
Add review plan modal with name and description fields, AI-review and human-approval toggles enabled, minimum approvals set to 1, approval timeout 24 hours, and an approver row defaulting to the REVIEWER role at stage 1.
/admin/review-plansAdd review plan. Stack approver rows to build multi-stage chains.
  1. Open /admin/review-plans and click Add review plan, or pick a built-in template from the dropdown caret next to it (Strict — writes need 2 approvals, Lenient — reads auto-approved, AI-only — no human approval, Standard — AI + 1 reviewer) to prefill the modal with sensible defaults.
  2. Name and describe the policy — e.g. "Production writes — two reviewers".
  3. Pick the gates. Toggle Require AI review to score every query before it queues for humans; toggle Require human approval to demand at least one reviewer sign-off. Auto-approve LOW-risk reads lets SELECTs skip humans entirely when AI risk is below the threshold.
  4. Set thresholds. Minimum approvals is the number of distinct reviewers needed before the query advances; Approval timeout (hours) is when AccessFlow auto-rejects an idle PENDING_REVIEW query (it scans on a cadence set by ACCESSFLOW_WORKFLOW_TIMEOUT_POLL_INTERVAL, default PT5M).
  5. Build the approver chain. Click Add approver for each stage; each row names a role (or a specific user) and a stage number. Stages advance sequentially, and a single REJECTED decision at any stage terminates the query.

Reviewer decisions. Reviewers can Approve, Reject, or Request changes. Reject and Request changes both require a non-empty comment — the server enforces this (HTTP 400 VALIDATION_ERROR), and the UI disables the confirm button until the textarea is populated. The comment is persisted on the decision row, rendered on the rejected stage of the timeline on /queries/<id>, and surfaced to the submitter as a "Changes requested" alert whenever the latest decision is REQUESTED_CHANGES and the query is still PENDING_REVIEW. Approve still treats the comment as optional.

Query status transitions. A query moves through these states:

PENDING_AI → PENDING_REVIEW → APPROVED → EXECUTED
                           ↘ REJECTED   (manual reviewer rejection)
                           ↘ TIMED_OUT  (approval-timeout auto-reject)
PENDING_REVIEW → CANCELLED (submitter only)
APPROVED → FAILED (execution error)

A single REJECTED decision at any stage terminates the query. If a query sits in PENDING_REVIEW past the plan's approval timeout, AccessFlow auto-rejects it (it scans on a cadence set by ACCESSFLOW_WORKFLOW_TIMEOUT_POLL_INTERVAL, default PT5M). Auto-approve reads lets SELECTs skip human approval entirely; Require AI review still scores the read but won't block on a human.

Routing policies

What it is. Policy-as-code that decides a query's path automatically, after AI analysis and before reviewers see it. Use it to auto-approve routine reads, hard-block dangerous patterns, or escalate sensitive ones — instead of sending everything through the same review plan. Policies run in ascending priority and the first enabled one whose condition matches wins; anything unmatched falls through to the datasource's review plan exactly as before.

Configure it. Manage them at /admin/routing-policies (the Routing policies entry in the Security nav group):

  1. Open /admin/routing-policies (the Routing policies entry in the Security nav group, next to Review plans) and click Add policy.
  2. Name the policy and optionally scope it to one datasource — leave the datasource blank for an org-wide rule. Set its priority (unique per organisation; lower runs first) and the enabled toggle.
  3. Build the condition with the guided builder: pick match ALL (AND) or match ANY (OR), then add leaf conditions — each can be negated (NOT). Operands include query type, referenced tables (glob, e.g. payroll.*), AI risk level, AI risk score (with a comparison operator), requester role, requester group, time-of-day window, day-of-week, presence of a WHERE clause, presence of a LIMIT clause, the transactional (BEGIN…COMMIT) flag, and the pre-flight cost estimate — estimated rows (comparison against the engine's own EXPLAIN estimate, or the exact affected-row count for UPDATE/DELETE) and scan type (glob match on the plan's root operation, e.g. Seq*) — so a policy can route a 10-million-row sequential-scan DELETE differently from a 10-row indexed one.
  4. Choose the action. Auto-approve (skip human review), Auto-reject (block the query), Require approvals (force human review with an absolute minimum number of approvers), or Escalate (force human review, adding a delta on top of the review plan's minimum). The approver count applies only to the last two actions.
  5. Reorder policies any time with the per-row up/down controls — the order is the evaluation order.
How it routes. Time-of-day and day-of-week conditions are evaluated in the server's local timezone (overnight windows wrap around midnight). On datasources with AI analysis disabled, risk-based conditions never match (there's no AI signal); routing does not run when AI analysis fails — the query goes to a human instead. The cost-estimate conditions likewise never match while no estimate exists (engine without a plan concept, or the estimate failed) — they fail closed rather than auto-approving blind. Every automated decision is recorded in the audit log (QUERY_APPROVED / QUERY_REJECTED with source: "ROUTING_POLICY"), and the query detail page shows which policy matched. Routing policies are managed via the ADMIN-only /api/v1/admin/routing-policies CRUD and /reorder endpoints.
The /admin/routing-policies page listing ordered routing policies by priority — name, scope, condition summary, action (auto-approve / escalate), and per-row reorder controls.
/admin/routing-policies — ordered, attribute-based auto-decision rules; first match by priority wins, unmatched falls through to the review plan.

Access recertification campaigns

What it is. Recurring attestation campaigns that make someone periodically re-confirm who still needs standing datasource access — the review control SOC 2 and ISO 27001 auditors ask for. An admin schedules an org- or datasource-scoped campaign; when it opens it snapshots the current standing grants into one item per grant and notifies the eligible reviewers (multi-channel, plus an attestation.campaign_opened WebSocket event). Reviewers work a certify / revoke worklist that reuses the review-queue patterns (self-review blocked, bulk-certify); a revoke routes through the normal permission-revoke path, so access is actually removed.

Configure it. Manage campaigns from /admin/attestation and certify items from the reviewer worklist at /reviews/attestations. Two clustered-safe jobs run the lifecycle: one opens SCHEDULED campaigns at their scheduled_open_at, the other closes OPEN campaigns at their due_at and applies each campaign's pending-default (KEEP or REVOKE) to anything a reviewer never got to. A completed campaign exports as a CSV evidence file (who reviewed what, decisions, timestamps), and every transition — ATTESTATION_CAMPAIGN_OPENED/CLOSED, ATTESTATION_ITEM_CERTIFIED/REVOKED — lands in the tamper-evident audit log.

Tune it. ACCESSFLOW_ATTESTATION_OPEN_POLL_INTERVAL and ACCESSFLOW_ATTESTATION_CLOSE_POLL_INTERVAL (open / close scan cadence, both default PT5M) and ACCESSFLOW_ATTESTATION_MAX_EVIDENCE_ROWS (row cap before an evidence CSV is marked truncated, default 50000).

The AccessFlow access-recertification campaign list at /admin/attestation, showing scheduled and open attestation campaigns with their due dates and pending-item counts.
/admin/attestation — admins schedule recurring access-recertification campaigns; reviewers certify or revoke each snapshotted grant.