# `Raxol.AgentClientProtocol.Ext.Capability.Issuer`
[🔗](https://github.com/DROOdotFOO/raxol-agent/blob/raxol_agent_client_protocol-v0.1.0/packages/raxol_agent_client_protocol/lib/raxol/agent_client_protocol/ext/attach_policy/token.ex#L347)

The signing side. Mints `RXC1` tokens.

**NEVER invoked on any verify path** — `Capability.Token`, `AttachPolicy.Token`
and `Runner` have zero reference to this module or to any private-key source
(grep/xref-verifiable). The private key never lives in the verifier.

Issuance caps are enforced: an interactive attach token is capped at TTL
**1 hour**; a longer TTL (up to **30 days**) requires an explicit
`archival: true` opt-in. `:max_ttl` can only lower the applicable cap,
never raise it. A 30-day token is a deliberate operator choice (the expiry
bounds an archive's protocol-readability window), never an accidental
default.

# `privkey_source`

```elixir
@type privkey_source() ::
  binary()
  | {:env, String.t()}
  | {:file, String.t()}
  | {:fun, (-&gt; binary())}
  | {:raw, binary()}
```

A private-key source. Raw binary is a 32-byte Ed25519 seed.

# `generate_keypair`

```elixir
@spec generate_keypair() :: {binary(), binary()}
```

Generate a fresh `{public_key, private_seed}` Ed25519 keypair.

# `sign`

```elixir
@spec sign(map(), String.t(), privkey_source(), keyword()) ::
  {:ok, binary()} | {:error, atom()}
```

Sign `claims` under `kid`. `claims` MUST carry integer `iat`/`exp`
(`exp > iat`). Enforces the TTL cap (`archival: true` opt-in for up to 30 days).

Returns `{:ok, token}` — the `RXC1` string — or `{:error, reason}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
