# Policy Bundle

## Retrieve

**get** `/policy/bundle`

Returns the effective Policy Bundle for the user identified by the
zone-issued resource-scoped token. When no user-scope binding exists,
one will be generated from the default set.

The response body is a binary archive in the codec selected via the
`Accept` header. The only codec supported today is
`application/vnd.keycard.policy-bundle.v1+tar+gzip`. Clients SHOULD send
an explicit `Accept` header; absent one, the server defaults to the
tar+gzip codec.

Supports conditional fetch via `If-None-Match`: when the supplied ETag
matches the current bundle, the server responds `304 Not Modified` with
no body.

### Header Parameters

- `"If-None-Match": optional string`

- `"X-Client-Request-ID": optional string`

### Example

```http
curl https://api.keycard.ai/policy/bundle \
    -H "Authorization: Bearer $KEYCARD_API_API_KEY"
```

## Update

**put** `/policy/bundle`

Accepts an edited Policy Bundle archive and applies it as the active
user-scope PolicySetVersion for the calling user.

The user's policy set is seeded from the system-default policies on
first access, forked into customer-owned policies; a user bundle
therefore contains only customer-owned policies. Applying an edit
creates a new version of the affected policy, and a `new_policy` entry
adds a further customer-owned policy. Platform-owned catalog policies
are never edited in place by this operation.

The request body codec is determined from `Content-Type`. The only codec
supported today is `application/vnd.keycard.policy-bundle.v1+tar+gzip`.

Supports optimistic concurrency via `If-Match`: when supplied, the server
applies the bundle only if the supplied ETag matches the current bundle
ETag; otherwise responds `412 Precondition Failed`.

On success the server returns the materialized bundle (in the same
codec) and its new `ETag`.

### Header Parameters

- `"If-Match": optional string`

- `"X-Client-Request-ID": optional string`

### Example

```http
curl https://api.keycard.ai/policy/bundle \
    -X PUT \
    -H 'Content-Type: application/octet-stream' \
    -H "Authorization: Bearer $KEYCARD_API_API_KEY" \
    -F 'body=@/path/to/body'
```

## Reset

**delete** `/policy/bundle`

Archives the PolicySet for the calling user (if any),
causing subsequent `GET /policy/bundle` requests to fall back to the
default user policies. Idempotent: returns `204 No Content` even when no
user-scope binding exists.

### Header Parameters

- `"X-Client-Request-ID": optional string`

### Example

```http
curl https://api.keycard.ai/policy/bundle \
    -X DELETE \
    -H "Authorization: Bearer $KEYCARD_API_API_KEY"
```
