# Keel - Permit Protocol for AI agents

Keel is the authority layer around AI execution. Before you do something
consequential - a model call that matters, a tool call, a payment, a system
change, a delegated action - you ask Keel for a **permit**. Keel evaluates the
request against the operator's policy and budget and returns a decision. The
permit is the unit of authority: within a Keel-governed execution path, only a
live `allow` permit authorizes the action to proceed, and each decision creates
tamper-evident evidence that can be exported and independently verified.

Keel does not build you, run you, route your traffic, or act as your identity
provider. It decides what your execution may do, under what authority and at what
cost, and proves it afterward.

## The one rule

> Before a consequential action, request a Keel permit with your own runtime
> credential. Act only on a live `allow`. Treat `deny`, `challenge`, `throttle`,
> expiry, and revocation as **do not act**. Keep the permit reference with the
> action you took.

If you cannot reach Keel, or the decision is anything other than a fresh `allow`,
**fail closed** - do not act.

## Credential, grant, permit, evidence

Four separate things - keep them separate:

- **Credential** - *which Keel principal the request is attributed to.* Your
  operator binds or supplies it. Presenting it authenticates the request; it does
  not prove that your name, parent, provenance, or other metadata is true.
- **Grant** - *what that principal is allowed to request.* Set by an authorized
  human or service principal in the operator's organization.
- **Permit** - *whether this exact action may execute right now.* Issued per
  action; this is the thing you request.
- **Evidence** - a tamper-evident record of what Keel decided, available through
  exports and receipts you can independently verify.

In one line: **credentials authenticate requests, grants define available
authority, permits decide individual actions, evidence proves the decision.** A
credential is not a grant, and a grant is not a permit - only a live `allow`
permit lets an action proceed.

## Request a permit

`POST https://api.keelapi.com/v1/permits`

Authenticate with the runtime key your operator configured for you (env
`KEEL_RUNTIME_KEY`):

```
Authorization: Bearer $KEEL_RUNTIME_KEY
```

Body (minimal - see the SDKs and docs for the full schema):

```json
{
  "project_id": "<your Keel project id>",
  "idempotency_key": "<unique per attempt>",
  "subject":  { "type": "agent",       "id": "<your agent id>" },
  "action":   { "name": "payment.send", "attributes": { "amount_usd": 42.00 } },
  "resource": { "type": "vendor",       "id": "acme-co", "attributes": {} },
  "context":  { "provider_meta": { "provider": "anthropic", "model": "claude-..." } }
}
```

`subject`, `action`, and `resource` are required. Use `session_id` for an
ephemeral session, and `parent_permit_id` to chain a resulting action back to the
permit that authorized the step before it.

Response:

```json
{
  "permit_id": "...",
  "permit_ref": "prm_...",
  "decision": "allow",
  "display_decision": "allow",
  "reason_code": "...",
  "reason": "...",
  "expires_at": "2026-07-11T18:04:00Z",
  "usage_limits": {},
  "decision_impact": {}
}
```

Most builders never call this by hand - the SDK provider wrappers
(`pip install keel-sdk`, `npm install keel-sdk`) request and enforce permits
around your model / proxy / execute calls automatically. Use
`POST /v1/permits/dry-run` to preview a decision without committing to it.

## Handle the decision

- **`allow`** - proceed, but only while the permit is unexpired (`expires_at`)
  and only within the returned constraints (`usage_limits`, `decision_impact`).
  Preserve `permit_ref` with the action you take.
- **`deny`** - do not act.
- **`challenge`** - a human or authorized approver must decide. Do not act until
  the challenge resolves into an `allow`.
- **`display_decision: "throttle"`** - this is a `deny` for rate or spend
  reasons. Back off and retry later; it is not executable.
- **expired or revoked** - not executable. Request a fresh permit.

A permit authorizes exactly the step you described. A permit for a model call
does **not** authorize the tool call or side effect that follows - request a
separate permit for each consequential step.

## After you act

Report usage and attach evidence for the permit you used (the SDK does this for
you; each permit exposes a receipt at `GET /v1/permits/{permit_id}/receipt`).
This is what makes the decision provable after the fact.

## Are you connected?

`GET https://api.keelapi.com/v1/identity/whoami` with your runtime key tells you
which principal and project your credential resolves to. That credential is
configured for you by your operator - a human or service principal in their Keel
project. Keel does not hand credentials to unknown callers, and you must never
generate an approval for yourself.

## Things that are easy to get wrong

- **Being known to Keel is not authority.** Only a live `allow` permit
  authorizes an action. A name, metadata, a parent relationship, or a stored
  credential authorize nothing on their own.
- **Keel does not define your identity or act as your identity provider.** Your
  operator associates your runtime credential with a Keel principal so Keel can
  attribute permit requests to you. The credential says *which principal is
  asking* - not that your provenance claims are true.
- **You may initiate a request, never your own approval.** Authority is granted
  by an authorized human or service principal in the operator's organization.
- **Use only the credential assigned to you.** Metadata is a claim; the
  credential authenticates your request. Never share it, and never act using
  another runtime's credential.
- **Keel does not verify your routing.** That your traffic actually flows through
  Keel, and that direct-provider bypasses are removed, is the operator's
  responsibility. Reaching this endpoint does not establish it.

## Links & versioning

- Discovery: `https://agents.keelapi.com/.well-known/keel.json`
- Summary: `https://agents.keelapi.com/llms.txt`
- Docs & SDKs: `https://docs.keelapi.com`
- Protocol version `0.1` (updated 2026-07-11). Breaking changes ship at a new
  version path; this document always describes currently shipped behavior.
