Govern overview
Decide which writes run, which wait for a person and which are refused, with risk tiers, policies, amount limits, grants and approvals bound to the exact action.
Updated 09/10/2026
On this page
One gate for every write
Every write that a flow, a dead-letter retry or an agent makes through a connector passes through one gate. The gate checks your policies, asks a person when one is needed, enforces limits and records hash-chained evidence before the provider is called. Reads always run.
The gate answers with one of three decisions:
| Decision | What happens |
|---|---|
| Allowed | The write runs straight away and its result is recorded. |
| Needs approval | The write waits in Govern → Approvals until a different person approves it. |
| Denied | The write is refused before the provider is called, and the refusal is recorded. |
A write must also be switched on for its connection. A connection can only perform the write operations you ticked when you set it up (see Connections).
Risk tiers
Nexra gives every connector operation a risk tier. The tier is set by Nexra on the server and shown on each operation, so a caller cannot lower it.
| Tier | Name | Covers |
|---|---|---|
| R0 | Read | Reads data only. Reads are always allowed. |
| R1 | Low | Creates or updates a single record. |
| R2 | Moderate | Changes many records at once, or creates or updates in one step (upsert). |
| R3 | External effect | Sends a message, costs money at the provider, creates a payment link, checkout or subscription, or touches payroll, bank or ID data. |
| R4 | Money or deletion | Moves money irreversibly or deletes data: payments, payouts, transfers, refunds, bank transactions and deletes. |
Payments run as you set them up. Payments run through your own payment account, exactly as you set them up. Add approval rules or limits if you want them, and daily reconciliation shows what moved. Payouts, transfers, refunds and charges are turned on per connection and managed in Connect → Money movement; payments that Nexra Agent or an AI tool starts always wait for a person. Other R4 writes, such as deletes and bank transactions in a ledger, are refused: no policy, grant or approval can allow them, and every attempt is recorded as evidence with the rule risk_tier_r4_denied. Creating a payment in Xero or QuickBooks Online, for example, never runs through Nexra. Editing an existing payment record moves no money, so it is R3.
Policies
Open Govern → Policies to choose what happens to each write. A policy applies to one connection or to the whole workspace, and to one operation (for example invoices.create) or to every write (*).
The most specific active policy wins, and policies are never merged:
This connection and this operation
This connection and every write
The workspace and this operation
The workspace and every write
Each policy sets an effect (allow, require approval or deny) and can add:
Approval: the role that must approve (for example Approver or Compliance reviewer), how long a request waits (1 minute to 24 hours, 60 minutes by default), and the risk tier at and above which every write needs a person.
Volume limits: records per run (a larger batch is refused before anything is written) and writes per hour on the connection.
Field limit: a numeric input above a threshold needs approval or is refused. A value that is not a number triggers the rule.
Amount limits: see below.
Grants: require a grant for the caller (see Grants).
Policies are switched off, never deleted, and every change is written to the audit log.
A good starting point: one workspace policy on every write that allows writes but requires approval at R3 and above. Messages, billable calls and payment links then wait for a person; ordinary record updates run. Add an allow policy for an exact operation when it should always run.
Amount limits
For an operation that carries an amount, set the amount field, its currency, a per-action limit and a rolling 24-hour limit. Amounts are exact decimals in the same unit as the field, so a limit on a field in pence is in pence.
An amount above the per-action limit is refused (amount_per_action_exceeded).
A write that would take the last 24 hours over the limit is refused (amount_rolling_exceeded). The window counts committed writes and writes still in progress, so concurrent writes cannot slip past it.
An amount that is missing or cannot be read always waits for a person (amount_unreadable).
Grants
A grant lets one flow or one agent credential write through one connection, for a set of operations, until it expires (at most 366 days). Each grant records who created it and why.
Turn on Require grants for every write in Govern → Grants, or set Require a grant on a single policy. A write without an active grant is then refused before any policy rule is checked. Revoking a grant stops that caller immediately; revoked grants stay on record.
Test a policy before you save it
Every policy has Test this policy. Choose an operation, paste a sample input and test it against your saved policies or your unsaved changes, optionally as a specific flow or credential. Nothing is written, reserved or approved.
The same dry run is available over the API:
POST /api/console/connect/governance/decisions/explain
Content-Type: application/json
{
"connectionId": "<connection id>",
"operationKey": "payment_links.create",
"input": { "amount": 800, "currency": "GBP", "reference": "ORDER-1001" },
"principalType": "mcp_credential",
"principalId": "<MCP credential id>"
}{
"decision": "deny",
"rule": "amount_per_action_exceeded",
"reason": "The amount 800 GBP exceeds the per-action limit of 700 GBP.",
"riskTier": "R3",
"policyId": "<policy id>",
"effectSource": "connection_operation",
"amount": {
"value": "800",
"currency": "GBP",
"perActionLimit": "700",
"rolling24h": { "used": "300", "reserved": "0", "limit": "1000" }
},
"grant": { "id": "<grant id>", "expiresAt": "2027-03-31T00:00:00.000Z" },
"grantRequired": true,
"inputError": null,
"evaluatedAt": "2026-10-09T09:12:44.120Z"
}Add "policy": { … } to test an unsaved draft. When the input itself would be refused by the provider, inputError says why and the decision is still reported.
Approvals bound to the exact action
An approval covers one write, once. Its digest binds the workspace, the connection, the operation, the normalised input and where the write came from (the flow record and step, or the agent credential). A different amount, record, connection or caller produces a different digest, so the approval does not cover it.
Single use. An approved write runs exactly once. Reusing the approval is refused.
Expiry. An expired approval is refused, and a fresh request is raised when the write is tried again.
Separation of duties. You cannot approve your own request, and only members with the policy's approver role can decide.
What you saw is what runs. The reviewer's decision carries the digest they reviewed. If anything changed since the page was opened, the decision is refused and the request must be reviewed again.
In a flow, a record that needs approval waits in the dead-letter queue while other records carry on. Approving it in Nexra resumes that record automatically and writes it once.
The approvals inbox
Open Govern → Approvals. Requests are listed oldest deadline first, with the action in plain words, the risk tier and who can approve. Each request shows:
the key amounts, parties, dates and counts, then every field with its label;
why approval is required (the rule that paused the write) and where the write came from;
the action digest it is bound to, and its expiry;
the action timeline: decision, approval, execution and result.
Before you approve, tick each check: the amount, party and target record are what you expect; the details are correct and complete; and you would make this change yourself. Billable operations and operations that send messages add their own check. A note is required to reject.
Keyboard shortcuts
| Keys | Action |
|---|---|
J / K | Next or previous request |
Enter | Open the request |
A | Approve: opens the review step |
R | Reject: opens the review step |
G then G | Go to Approvals from anywhere in the console |
? | Show every keyboard shortcut |
Nothing is decided by a single key. Approving still needs every check ticked, and rejecting still needs a note.
Decide over the API
POST /api/console/connect/governance/approvals/<approval id>/decision
Content-Type: application/json
{
"decision": "approve",
"reviewedDigest": "9c41f0a7e2b6…",
"note": "Matches the signed purchase order."
}reviewedDigest is the binding.digest from GET /api/console/connect/governance/approvals/:id. Refusals carry a code: reviewed_digest_required, approval_digest_mismatch, note_required, self_approval_forbidden, approver_role_required, not_pending or expired.
Measures
Govern → Overview shows what is waiting for a person, the median time to decide, denied writes by rule and whether the evidence chain still verifies, over the last 7 or 30 days. See Prove overview for the same measures over the API.
Who can do what
| Role | Can |
|---|---|
| Owner, Admin, Security administrator | Manage policies, grants and governance settings |
| Owner, Admin, Approver | Decide approvals (subject to each policy's approver role) |
| Connect operator | Run writes; cannot change guardrails or approve |
| Compliance reviewer | Read and export evidence |
API
All routes are under /api/console/connect/governance. Lists return {items, nextCursor}; pass nextCursor back as cursor until it is null.
| Method | Path | Permission |
|---|---|---|
GET | /policies | connect.connection.read |
PUT | /policies | connect.policy.manage |
POST | /policies/:policyId/disable | connect.policy.manage |
POST | /decisions/explain | connect.connection.read |
GET | /grants | connect.policy.manage |
POST | /grants | connect.policy.manage |
POST | /grants/:id/revoke | connect.policy.manage |
GET | /settings | connect.connection.read |
PUT | /settings | connect.policy.manage |
GET | /approvals | approvals.request (own) or approvals.manage |
GET | /approvals/:id | approvals.request (own) or approvals.manage |
POST | /approvals/:id/decision | approvals.manage and the policy's approver role |
A policy body looks like this:
{
"connectionId": "<connection id>",
"operationKey": "invoices.create",
"effect": "require_approval",
"approverRole": "APPROVER",
"approvalExpiresInMinutes": 240,
"maxRecordsPerRun": 200,
"amountPath": "lines.0.amount",
"amountCurrency": "GBP",
"perActionAmountLimit": "2500",
"rolling24hAmountLimit": "20000",
"minRiskTierForApproval": "R3",
"grantRequired": false
}Next
Prove overview: the evidence every decision leaves behind.
Nexra Agent: ask about approvals and test a policy in plain words.
Governed workflow templates: workflows that install with approval policies on every write.