AI Permit-to-X
AI Permit-to-X gives a customer a human-readable name for the exact authority Keel established. A Policy defines reusable rules. A later request can produce an AI Permit-to-Work for one bounded job and, inside it, an AI Permit-to-Pay for one exact payment.
The shortest mental model is:
Policy -> request -> AI Permit -> bounded action -> evidenceThese are different records:
| Record | Human meaning | What it does not mean |
|---|---|---|
| Policy | Reusable rules for future requests | No Permit has been issued and no work has run. |
| AI Permit-to-Work | Authorization for one bounded AI job | It is not a workflow plan, progress tracker, or completion claim. |
| AI Permit-to-Pay | Exact payment authorization | It does not by itself prove dispatch, provider acceptance, or settlement. |
| Evidence | Recorded facts about the decision and later lifecycle | Verification does not make an unsupported real-world outcome true. |
A specific title is descriptive, not authorizing. The Permit decision, signed scope, Policy result, approvals, and current execution gates determine whether an action may proceed. Customer text cannot select or mint a Permit-to-X title.
Customer journey: invoice processing
This example uses a payment-focused Work beta:
- a Policy ceiling of $1,000 per job;
- a maximum of four payments;
- review for each payment above $100;
- review of the first Work request from each new verified agent; and
- a particular agent request for only $500 of payment authority.
1. Connect the agent and payment rail
In the dashboard, select the project, then:
- connect and verify the agent under Authority;
- connect and enable a supported payment rail under Integrations; and
- confirm that Make payments is available for that project.
Availability is project-specific. If a supported rail is missing, the Policy builder explains that setup is required instead of offering an action that the project cannot govern.
2. Start a reusable Policy
Open Policies, choose Create Policy, select AI work, and set Applies to to any verified agent or one specific verified agent.
The customer makes the rule in three steps.
Step 1 — What can the agent do?
Select Make payments. Only actions that are actually available in the project appear here.
Step 2 — What are the limits?
For this example, enter:
| Option | Value |
|---|---|
| Maximum payments per job | 4 |
| Maximum payment authority per job | $1,000 |
| Review each payment above | $100 |
| Maximum job duration | 24 hours |
These values are the Policy ceiling for future jobs. An agent may later ask for less—for example, $500 for one invoice—but cannot use the Policy to expand an already issued job.
Step 3 — What should Keel do?
Choose one parent-review mode:
- Review the first work request from each new agent;
- Review every work request; or
- Allow matching work automatically.
The summary states what Keel will do:
- allow included payment actions only within the configured limits;
- review each payment above $100;
- exclude actions outside the approved Work scope;
- block the job when a required action is excluded;
- route unclassified actions to review before dispatch; and
- honor stricter blocks from every other applicable Policy.
It also previews the records the Policy may cause Keel to issue:
Keel may issue
AI Permit-to-Work — when Keel authorizes one bounded job
AI Permit-to-Pay — when the job issues an exact linked payment authorization
Keel will issue an AI Permit-to-Pay for each linked payment action
authorized under the job.3. Review and save the Policy
Choose Review policy, confirm the summary, name it Invoice Processing Policy, and save it.
The saved object is still a reusable Policy. It is not an AI Permit, it does not reserve authority, and it does not execute anything.
4. The agent requests one bounded job
The verified agent submits a strict Work request for Process invoice INV-2048, with one required payment authority capped at $500 and an explicit expiry.
Keel derives work.authorize, the Work-root role, the verified principal, and
the trusted semantic identity. The agent supplies the declared purpose and
requested limits, but cannot supply the Permit title or trusted semantic.
Keel intersects the request with current Policy. The issued Work scope can be narrower than both the request and the Policy, but never wider.
5. A person reviews the bounded job once
Because this is the first Work request from that verified agent, it appears in Requests as AI Permit-to-Work. The review shows:
- requested job and requested-scope hash;
- required authorities;
- included authorities and their issued limits;
- excluded authorities and reasons; and
- the review route selected by Policy.
The reviewer chooses Approve bounded job or Deny bounded job. Approval authorizes the issued job scope; it does not pre-approve an unlimited stream of actions and does not say that the invoice was processed successfully.
6. Exact payment requests use the issued scope
The Work root never dispatches. For each attempted payment, the agent requests an ordinary exact child Permit linked to the Work root and one named authority.
With this example’s $500 issued job limit and $100 automatic threshold:
| Request | Result | Customer sees |
|---|---|---|
| $84 matching payment | May be allowed without another review | AI Permit-to-Pay, linked to the Work Permit |
| $425 matching payment | Requires its own review | AI Permit-to-Pay with a review-required decision |
| $1,200 payment | Denied | It exceeds both the issued $500 job authority and the $1,000 Policy ceiling |
| Unclassified or out-of-scope action | Review or deny, fail-closed inside Work | No invented Permit-to-X title |
Parent approval removes repetitive review only inside the bounded authority. It does not suppress the per-payment threshold, current Policy, liveness, approval, reservation, or non-bypassable safety checks.
7. Inspect the Permits
Open Permits and select a record. The drawer and full Permit page use the exact trusted title when the signed semantic and released presentation profile support it.
An AI Permit-to-Work page shows:
- Available authority — what the job may still request;
- Permits issued — exact linked action Permits;
- Actions observed — recorded lifecycle evidence, not a task checklist;
- Timeline — dated grant, linked-use, expiry and revocation evidence shown as a visual chronology with a compact event log below it;
- declared purpose, job reference, resource, limits, and signed Policy snapshot;
- current authority status; and
- what the record does not establish.
An AI Permit-to-Pay page says whether it is Linked to a Work Permit or Standalone, then separates:
- authorization;
- approval;
- dispatch;
- external provider outcome; and
- financial settlement.
“Allowed,” “dispatched,” “provider accepted,” and “settled” are not synonyms.
8. End, replace, or revoke Work authority
From the Work Permit page, an authorized operator can:
- End job authority — stop new linked Permits and release safe unused reservations;
- End for replacement — end this authority and explicitly mark the reason; a later request must still ask for replacement; or
- Revoke Permit — revoke the Permit under the existing revocation rules.
Ending or revoking after dispatch cannot retroactively prevent a dispatch that already crossed the recorded execution boundary. None of these controls marks the business job complete or proves settlement.
9. Download and verify evidence
Choose Download Work evidence from the Work Permit page. The dashboard
downloads the separate work-chain.v1 pack. Verify it outside Keel:
keel-verify work-chain work-evidence.jsonBare-path auto-detection is also supported:
keel-verify work-evidence.jsonThe verifier independently adjudicates four claims:
- Work authority manifest;
- exact child containment;
- execution authorization at the dispatch boundary; and
- payment value conservation.
The pack is scope-faithful through its declared cutoff and checkpoint. It does not claim comprehensive runtime recording, Policy correctness, business-job completion, provider success, or payment settlement without the required supporting evidence.
API flow
Work uses the existing Permit API. It does not add a second Permit endpoint family.
Request a Work Permit
Use an API key bound to a verified agent. A Work-root request accepts only
project_id, idempotency_key, and the strict work_request object. Keel
rejects caller-supplied root subject, action, resource attributes, semantic, or
title fields.
curl -sS -X POST "https://api.keelapi.com/v1/permits" \
-H "Authorization: Bearer $KEEL_AGENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project_id": "11111111-1111-1111-1111-111111111111",
"idempotency_key": "work-inv-2048-v1",
"work_request": {
"version": "keel.work_request.v1",
"declared_purpose": "Process invoice INV-2048",
"job_reference": "invoice-job-2048",
"resource": {
"type": "invoice",
"id": "INV-2048",
"digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
},
"requested_authorities": [{
"authority_id": "pay-invoice",
"request_kind": "payment",
"requested_action": "payment.execute",
"max_uses": 1,
"value_max_minor": 50000,
"currency": "USD",
"automatic_review_threshold_minor": 10000,
"recipient_digest": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"purpose_digest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
}],
"required_authority_ids": ["pay-invoice"],
"not_before": "2026-07-22T16:00:00Z",
"expires_at": "2026-07-23T16:00:00Z"
}
}'work.authorize is server-derived. Sending that action without a strict
work_request fails validation.
Request a linked payment Permit
After the root is allowed and any required parent review is satisfied, request
an exact child Permit using both parent_permit_id and work_authority_id.
{
"project_id": "11111111-1111-1111-1111-111111111111",
"parent_permit_id": "<work_permit_id>",
"work_authority_id": "pay-invoice",
"idempotency_key": "pay-inv-2048-84-v1",
"subject": {"type": "agent", "id": "<verified_agent_principal_id>"},
"action": {"name": "payment.execute"},
"resource": {
"type": "invoice",
"id": "INV-2048",
"attributes": {
"provider": "stripe_mpp",
"model": "stripe.mpp.v1",
"operation": "payment.execute",
"modality": "payment",
"execution_mode": "sync",
"estimated_input_tokens": 0,
"estimated_output_tokens": 0,
"max_output_tokens_requested": 0,
"work_resource_digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"spend_scope": {
"amount_max": "8400",
"currency_class": "USD_FIAT",
"cadence": "one_shot",
"ttl_seconds": 3600,
"purpose_binding": "purchase.once",
"recipient_address_digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"description_digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
}
}
}
}The request still uses current Policy and must fit the frozen root authority.
An allow authorizes execution subject to final boundary checks; challenge
requires review; deny does not authorize execution.
Work routes
| Route | Purpose |
|---|---|
POST /v1/permits with work_request | Request one Work-root Permit. |
POST /v1/permits with parent_permit_id and work_authority_id | Request one linked exact action Permit. |
GET /v1/permits/{permit_id}/timeline | Read the Permit-centric dated lifecycle, target, expiry and revocation trail. |
GET /v1/permits/{permit_id}/lineage | Read signed and relational parent/child context. |
GET /v1/permits/{permit_id}/bundle?profile=work-chain.v1 | Download the self-contained Work evidence pack. |
POST /v1/permits/{permit_id}/close | End Work authority with an admin-scoped key. |
POST /v1/permits/{permit_id}/revoke | Revoke a Permit with an admin-scoped key. |
Closing accepts customer_requested, job_no_longer_authorized, or replaced
as the reason code and requires its own idempotency key.
Policy representation
The dashboard compiles the three customer choices into an ordinary Policy rule. Permit titles are not Policy inputs.
{
"name": "Invoice Processing Policy",
"scope": "project",
"rules": [{
"if": {
"all": [
{
"field": "context._keel.verified_agent_principal_id",
"op": "exists",
"value": true
},
{"field": "action.name", "op": "eq", "value": "work.authorize"}
]
},
"action": "constrain_work_authority",
"params": {
"semantic_action": "payment.execute",
"max_uses": 4,
"value_max_minor": 100000,
"currency": "USD",
"automatic_review_threshold_minor": 10000,
"max_validity_seconds": 86400,
"parent_review_mode": "review_first_request_per_agent"
}
}]
}Policy timing
An issued Work Permit freezes the granted maximum and issuance-time Policy snapshot. It does not mutate when the Policy changes.
- Tightening Policy can block a future child request or dispatch without rewriting the issued record.
- Widening Policy does not expand an existing Work Permit. Request a new one.
- Final dispatch rechecks current execution Policy, non-bypassable safety, identity, parent and authority liveness, approval, and reservation state.
- End, revoke, expiry, and replacement remain live gates.
This preserves an honest historical record while letting current controls stop new execution.
How a specific title is earned
Keel uses this hierarchy:
- Policy — reusable rules;
- context authority — a bounded job or session;
- exact action Permit — one consequential action;
- evidence — separate later facts; and
- fallback — generic or unclassified wording when a specific title is not supportable.
A specific Permit-to-X title is admitted only when Keel has a stable meaning, trusted server-owned identity, governed execution boundary, typed fail-closed scope, exact signed binding, evidence with explicit negative space, verifier parity, safe standalone/linked semantics, real environment availability, and an implication audit.
Current presentation vocabulary
| Trusted semantic | Customer title | Status |
|---|---|---|
| One bounded payment job | AI Permit-to-Work | Payment-focused beta |
| Exact payment execution | AI Permit-to-Pay | Specific action title |
| Server-built text generation | AI Permit-to-Generate Text | Specific action title |
| Bounded realtime session | AI Permit — Realtime session | Generic-qualified context title |
| Trusted action without an admitted profile | AI Permit | Generic fallback |
| Insufficiently trusted identity | Unclassified action request | Fail-closed Work fallback |
For example, ai.generate plus generate.text receives
AI Permit-to-Generate Text only on a server-owned governed execution path
with the required signed semantic binding. A caller writing “generate text” in
the declared purpose does not earn that title.
Realtime is deliberately AI Permit — Realtime session. Keel does not call it Permit-to-Speak, Permit-to-Talk, Permit-to-Converse, or Permit-to-Call, because session authorization does not establish participant identity, recording consent, or authority to represent someone.
Availability is not authorization
“Available in this project” means Keel has the connector, entitlement, and trusted contract needed to govern that action type. It does not mean a particular request is allowed. Policy can still allow, require review, deny, or constrain each request.
Declared purpose is not the trusted title
Declared purpose describes what the agent says it is doing. The trusted Permit title states what Keel established about the action type. The former is useful context and signed Work-package data; it cannot choose the latter.
Standalone and linked action Permits
An exact action Permit can be:
- Linked — issued under a compatible Work or session context, with a signed parent reference and narrower contained scope; or
- Standalone — issued directly under a separate applicable Policy.
The action meaning remains the same. The relationship changes the authority chain and evidence shown to the customer, not the meaning of “Pay” or “Generate Text.”
Compatibility and historical records
- Existing Permit and default evidence-bundle bytes remain unchanged.
- Legacy Permits are not backfilled with guessed semantics and render as AI Permit.
- If a historical record names a semantic but the exact presentation material is unavailable, the UI says AI Permit — specific title unavailable for this record.
- A missing presentation profile affects rendering only. It cannot change the original authorization or an independent verifier verdict.
- Cost Permits keep their existing names, routes, and reports.
Beta boundary and future Permit-to-X requests
The first Work beta is payment-focused. AI Permit-to-Generate Text is a real standalone exact title, but its existence does not make the first Work beta a general heterogeneous job system. A non-payment action must separately gain a typed Work authority, comparator, execution gate, evidence, and verifier claim before it can be a linked Work child.
The foundation is designed so an already governed action can be added without a new Permit endpoint family or action-specific dashboard page. That does not make admission automatic.
When requesting another Permit-to-X, send the product and security teams:
Requested customer title:
Stable business action meaning:
Customer problem this title solves:
Standalone, linked, or both:
Server-owned source of action identity:
Governed dispatch surface:
Typed consequential scope and fail-closed comparator:
Fields that must be included in the signed binding:
Execution and outcome evidence available:
Facts the title must explicitly not imply:
Connector and entitlement prerequisites:
Independent verifier claims required:
Example allowed, review-required, denied, and unclassified requests:A request that cannot answer those questions remains AI Permit or Unclassified action request until the contract is supportable.
Related pages
- AI Permits — the base Permit API and decision contract
- Policy Reference — technical Policy syntax
- Running Keel Verify — offline verification
- Realtime Voice — realtime session lifecycle
- Reconciliation — decision, execution, and outcome evidence