Stella Ops Disaster Recovery Guide
Audience: TUF/trust administrators, security responders, and platform operators. Purpose: Recover the Stella Ops trust infrastructure during a Rekor outage, key compromise, or TUF repository failure, using the shipped
stella trustCLI anddevops/scripts/tooling.
Sprint: SPRINT_20260125_003 — WORKFLOW-003. Last updated: 2026-05-30 (reconciled against
src/Attestor,src/Cli, anddevops/scripts/).
Tooling note (verified against source): The DR scripts referenced below (
disaster-swap-endpoint.sh,rotate-rekor-key.sh,rotate-signing-key.sh,bootstrap-trust-offline.sh) exist underdevops/scripts/. The operator CLI ships astella trustcommand group with exactly these subcommands:init,sync,status,verify,export,import, andsnapshot export(src/Cli/StellaOps.Cli/Commands/Trust/TrustCommandGroup.cs). There is nostella rekorgroup and noreset-circuitssubcommand. Several commands in earlier drafts of this guide named flags that do not exist; those have been corrected inline below.
Overview
This guide covers disaster recovery procedures for Stella Ops trust infrastructure, including Rekor outages, key compromise, and TUF repository failures.
| Scenario | Trigger | Jump to |
|---|---|---|
| Rekor service outage | Attestation/verification failures, circuit breaker OPEN | Scenario 1 |
| Rekor key compromise | Suspected Rekor key exposure | Scenario 2 |
| TUF repository unavailable | Clients cannot sync trust metadata | Scenario 3 |
| Signing key compromise | Suspected signing key exposure | Scenario 4 |
| Root key ceremony required | Scheduled/emergency root rotation | Scenario 5 |
Scenario 1: Rekor Service Outage
Symptoms
- Attestation submissions failing
- Verification requests timing out
- Circuit breaker reporting OPEN state
Immediate Actions
Verify the outage
# Check Rekor health curl -sf https://rekor.sigstore.dev/api/v1/log | jq .The Rekor circuit breaker is a server-side component inside the Attestor (
StellaOps.Attestor.Core.Resilience.CircuitBreaker, wrapped byResilientRekorClient). Its state (Closed/Open/HalfOpen) is not exposed by thestellaCLI — there is nostella trust status --show-circuit-breakerflag (the onlystella trust statusflags are--show-keys/-k,--show-endpoints/-e, and--output/-o). Observe the breaker via the Attestor service logs, which emitCircuit {Name} transitioned from {OldState} to {NewState}andPrimary Rekor circuit breaker: {OldState} -> {NewState}on every transition.Check if mirror failover engaged
The Attestor’s
ResilientRekorClientperforms automatic mirror failover when the primary circuit opens (it routes operations to the configured mirror with no operator action). There is nostella trust status --show-backendscommand. Confirm failover from the Attestor logs (Primary circuit is OPEN, routing {Operation} to mirror) and from whether the mirror is configured inAttestorOptions(Rekormirror settings) before relying on it.If the mirror is not available, swap endpoints via TUF
# On TUF repository admin system ./devops/scripts/disaster-swap-endpoint.sh \ --repo /path/to/tuf \ --new-rekor-url https://rekor-mirror.internal:8080 \ --note "Emergency: Production Rekor outage $(date -u)"The script prompts for an interactive confirmation: type
SWAPto proceed. Accepted flags are--repo,--new-rekor-url(both required),--new-fulcio-url,--note, and--version(auto-increments the service-map version if omitted). It writes a newsigstore-services-v{N}.jsontarget; it does not sign or publish the metadata — that is the next step.Sign and publish the updated metadata
The swap script only stages the new service map. You must then sign the updated TUF metadata (
targets.json→snapshot.json→timestamp.json, each with its respective key) and deploy it to the TUF server. These signing and publish steps use the TUF repository’s own tooling (e.g. thescripts/sign-metadata.sh/scripts/publish.shthat live in your TUF repo directory); they are not commands shipped by StellaOps. The swap script prints the exact required next steps when it completes.Force client sync (optional, for immediate effect)
stella trust sync --force
Key Principle
No client reconfiguration required. Endpoint changes flow through TUF. Clients discover new endpoints within their configured refresh interval.
Recovery
Once the primary Rekor is restored:
Swap back to primary
./devops/scripts/disaster-swap-endpoint.sh \ --repo /path/to/tuf \ --new-rekor-url https://rekor.sigstore.dev \ --note "Recovery: Primary Rekor restored"Verify the service map published
stella trust sync --force stella trust status --show-endpointsCircuit breakers recover automatically
There is no
stella trust reset-circuitscommand. The Attestor circuit breaker self-heals: once a primary is reachable again it transitionsOpen → HalfOpenautomatically afterOpenDurationSecondsand back toClosedafterSuccessThresholdconsecutive successful probes (seeCircuitBreaker.cs). AReset()to force-close exists only as an in-process API onResilientRekorClient/CircuitBreaker; it is not exposed to operators. To force an immediate re-probe you can restart the Attestor service.
Scenario 2: Rekor Key Compromise
Symptoms
- Security team reports potential key exposure
- Unusual entries in transparency log
- Third-party security advisory
Immediate Actions
Assess the compromise scope
- When was the key potentially exposed?
- What entries may be affected?
- Are there signed entries from the compromised period?
Emergency key rotation
# Phase 1: Add new key immediately (no grace period) ./devops/scripts/rotate-rekor-key.sh add-key \ --repo /path/to/tuf \ --new-key /secure/new-rekor-key-v2.pub # Sign and publish immediately cd /path/to/tuf ./scripts/sign-metadata.sh ./scripts/publish.shForce all clients to sync
- Announce emergency update to all teams
- Clients should run:
stella trust sync --force
Revoke compromised key immediately
# Phase 2: Remove old key (skip grace period due to compromise) ./devops/scripts/rotate-rekor-key.sh remove-old \ --repo /path/to/tuf \ --old-key-name rekor-key-v1 # Sign and publish (use your TUF repo's own signing/publish tooling) cd /path/to/tuf ./scripts/sign-metadata.sh ./scripts/publish.shremove-oldrequires--repoand--old-key-name, is interactive (promptsType 'CONFIRM' to proceed), and is irreversible. It removes the key file fromtargets/but the script itself does not rewritetargets.jsonor sign/publish — it reminds you to updatetargets.jsonand then sign and publish via your TUF repo’s tooling.add-keyaccepts--repo,--new-key, optional--new-key-name(defaults torekor-key-v{N+1}), and--grace-days(default 7).Document the incident
- Log rotation time
- Affected key ID and fingerprint
- List of potentially affected entries
- Remediation steps taken
Forensics
Identify entries signed during the compromise window.
NOT IMPLEMENTED: There is no
stella rekor querycommand in the CLI (thestellaCLI ships astella trustgroup —init,sync,status,verify,export,import,snapshot export— but norekorgroup). Perform time-range forensics directly against the Rekor transparency log API (e.g. the upstreamrekor-clior the Rekor REST API), correlating entries by the compromised key’s public-key fingerprint:# Example using the upstream Rekor REST API (not a StellaOps command) curl -sf "https://rekor.sigstore.dev/api/v1/index/retrieve" \ -H "Content-Type: application/json" \ -d '{"publicKey": {"format": "x509", "content": "<base64-pubkey>"}}' | jq .Cross-reference the returned entry indices against the compromise window using each entry’s
integratedTime.
Scenario 3: TUF Repository Unavailable
Symptoms
- Clients cannot sync trust metadata
stella trust syncfailing with network errors- TUF timestamp verification failing
Immediate Actions
Diagnose the issue
# Check TUF repository health curl -sf https://trust.example.com/tuf/timestamp.json | jq . # Check DNS resolution nslookup trust.example.com # Check TLS certificate openssl s_client -connect trust.example.com:443 -servername trust.example.comFor clients - tolerate stale metadata
stella trust synchas no--allow-stale/--max-ageflags (its only options are--force/-fand--output/-o). Staleness tolerance is enforced at import time, not sync time: the--reject-if-stalethreshold onstella trust import(e.g.--reject-if-stale 7d) decides whether an offline bundle is accepted. When the TUF server is unreachable, clients continue to verify against their already-cached trust state (under~/.local/share/StellaOps/TufCache) until a fresh sync succeeds; there is no flag to relax the live freshness check onsync. To re-seed from a known-good offline bundle while the server is down, import with an explicit staleness bound:stella trust import ./trust-bundle.tar.zst --reject-if-stale 7dRestore TUF server
- Check hosting infrastructure
- Restore from backup if needed
- Verify metadata integrity
Deploy mirror (if available)
# Update DNS or load balancer to point to mirror # Or update clients directly (less preferred) stella trust init \ --tuf-url https://trust-mirror.example.com/tuf/ \ --force
Scenario 4: Signing Key Compromise
Symptoms
- Security team reports key exposure
- Unauthorized attestations appearing
Immediate Actions
Generate the replacement key first
./devops/scripts/rotate-signing-key.sh generate \ --key-type ecdsa-p256Valid
--key-typevalues areecdsa-p256(default),ecdsa-p384, andrsa-4096. Keys are written under--key-dir(default/etc/stellaops/keys) assigning-key-v{N}.pem/.pub. Generate the new key before retiring the old one so signing capability is never lost.Retire the compromised key
./devops/scripts/rotate-signing-key.sh retire \ --old-key compromised-key-nameretirerequires--old-keyand is interactive and irreversible: it promptsType 'RETIRE' to proceedand then archives (does not delete) the old key under<key-dir>/archived/. The script’s normal flow isgenerate → activate → verify → retirewith a default 14-day grace period; in a confirmed-compromise scenario you skip the grace period and retire immediately, but you still complete the CI/CD and notification steps below.Update CI/CD immediately
- Remove compromised key from all pipelines
- Add new key
- Trigger rebuild of recent releases
Notify downstream consumers
- Announce key rotation
- Provide new public key
- Advise re-verification of recent attestations
Scenario 5: Root Key Ceremony Required
When Required
- Scheduled root key rotation (typically annual)
- Root key compromise (emergency)
- Threshold change for root signatures
Procedure
Schedule ceremony
- Require M-of-N key holders present
- Air-gapped ceremony machine
- Hardware security modules
Generate new root
NOT IMPLEMENTED (no shipped tool): StellaOps does not ship a
tuf-ceremonybinary — there is no such command anywhere insrc/ordevops/. Generate the new root with your standard TUF tooling (tuf/python-tuf,cosign/sigstoreroot signing, or your HSM-backed ceremony procedure). The illustrative command below is not a StellaOps command:# Illustrative only — use your organization's TUF ceremony tooling tuf-ceremony init --threshold 3 --keys 5 --algorithm ed25519Sign new root with old keys
- Requires old threshold of signatures
- Ensures continuous trust chain
Distribute new root
- Publish to TUF repository
- Update bootstrap documentation
- Notify all operators
Air-Gap Considerations
For air-gapped deployments after root rotation:
# Export a trust bundle for offline distribution.
# NOTE: there is no `--include-root` flag. `stella trust snapshot export`
# accepts: --out/-o (required), --from-proxy, --tiles, --include-entries, --depth.
# The exported snapshot carries the current TUF metadata (including the root that
# is part of the synced trust state) — it does not need an explicit root flag.
stella trust snapshot export \
--out post-rotation-bundle.tar.zst
# Alternatively, export the plain trust state (TUF metadata + targets):
# stella trust export --out ./post-rotation-bundle/
# Transfer and import on air-gapped systems
./devops/scripts/bootstrap-trust-offline.sh \
post-rotation-bundle.tar.zst \
--force # Required due to root change
The offline bootstrap script imports the bundle via
stella trust import(--verify-manifestis on by default) and then verifies withstella trust status --show-keys.--forceis passed through to the import so a root change does not fail manifest validation.
Communication Templates
Outage Notification
Subject: [StellaOps] Rekor Service Disruption - Failover Active
Status: Service Degradation
Impact: Attestation submissions may be delayed
Mitigation: Automatic failover to mirror active
Action Required: None - clients will auto-discover new endpoint
Updates: Monitor status at https://status.example.com
Key Rotation Notice
Subject: [StellaOps] Emergency Key Rotation - Action Required
Reason: Security precaution / Scheduled rotation
Affected Key: rekor-key-v1 (fingerprint: abc123...)
New Key: rekor-key-v2 (fingerprint: def456...)
Action Required:
1. Run: stella trust sync --force
2. Verify: stella trust status --show-keys
Timeline: Old key will be revoked at [DATE/TIME UTC]
Monitoring and Alerting
Key Metrics
- Circuit breaker state changes
- TUF metadata freshness
- Rekor submission latency
- Verification success rate
Alert Thresholds
| Metric | Warning | Critical |
|---|---|---|
| TUF metadata age | > 12h | > 24h |
| Circuit breaker opens | > 2/hour | > 5/hour |
| Submission failures | > 5% | > 20% |
| Verification failures | > 1% | > 5% |
Contacts
| Role | Contact | Escalation |
|---|---|---|
| TUF Admin | tuf-admin@example.com | On-call |
| Security Team | security@example.com | Immediate |
| Platform Team | platform@example.com | Business hours |
