# JWKS Key Rotation and Expiration Policy

Alpha Governance Group PBC (https://www.alpha.ac) publishes its public
signing material at:

- OpenID Connect JWKS: `/.well-known/jwks.json`
- Web Bot Auth directory: `/.well-known/http-message-signatures-directory`

This page is the canonical, machine-and-human readable policy for how
those keys are issued, rotated, and retired. It is referenced from both
discovery documents in their `service_documentation` / `policy_uri`
fields.

## Status

Alpha does not currently sign outbound agent or bot requests and does
not currently issue OIDC ID tokens or access tokens. Both key sets are
published as empty arrays so verifiers receive a valid, parseable
response. The policy below takes effect the moment the first key is
provisioned.

## Key types and algorithms

| Use                  | Algorithm | Curve / Modulus | `kty` | `use` |
| -------------------- | --------- | --------------- | ----- | ----- |
| OIDC token signing   | `EdDSA`   | Ed25519         | `OKP` | `sig` |
| OIDC token signing   | `RS256`   | RSA 2048        | `RSA` | `sig` |
| Web Bot Auth signing | `EdDSA`   | Ed25519         | `OKP` | `sig` |

Every published JWK includes `kid`, `alg`, `kty`, `use`, and the
public key material. Private material never leaves the production
HSM / key vault.

## Lifecycle

1. **Issuance.** A new key is generated in the production key vault.
   Its public JWK is added to the relevant `keys` array with a fresh
   `kid` (UUIDv4) and an `x-issued-at` timestamp. The discovery
   document is redeployed.
2. **Activation.** After a propagation window of at least 24 hours
   (to allow downstream caches and verifiers to refresh), signing
   traffic begins using the new key.
3. **Overlap.** The previous active key remains in `keys` for at
   least 30 days after the new key activates. Verifiers MUST accept
   any key currently in the published set.
4. **Retirement.** The previous key is removed from `keys` once the
   30-day overlap elapses and operational metrics confirm no
   verifier is still pinning the retired `kid`.
5. **Compromise.** On suspected compromise, the affected key is
   removed immediately, a new key is issued, and an out-of-band
   notice is sent to known integration partners. The standard 24-hour
   activation window is waived.

## Schedule

- **Routine rotation cadence:** every 180 days, on a published
  calendar maintained by the Alpha platform team.
- **Maximum key lifetime:** 365 days from issuance. Any key older
  than 365 days is rotated regardless of cadence.
- **Discovery cache TTL:** `Cache-Control: public, max-age=300,
must-revalidate` on JWKS and the signature directory. Verifiers
  SHOULD refresh on `kid` mismatch.

## Verifier guidance

- Fetch `/.well-known/jwks.json` over HTTPS only.
- Cache for at most 5 minutes. On any signature verification failure
  caused by an unknown `kid`, refetch and retry once before failing.
- Pin to `kid`, never to a single key's public bytes.
- For Web Bot Auth, fetch `/.well-known/http-message-signatures-directory`
  and verify the published `keys` array using the same caching rules.

## Contact

Operational questions, partner notifications, and compromise
reports: hello@alpha.ac
