- Introduced AGENTS.md, README.md, TASKS.md, and implementation_plan.md for Vexer, detailing mission, responsibilities, key components, and operational notes. - Established similar documentation structure for Vulnerability Explorer and Zastava modules, including their respective workflows, integrations, and observability notes. - Created risk scoring profiles documentation outlining the core workflow, factor model, governance, and deliverables. - Ensured all modules adhere to the Aggregation-Only Contract and maintain determinism and provenance in outputs.
4.3 KiB
Authority Signing Key Rotation Playbook
Status: Authored 2025-10-12 as part of OPS3.KEY-ROTATION rollout.
Use together withdocs/11_AUTHORITY.md(Authority service guide) and the automation shipped underops/authority/.
1. Overview
Authority publishes JWKS and revocation bundles signed with ES256 keys. To rotate those keys without downtime we now provide:
- Automation script:
ops/authority/key-rotation.sh
Shell helper that POSTS to/internal/signing/rotate, supports metadata, dry-run, and confirms JWKS afterwards. - CI workflow:
.gitea/workflows/authority-key-rotation.yml
Manual dispatch workflow that pulls environment-specific secrets, runs the script, and records the result. Works across staging/production by passing theenvironmentinput.
This playbook documents the repeatable sequence for all environments.
2. Pre-requisites
- Generate a new PEM key (per environment)
openssl ecparam -name prime256v1 -genkey -noout \ -out certificates/authority-signing-<env>-<year>.pem chmod 600 certificates/authority-signing-<env>-<year>.pem - Stash the previous key under the same volume so it can be referenced in
signing.additionalKeysafter rotation. - Ensure secrets/vars exist in Gitea
<ENV>_AUTHORITY_BOOTSTRAP_KEY<ENV>_AUTHORITY_URL- Optional shared defaults
AUTHORITY_BOOTSTRAP_KEY,AUTHORITY_URL.
3. Executing the rotation
Option A – via CI workflow (recommended)
- Navigate to Actions → Authority Key Rotation.
- Provide inputs:
environment:staging,production, etc.key_id: newkid(e.g.authority-signing-2025-dev).key_path: path as seen by the Authority service (e.g.../certificates/authority-signing-2025-dev.pem).- Optional
metadata: comma-separatedkey=valuepairs (for audit trails).
- Trigger. The workflow:
- Reads the bootstrap key/URL from secrets.
- Runs
ops/authority/key-rotation.sh. - Prints the JWKS response for verification.
Option B – manual shell invocation
AUTHORITY_BOOTSTRAP_KEY=$(cat /secure/authority-bootstrap.key) \
./ops/authority/key-rotation.sh \
--authority-url https://authority.example.com \
--key-id authority-signing-2025-dev \
--key-path ../certificates/authority-signing-2025-dev.pem \
--meta rotatedBy=ops --meta changeTicket=OPS-1234
Use --dry-run to inspect the payload before execution.
4. Post-rotation checklist
- Update
authority.yaml(or environment-specific overrides):- Set
signing.activeKeyIdto the new key. - Set
signing.keyPathto the new PEM. - Append the previous key into
signing.additionalKeys. - Ensure
keySource/providermatch the values passed to the script.
- Set
- Run
stellaops-cli auth revoke exportso revocation bundles are re-signed with the new key. - Confirm
/jwkslists the newkidwithstatus: "active"and the previous one asretired. - Archive the old key securely; keep it available until all tokens/bundles signed with it have expired.
5. Development key state
For the sample configuration (etc/authority.yaml.sample) we minted a placeholder dev key:
- Active:
authority-signing-2025-dev(certificates/authority-signing-2025-dev.pem) - Retired:
authority-signing-dev
Treat these as examples; real environments must maintain their own PEM material.
6. References
docs/11_AUTHORITY.md– Architecture and rotation SOP (Section 5).docs/modules/authority/operations/backup-restore.md– Recovery flow referencing this playbook.ops/authority/README.md– CLI usage and examples.scripts/rotate-policy-cli-secret.sh– Helper to mint newpolicy-clishared secrets when policy scope bundles change.
7. Appendix — Policy CLI secret rotation
Scope migrations such as AUTH-POLICY-23-004 require issuing fresh credentials for the policy-cli client. Use the helper script committed with the repo to keep secrets deterministic across environments.
./scripts/rotate-policy-cli-secret.sh --output etc/secrets/policy-cli.secret
The script writes a timestamped header and a random secret into the target file. Use --dry-run when generating material for external secret stores. After updating secrets in staging/production, recycle the Authority pods and confirm the new client credentials work before the next release freeze.