Skip to content
API Reference
Coming soon: platform-managed policy is not yet generally available.

Platform-Managed Policy

Govern what coding agents may execute from the Keycard platform: a per-user access policy the keycard CLI enforces on every tool call, centrally visible and auditable instead of buried in per-machine settings files.

Every coding agent ships its own permission system, configured in a settings file on the engineer’s machine. That leaves the controls on agent actions invisible to the people accountable for them: you can’t tell what any given agent is allowed to run, whether it matches what your organization approved, or what it actually did.

Platform-managed policy moves those controls into Keycard. The access policy that governs what an agent may execute is stored on the platform and bound to the user running the session. The keycard CLI downloads it at session start, enforces it locally on every agent tool call, and records each decision against the session.

Keycard stores policy in one place and enforces it at distributed enforcement points. Those points sit at two distinct moments in an agent’s work:

Enforcement pointThe question it answersWhere the decision is made
Issuance timeWhich credentials may this agent obtain, for which Resources, and on whose behalf?The Keycard platform, on every credential request
Execution timeWhich tools and commands may this agent run on the machine?The keycard CLI, on every tool call the agent executes locally

The keycard CLI is the execution-time enforcement point, and this page covers that layer. Its policies decide whether a tool call runs, not which credentials the agent can obtain. The two layers are complementary: issuance-time policy can withhold a GitHub credential from an agent entirely, while execution-time policy decides whether that agent may run gh pr merge with a credential it already holds. Both are Cedar and both live in the platform’s access policy system, so they are versioned, integrity-hashed, and auditable the same way.

A drop-in replacement for built-in agent permissions

Section titled “A drop-in replacement for built-in agent permissions”

The controls this replaces are the agent’s own: Claude Code’s permission modes and allow/deny rules, and their equivalents in other agents.

The primary reason to replace them is the trust boundary. Those controls belong to the harness, so the same software that runs the model also decides what the model may do and how that decision reaches you. The agent shapes what an approval prompt says, how a command is described, and what context you see before you approve it. The thing being governed owns the governance.

Keycard evaluates policy outside the harness. The rules come from the platform, the CLI makes the decision, and neither the model nor the harness can change the ruleset, the verdict, or how it is put to you.

Moving the ruleset off the machine adds the properties that make it governable at scale:

  • Transferable: one ruleset follows an engineer across machines, projects, and agents, instead of being re-created in each tool’s own configuration format and drifting between laptops, container, remote instances.
  • Centrally visible: you can see which policies exist, which version each user is enforcing, and every allow, deny, and prompt decision in the session audit trail.
  • A foundation for governance: the primitives here (immutable versions, platform-held bindings, audited decisions) are the ones organization-level policy builds on, where an organization sets a baseline that users can narrow but not widen.

Execution-time policy is scoped to a user, not to a Zone. Engineers need different permissions from one another, and the ruleset reflects that: every user has their own policy set with its own active binding on the platform. The Zone’s active policy set, the one you manage in Console, is the issuance-time ruleset. It is a separate binding and is not what the CLI evaluates on tool calls.

Nobody creates a user’s ruleset by hand. The first time a session asks for it, the platform materializes one from the Keycard-shipped baseline tool-use policy, forked into policies that user owns. From then on, keycard run fetches that user’s bundle at session start: the Cedar policies plus the schema they were validated against. It verifies the bundle’s integrity, caches it, and evaluates every tool call locally against it, with nothing to install or configure on the machine.

ConceptWhat it is
User policy setThe execution-time ruleset for one user, with its own active binding
BaselineThe default tool-use policy Keycard ships. Every user’s set starts as a fork of it
Policy set versionAn immutable, integrity-hashed snapshot of the set
PolicyAn individual Cedar document, versioned on its own
BundleWhat the CLI downloads: the active version’s policies plus the Cedar schema

Policies in a set are evaluated together as one Cedar authorization: a tool call is allowed only if some permit matches and no forbid matches. An @itl("prompt") annotation on a permit adds a third outcome, where the call is allowed but only after the engineer approves it in the loop. An enforced policy can therefore allow, deny, or prompt. See Access Policies for the Cedar syntax.

  • The keycard CLI installed on the machines running agents (see CLI)
  • A Zone the user can sign in to. Their execution-time policy is materialized from the baseline on first use, so there is nothing to provision per user.

Run this yourself to see what an engineer’s session does with their policy.

  1. Start a session

    Terminal window
    keycard run claude

    keycard run signs in if needed, fetches your user’s current policy version, integrity-checks it, and enforces it on every tool call. Nothing is configured per machine. The bound policy applies automatically at start, and the version is pinned for the life of the session, so a session started before a change keeps enforcing the version it began with.

  2. Ask what is being enforced

    From inside the session, ask the agent something like “What policy is being enforced right now?” The Keycard plugin surfaces the active policies, their versions, and the resolving policy set version, which is how anyone can confirm what a machine is actually enforcing.

  3. Trigger a governed tool call

    Run something a permit, forbid, or @itl rule targets and confirm the CLI allows, denies, or prompts as expected. The decision appears in the session’s audit trail in the Console alongside the policy set version that produced it.

Policy edits are conversational and happen inside a session. An engineer describes the change they want, such as “Allow running npm test without prompting”. The agent proposes an updated policy, and on approval it validates the change (Cedar syntax locally, and against the schema on the platform) and publishes it as a new version of that engineer’s policy set.

Three consequences matter when you are assessing this model:

  • A change applies to the engineer who made it and to no one else. Users can only read and write their own policy set, so one person widening their ruleset cannot loosen anyone else’s.
  • The corollary is the current governance gap: there is no Zone-wide execution-time ruleset, so a user can widen their own policy away from the baseline. Organization-level policy that users can narrow but not widen is what closes this.
  • Every change is an immutable, integrity-hashed version with an audit event, so you can reconstruct who changed what and which version was enforced at any point in time. Reverting a user returns their set to the baseline it was forked from.
  • Every tool call is denied. Enforcement is failing closed. The platform may be unreachable with no cached policy, or the cache may be corrupt. Reconnect and start a new session so keycard run can re-fetch.
  • A change was not published. The user’s active policy changed since the session started. Ask the agent to reconcile against the diff it shows and publish again.
  • keycard run cannot load the policy. The session may lack a valid token for the policy resource. Confirm it is targeting the right Zone. keycard run re-establishes sign-in when needed.