PolicySetManifest

Apply the full desired state of a policy set

Changed on

Declarative full-replace apply. entries is the complete desired content of the policy set: any policy omitted from entries is dropped from the resulting version (its rows are retained and a later apply may reference it again). Entry order is preserved for newly added policies; retained policies keep their current manifest order, so an unchanged apply is byte-identical and dedups to the existing version.

Per entry, the server diffs by content SHA against the version pinned in the latest manifest: unchanged content under the same schema version reuses the pinned policy version; changed content mints a new policy version; new_policy entries mint a customer-owned policy with the requested name. All of this, plus the policy set version mint and the optional activation, happens in one transaction (row lock on the policy set). Cedar validation runs against the resolved schema before the transaction opens — an invalid policy rejects the whole apply with zero writes.

Schema resolution: schema_version omitted → the latest version's schema if still writable, else the zone default. Provided → authoritative (schema_version_unsupported if unknown, unattested, or archived). All entries validate against the single resolved version (uniform-schema-per-version is retained); a pinned policy version created under a different schema is re-versioned even if its content is unchanged.

Activation: activate: true requires a zone-targeted set and rebinds the (zone, target_type=zone, mode=active) slot to the resulting version in the same transaction. It requires policy_set_bindings:activate permission and preserves the previous binding in binding history. Unchanged content returns created: false and still activates the resulting version. An already active version keeps its binding unchanged.

Concurrency: If-Match is optional (omitted = last-writer-wins). When provided it is compared, under the row lock, against the digest of the latest version's manifest; mismatch returns 412 (etag_mismatch) carrying the current ETag. The token is content-addressed, not a version identity: it guards "the content I read is still the content in place", so two versions with identical manifests are interchangeable for the precondition, and archiving the tip does not invalidate a token whose digest the new latest version still carries. Do not re-key it on policy_set_version_id.

Identity and reverts: a desired state identical to the latest version is a no-op (created: false, latest returned, nothing minted). A desired state matching an older version mints a new version at the tip — history is linear, never forked. Rolling back deployment without a content edit is not an apply at all: bind the older version via PUT /policy-bindings.

Authorization: the route gate is update on the policy set. When activate: true, the handler additionally requires the activate action on policy_set_bindings.

Domain error codes: policy_set_not_found, policy_not_found, policy_version_not_found, version_archived, schema_version_mismatch, manifest_duplicate_policy, missing_cedar_content, invalid_cedar, schema_version_unsupported, policy_name_conflict, policy_archived, set_archived, etag_mismatch, activate_requires_zone_target, shadow_equals_active.

put/zones/{zone_id}/policy-sets/{policy_set_id}/manifest

Request

  • Base URL
    https://docs.keycard.ai (the document declares no server; this is the origin it was published from)
  • URL
    https://docs.keycard.ai/zones/{zone_id}/policy-sets/{policy_set_id}/manifest
  • Auth
    • HTTP bearer
    • or OAuth 2
      Client credentials
      Token URL: /service-account-token

Path parameters

zone_idstring required

The zone identifier

policy_set_idstring required

The policy set identifier

Query parameters

dry_runboolean

Not yet implemented — true returns 501 until ACC-1002. When true, performs validation, schema resolution, and the content diff, and returns the would-be changes and warnings — but persists nothing. policy_set_version is omitted from the response and no ETag is returned.

Headers

If-Matchstring

ETag value from a previous GET/POST/PATCH response. When provided, the update only succeeds if the resource has not been modified; otherwise 412 Precondition Failed is returned.

X-API-Versionstring

API version header (date-based, e.g. 2026-02-01)

X-Client-Request-IDstring uuid

Unique request identifier specified by the originating caller and passed along by proxies.

Request body

schema_versionstring

Cedar schema version to validate and pin the resulting version against. Omitted: the server resolves it (latest version's schema if still writable, else the zone default).

activateboolean

Also rebind the zone/active slot to the resulting version in the same transaction. Requires the activate permission on policy set bindings. Targets only the zone/active slot; other slots go through PUT /policy-bindings.

Response

The apply result. Always 200 — the resulting version may be newly minted (created: true), deduped to an existing version, or a pure no-op (created: false); the body discriminates so clients never branch on status.

createdboolean required

True when the server mints a new policy set version. False when the content matches the latest version, even when activate changes the active binding. Reverts to older content mint a new version at the tip and return true.

Changes