> ## Documentation Index
> Fetch the complete documentation index at: https://docs.checkfu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions

> Choose who may act on each resource, when an action needs approval, and which limits still apply.

Permissions determine who may use a resource and which actions they may take.
Start with the acting identity, the exact resource or account, and the intended
action. Then apply policy, any required approval, and the execution and spending
limits for that path.

For example, your application asks a support Agent to create an issue in a
team's GitHub repository. Authenticate the user, select their acting Principal,
and bind the intended GitHub Connection. The required subjects need access to
that Connection and ToolSource. If your ActionPolicy requires review, an
eligible reviewer must approve that exact call. Approval does not grant missing
access or bypass a revoked Connection, an exhausted Budget, or an unsupported
execution path. Reading a private ticket also does not authorize publishing its
contents to the repository.

| Decision | What answers it |
| - | - |
| Who is asking, and for whom? | The authenticated caller and trusted execution identity |
| Which resource or account may they use? | The selected resource and its PermissionAssignments |
| May this exact action proceed now? | ActionPolicy: allow, deny, or require approval |
| Who may approve it? | The responder's current authority for the frozen action |
| Can the work run within its limits? | Current authority, Budget, quota, and supported execution capabilities |

These decisions are separate. A funded Budget grants no permission. An approval
adds no resource access. An API-key role does not grant the Agent every resource
that the key can administer.

Use [Session identity](/reference/access#session-identity) to bind the caller and
acting Principal, [Tools](/concepts/tools) to choose the execution path, and
[Handle an approval](/guides/handle-an-approval) for the review flow.

## Workspace scope

Resources and their governing rules belong to a Workspace:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
Organization
└── Tenant, normally implicit
    └── Workspace
        ├── Vault → Credential
        ├── Connection
        ├── PermissionAssignment
        ├── ActionPolicy
        ├── ActionApproval
        ├── Session
        ├── Usage
        ├── Budgets
        └── Audit and retention controls
```

The Organization is the administrative and commercial root. The Tenant is the
isolation tenant and is normally implicit in public APIs. A Workspace is the
ordinary customer boundary for resources, execution, Usage, governance, and
retention.

An ordinary API key is bound to one Workspace. A request cannot select a
different Workspace with a header. Organization-scoped root operations name
their target explicitly.

## Principals and control-plane identities

A **Principal** represents an end user or service. Keep the authenticated
caller, the end user, the execution identity, and the external account owner
explicit:

| Identity | Trusted source | Role |
| - | - | - |
| Caller | Authenticated API key, Principal credential, or admitted Automation | Initiates the request under that interface's trust model |
| End user | Identity authenticated by your application or the trusted Principal path | The person requesting work; may differ from the service that executes it |
| Execution identity | The admitted Run's `requested_by`, `acted_as`, and Agent or installation binding | Records the requester and the Principal whose runtime permissions are checked |
| Account owner | The selected Connection's `owner_principal_id` | Owns the external account and its credential custody |

Your backend authenticates the end user before asserting an execution Principal.
Keep the original issuer and delegation chain distinct from the requester,
acting Principal, account owner, and payer. An identifier supplied by a browser
or model is not proof of any of those roles. Checkfu API keys remain server-side. Naming a Principal in a Workspace-key
request does not turn that key into an end-user credential or replace the
interface's authorization checks.

Selecting a personal or shared Connection is separate from permission to use
it. Frozen native Connection attachments check the acting Principal and the
Agent; installed non-frozen paths check the Principal and AgentPlacement.
Automation retains its own admitted subject path. Grant each required subject
explicit access to the selected Connection and ToolSource. Non-frozen and
installed gateway paths also require the Connection owner to match `acted_as`.
An uninstalled frozen native attachment can use a separately owned Connection
when its mandatory checks succeed. These identities need not all be equal, and
permission to use an account does not establish permission to share its results
with another audience.

A private Session, a shared conversation, and background work can use the same
Agent with different authority. Loaded context, Files, Memory, browser state,
and checkpoints can retain private information. Reuse needs compatible current
access and an authorized audience; the same Agent or Environment is not enough.
See [Context](/concepts/context#keep-access-current) for retained-input rules.

Keep two authorities separate:

* **API-key role** controls who may author and administer control-plane
  resources.
* **PermissionAssignment** controls whether a Principal, Agent, installation,
  surface, Session, or another admitted subject kind may use a governed resource.

An API-key role does not recursively grant runtime access. A
PermissionAssignment does not mint a stronger API key.

## The governance decision path

Every Connection or other PermissionAssignment-gated effect follows one decision path.

<Note>
  An Agent-declared Custom tool is the deliberate v1 exception. It has no
  PermissionAssignment gate. Its AgentVersion-frozen declaration and exact
  Custom-tool ActionPolicy are the authority: a matching `deny` refuses the
  call, `require_approval` creates an ActionApproval, and no matching rule
  allows the declared tool. Your application still owns its downstream tenant,
  account, and row-level authorization. See
  [Serve Tools from your app](/guides/serve-tools-from-your-app).
</Note>

### 1. Authenticate and bind scope

Checkfu authenticates the API key, resolves its Organization and Workspace, and
resolves the Principal or service actor carried by the trusted request path.
An ID from another Workspace is not authority to read that resource.

### 2. Check the PermissionAssignment

A **PermissionAssignment** answers:

> Does this subject have this permission on this resource?

When no matching active PermissionAssignment exists, the governed action is
denied. An ActionPolicy cannot create the missing permission.

Permission names apply to their declared resource kinds. Environment use,
Computer use, browser or desktop control, network egress, credential use, and
spending are separate decisions. A selected Environment does not grant host
filesystem access or access to a logged-in account.

The Computer tuple declares `use_computer`, `allow_data_egress`, and
`allow_spend`, but its production attachment checks are deferred. A declared
tuple is not an enforcement guarantee. Check the exact path's maintained
[capability status](/getting-started/status) before relying on a refusal.
[Security](/concepts/security) covers isolation and credential custody; a prompt,
setting, or event is not proof that a workload boundary enforces a permission.

PermissionAssignments are immutable authorization facts. Change access by
creating or deleting a row rather than editing its subject, resource, or
permission in place.

### 3. Evaluate the exact ActionPolicy

An **ActionPolicy** evaluates the canonical action, including the subject,
resource, permission, surface, trusted context, and bounded argument
conditions. It returns one disposition:

* `allow`;
* `deny`; or
* `require_approval`.

For an action that has permission, the strongest matching disposition wins:
`deny` over `require_approval` over `allow`. When no ActionPolicy rule matches,
the permission remains allowed unless the operation's typed contract adds a
stricter runtime mutation gate.

ActionPolicy restricts or routes existing authority. It does not grant a
PermissionAssignment, a Credential, commercial entitlement, or support
availability.

`POST /v1/action-policies/evaluate` is a decision query. It does not perform the
effect and does not reserve future authorization.

### 4. Record the human decision

When policy returns `require_approval`, Checkfu creates an
**ActionApproval**. The record freezes the action and the context the responder
was shown. The responder's authority is checked when the response is accepted.

Approval is bounded to that frozen action. Changing arguments, resource,
Connection, destination, or trusted context requires a new decision. Approval
expiry, cancellation, or denial settles the approval without performing the
effect. A permitted decision still needs the appropriate execution path;
approval does not execute an application-owned Custom-tool handler.

Only request a human decision when the governing policy requires it. See
[ActionApprovals](/concepts/action-approvals) for responder authority, exact
argument matching, expiry, and bounded standing approvals.

### 5. Re-check live authority

On the supported execution path, the resource owner rechecks live authority at
the effect boundary, including after waits, replay, reconnect, or recovery.
Earlier decisions do not preserve access. The relevant checks include:

* Workspace and membership state;
* the PermissionAssignment and ActionPolicy;
* the ActionApproval status and frozen context;
* Connection and Credential revocation;
* Budget and quota state; and
* the admitted capability and runtime prerequisites.

A prior approval does not override a revoked Connection, a removed PermissionAssignment,
a new deny policy, an exhausted Budget, or a missing runtime prerequisite.
Current access and audience rules also apply before releasing results or
reusing retained content. A completed effect can remain recorded even when its
result must be withheld.

If authority cannot be evaluated, the boundary must refuse the effect or
release as unavailable. That operational failure is distinct from a decision
that the subject lacks permission. A preview or earlier `allow` is not a
substitute for a current check.

### 6. Perform or refuse the effect

For a custodied provider call, the trusted adapter attaches the credential and
attempts the permitted effect. Raw custodied credential bytes must stay out of
model input, harness configuration, Session events, and sandbox workloads.
Qualify credential exclusion for the exact path; provider responses and
application results can otherwise echo secrets. Customer-executed handlers own
their final authorization and result-release checks.

External systems can fail after accepting a request but before Checkfu receives
a conclusive response. Such effects remain **indeterminate** until reconciled.
Retain the original effect identity and reconcile it before retrying. Do not
switch accounts or create a replacement call to work around an uncertain
outcome or refusal.

### 7. Append Audit

**Audit** is the trusted record that connects identity, authorization, policy,
approval, and observed effect disposition. It can answer who requested the
action, which authority matched, who approved it, and what Checkfu observed.

Audit is not a second Session transcript and does not replace the Session event
log as execution truth. It also does not prove that a provider completed an
external effect when the provider response was uncertain.

## Revocation and Audit are one trust system

Revocation is useful only when it changes the next trusted decision and leaves
evidence of that change.

For a Connection or Credential, Checkfu first marks the local authority
revoked. A later provider call must fail at the next trusted check before secret
attachment. If remote provider revocation cannot complete immediately, its
custody state can remain pending while the local deny remains in force. Audit
records the revocation request, local disposition, remote custody disposition,
and any refused later use.

The same pattern applies to API keys and memberships: new authenticated
requests fail after revocation, while an already-submitted external effect
cannot be retroactively declared absent. Revocation takes effect at the next
enforced boundary; it does not undo a provider request already in flight.

## Budgets and Usage are adjacent, not authorization substitutes

A Budget or Workspace quota can refuse work even when permission and policy
allow it. Conversely, remaining Budget capacity does not grant permission.

Budget decisions use reservations and authoritative Usage facts. Traces are
diagnostic projections and do not enforce Budgets, quotas, billing, policy, or
authorization. See [Attribute Usage](/guides/attribute-usage).

## Retention changes available semantics

Standard retention may keep Session content and recoverable artifacts according
to policy. Zero-data retention omits execution content from durable custody.
That difference changes recovery, replay, and export;
it is not only a storage-duration setting.

Read [Retention and zero-data retention](/concepts/retention-and-zdr) before
enabling a retention mode or designing deletion workflows.

## Support is a separate answer

A valid PermissionAssignment, an `allow` policy result, and an approved action
still do not prove that the capability is live. The selected deployment,
provider lane, runtime tuple, region, retention mode, and prerequisites must be
admitted by the current [capability status](/getting-started/status).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.