This runbook defines operational procedures for introducing and running cryptographic signing in the ClawSec repository.
It covers:
- key generation
- GitHub secret management
- signing workflow integration
- key rotation and revocation
- incident response
On main, advisory and release channels are signed and verified by default:
- Feed writers:
.github/workflows/poll-nvd-cves.ymlupdatesadvisories/feed.jsonand signsadvisories/feed.json.sig.github/workflows/community-advisory.ymldoes the same for approved issue reports- both sync signed feed artifacts into
skills/clawsec-feed/advisories/
- Feed publish path:
.github/workflows/deploy-pages.ymlpublishespublic/advisories/feed.json+.sig- generates and signs
public/checksums.json+public/checksums.sig - publishes canonical key as
public/signing-public.pemandpublic/advisories/feed-signing-public.pem - mirrors compatibility artifacts under
public/releases/latest/download/(includingfeed.json,feed.json.sig,checksums.json,checksums.sig,signing-public.pem)
- Feed consumers:
skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.tsskills/clawsec-suite/scripts/guarded_skill_install.mjsskills/clawsec-nanoclaw/lib/advisories.ts- default feed URL is
https://clawsec.prompt.security/advisories/feed.json
Unsigned mode remains an explicit compatibility bypass (CLAWSEC_ALLOW_UNSIGNED_FEED=1) and is not the steady-state operating model.
advisories/feed.json(payload)advisories/feed.json.sig(detached Ed25519 signature; base64)advisories/feed-signing-public.pem(pinned public key)
<release>/checksums.json<release>/checksums.sig<release>/signing-public.pem
- Security owner: approves key lifecycle changes and incident actions.
- Platform owner: maintains workflows and GitHub secrets.
- Reviewer: validates fingerprints in PRs/releases.
Policy:
- private keys are never committed
- public keys are committed and code-reviewed
- key generation occurs on trusted operator workstation or HSM-backed environment
Run from a secure workstation. Do not run on shared CI runners.
# Feed signing keypair
openssl genpkey -algorithm Ed25519 -out feed-signing-private.pem
openssl pkey -in feed-signing-private.pem -pubout -out feed-signing-public.pem
# Release checksums signing keypair (optional separate key)
openssl genpkey -algorithm Ed25519 -out release-signing-private.pem
openssl pkey -in release-signing-private.pem -pubout -out release-signing-public.pemGenerate fingerprints (store in ticket/change record):
openssl pkey -pubin -in feed-signing-public.pem -outform DER | shasum -a 256
openssl pkey -pubin -in release-signing-public.pem -outform DER | shasum -a 256Optional test-sign before publishing:
echo '{"probe":"ok"}' > /tmp/probe.json
openssl pkeyutl -sign -rawin -inkey feed-signing-private.pem -in /tmp/probe.json -out /tmp/probe.sig.bin
openssl base64 -A -in /tmp/probe.sig.bin -out /tmp/probe.sig
openssl base64 -d -A -in /tmp/probe.sig -out /tmp/probe.sig.bin
openssl pkeyutl -verify -rawin -pubin -inkey feed-signing-public.pem -in /tmp/probe.json -sigfile /tmp/probe.sig.binCLAWSEC_SIGNING_PRIVATE_KEY— PEM-encoded Ed25519 private key (used for both feed and release signing)CLAWSEC_SIGNING_PRIVATE_KEY_PASSPHRASE— (optional) passphrase if the private key is encrypted
- Go to Repo Settings → Secrets and variables → Actions → New repository secret.
- Paste full PEM including header/footer.
- Prefer GitHub Environment secrets (with required reviewers) for workflow scoping when possible.
- Record change ticket with:
- secret name
- creator
- creation time
- key fingerprint
- Require manual approval for workflows that can use signing secrets.
- Restrict who can edit protected workflows.
- Enable branch protection for
mainand require review for workflow changes.
This repo enforces signing as a post-mutation, pre-publish control.
Current feed mutation points:
.github/workflows/poll-nvd-cves.yml.github/workflows/community-advisory.yml
Current behavior:
- workflow step signs
advisories/feed.jsonintoadvisories/feed.json.sig - signing action verifies generated signatures during workflow execution
- signed artifacts are committed via PR automation
Current publisher:
.github/workflows/deploy-pages.yml
Current behavior:
- copies payload/signature to
public/advisories/ - generates + signs
public/checksums.jsonandpublic/checksums.sig - publishes signing key to
public/signing-public.pemandpublic/advisories/feed-signing-public.pem - mirrors advisory + signature/checksum/key companions into
public/releases/latest/download/compatibility paths
Current release generator:
.github/workflows/skill-release.yml
Current behavior:
- creates
checksums.json, signs it aschecksums.sig, and verifies signature before publish - includes
signing-public.pemin release assets - validates generated public-key fingerprint against canonical key material
- Routine: every 90 days (or stricter org policy).
- Immediate: on suspected exposure, unauthorized workflow change, or unexplained signature mismatch.
- Generate new keypair(s).
- Open PR that updates public key file(s) and fingerprints documentation.
- Add new private key(s) as GitHub secret(s).
- Merge workflow changes that use new key(s).
- Re-sign latest feed/release manifests.
- Validate verification in CI and in one external client.
- Remove old private key secret(s).
- Keep old public key reference only as long as required for historical verification.
- Disable workflows using compromised key.
- Remove compromised GitHub secret(s).
- Commit revocation note and new public key.
- Re-sign latest artifacts with replacement key.
- Publish incident advisory with timestamp and impacted window.
- signature verification fails for newly published feed/release
- unknown commits/workflow edits touching signing paths
- leaked key material, accidental logging, or suspicious secret access
- SEV-1: key exfiltration confirmed or maliciously signed payload published
- SEV-2: verification failures with unknown cause
- SEV-3: procedural non-compliance, no active compromise
- Containment
- pause signing/publish workflows
- block further feed merges if authenticity is uncertain
- Investigation
- review workflow run logs
- review commits affecting
.github/workflows/,advisories/, and key files - determine first-bad timestamp and affected artifacts
- Eradication
- rotate/revoke compromised key(s)
- restore trusted artifacts from known-good commit
- Recovery
- re-sign artifacts
- redeploy pages/releases
- verify via independent client check
- Post-incident
- publish timeline and remediation summary
- tighten controls (review gates, protected environments, secret scope)
For each release cycle or feed-signing run, retain:
- workflow run URL and commit SHA
- signer key fingerprint in use
- verification result logs
- operator/reviewer approvals
- any exception or bypass rationale
Before tightening policy further (for example, removing compatibility bypass paths):
- signed artifacts are produced consistently for at least 2 weeks
- deploy pipeline mirrors signature companions
- one rollback drill and one key rotation drill completed successfully
- incident response on-call owner identified and documented
- advisories/feed.json
- advisories/feed.json.sig
- advisories/feed-signing-public.pem
- clawsec-signing-public.pem
- .github/actions/sign-and-verify/action.yml
- .github/workflows/poll-nvd-cves.yml
- .github/workflows/community-advisory.yml
- .github/workflows/deploy-pages.yml
- .github/workflows/skill-release.yml
- scripts/ci/verify_signing_key_consistency.sh
- wiki/migration-signed-feed.md