Files
git.stella-ops.org/docs/operations/key-rotation-runbook.md
master 8bbfe4d2d2 feat(rate-limiting): Implement core rate limiting functionality with configuration, decision-making, metrics, middleware, and service registration
- Add RateLimitConfig for configuration management with YAML binding support.
- Introduce RateLimitDecision to encapsulate the result of rate limit checks.
- Implement RateLimitMetrics for OpenTelemetry metrics tracking.
- Create RateLimitMiddleware for enforcing rate limits on incoming requests.
- Develop RateLimitService to orchestrate instance and environment rate limit checks.
- Add RateLimitServiceCollectionExtensions for dependency injection registration.
2025-12-17 18:02:37 +02:00

430 lines
10 KiB
Markdown

# Key Rotation Runbook
> **Module**: Signer / Key Management
> **Version**: 1.0.0
> **Last Updated**: 2025-12-17
This runbook describes procedures for managing signing key lifecycle in StellaOps, including key rotation, revocation, and trust anchor management.
---
## Overview
StellaOps uses signing keys to create DSSE envelopes for proof chain attestations. Key rotation is critical for:
- Limiting exposure from compromised keys
- Compliance with key age policies (e.g., NIST SP 800-57)
- Transitioning between cryptographic algorithms
### Key Principles
1. **Never mutate old DSSE envelopes** - Signed content is immutable
2. **Never remove keys from history** - Move to `revokedKeys`, don't delete
3. **Publish key material** - Via attestation feed or Rekor-mirror
4. **Audit all changes** - Full log of key lifecycle events
5. **Maintain key version history** - For forensic verification
---
## Signing Key Profiles
StellaOps supports multiple signing key profiles for different security requirements:
| Profile | Algorithm | Key Store | Use Case |
|---------|-----------|-----------|----------|
| `default` | SHA256-ED25519 | AWS KMS | Standard production |
| `fips` | SHA256-ECDSA-P256 | HSM (PKCS#11) | FIPS 140-2 environments |
| `gost` | GOST-R-34.10-2012 | Local HSM | Russian regulatory |
| `sm2` | SM2-P256 | Local HSM | Chinese regulatory |
| `pqc` | ML-DSA-65 | Software | Post-quantum ready |
### Profile Configuration
```yaml
# /etc/stellaops/signer.yaml
signer:
profiles:
default:
algorithm: "SHA256-ED25519"
keyStore: "kms://aws/key/stellaops-default"
rotation:
enabled: true
maxAgeMonths: 12
warningMonths: 2
fips:
algorithm: "SHA256-ECDSA-P256"
keyStore: "hsm://pkcs11/slot/0"
rotation:
enabled: true
maxAgeMonths: 12
warningMonths: 2
```
---
## Key Rotation Workflow
### Step 1: Generate New Key
Generate a new signing key in the configured key store:
```bash
# Using CLI
stellaops key generate \
--profile default \
--key-id key-2025-prod \
--algorithm SHA256-ED25519
# Via API
curl -X POST https://api.stellaops.local/v1/signer/keys \
-H "Authorization: Bearer $TOKEN" \
-d '{"profile": "default", "keyId": "key-2025-prod", "algorithm": "SHA256-ED25519"}'
```
### Step 2: Add Key to Trust Anchor
Add the new key to the trust anchor without removing the old key:
```bash
# Using CLI
stellaops anchor add-key \
--anchor-id 550e8400-e29b-41d4-a716-446655440000 \
--key-id key-2025-prod
# Via API
curl -X POST https://api.stellaops.local/v1/anchors/550e8400.../keys \
-H "Authorization: Bearer $TOKEN" \
-d '{"keyid": "key-2025-prod", "publicKey": "<pem-encoded>"}'
```
**Result:** Trust anchor now accepts signatures from both old and new keys.
### Step 3: Transition Period
During transition:
- New signatures are created with the new key
- Old proofs are verified with either key
- Monitor for verification failures
**Recommended transition period:** 2-4 weeks
```bash
# Check verification status
stellaops anchor status --anchor-id 550e8400...
# Expected output:
# Anchor: 550e8400-e29b-41d4-a716-446655440000
# Active Keys: key-2024-prod, key-2025-prod
# Verification Success Rate: 100%
# Pending Rescans: 0
```
### Step 4: Revoke Old Key (Optional)
After transition is complete, revoke the old key:
```bash
# Using CLI
stellaops anchor revoke-key \
--anchor-id 550e8400... \
--key-id key-2024-prod \
--reason "annual-rotation" \
--effective-at "2025-02-01T00:00:00Z"
# Via API
curl -X POST https://api.stellaops.local/v1/anchors/550e8400.../keys/key-2024-prod/revoke \
-H "Authorization: Bearer $TOKEN" \
-d '{"reason": "annual-rotation", "effectiveAt": "2025-02-01T00:00:00Z"}'
```
**Important:** The old key remains valid for verifying proofs signed before the revocation date.
### Step 5: Publish Key Material
Publish updated key material:
```bash
# Update attestation feed
stellaops feed publish --include-keys
# Sync to Rekor mirror (if applicable)
stellaops rekor sync --keys-only
```
---
## Trust Anchor Management
### Trust Anchor Structure
```json
{
"trustAnchorId": "550e8400-e29b-41d4-a716-446655440000",
"purlPattern": "pkg:npm/*",
"allowedKeyids": ["key-2024-prod", "key-2025-prod"],
"allowedPredicateTypes": [
"evidence.stella/v1",
"reasoning.stella/v1",
"cdx-vex.stella/v1",
"proofspine.stella/v1"
],
"policyVersion": "v2.3.1",
"revokedKeys": ["key-2023-prod"],
"keyHistory": [
{
"keyid": "key-2023-prod",
"addedAt": "2023-01-15T00:00:00Z",
"revokedAt": "2024-01-15T00:00:00Z",
"revokeReason": "annual-rotation"
}
]
}
```
### Create Trust Anchor
```bash
stellaops anchor create \
--purl-pattern "pkg:npm/*" \
--key-ids key-2025-prod \
--predicate-types evidence.stella/v1,reasoning.stella/v1
```
### List Trust Anchors
```bash
stellaops anchor list
# Output:
# ID Pattern Keys Status
# 550e8400-e29b-41d4-a716-446655440000 pkg:npm/* key-2025-prod active
# 660f9500-f39c-51e5-b827-557766551111 pkg:maven/* key-2025-java active
```
### PURL Pattern Matching
Trust anchors use PURL patterns for scope:
| Pattern | Matches |
|---------|---------|
| `pkg:npm/*` | All npm packages |
| `pkg:maven/org.apache.*` | Apache Maven packages |
| `pkg:docker/myregistry/*` | All images from myregistry |
| `*` | Universal (all packages) |
---
## Verification with Key History
When verifying a proof signed at time T:
1. Lookup trust anchor for the artifact PURL
2. Find keys that were valid at time T:
- Key was added before T
- Key was not revoked, OR revoked after T
3. Verify signature against valid keys
4. Return success if any valid key verifies
### Temporal Verification
```bash
# Verify proof at specific point in time
stellaops verify \
--proof-bundle sha256:abc123... \
--at-time "2024-06-15T12:00:00Z"
# Check key validity at time
stellaops key check-validity \
--key-id key-2024-prod \
--at-time "2024-06-15T12:00:00Z"
```
---
## Emergency Key Revocation
In case of key compromise:
### Immediate Actions
1. **Revoke the compromised key immediately**
```bash
stellaops anchor revoke-key \
--anchor-id ALL \
--key-id compromised-key-id \
--reason "compromise" \
--effective-at "NOW"
```
2. **Generate new key**
```bash
stellaops key generate \
--profile default \
--key-id emergency-key-$(date +%Y%m%d)
```
3. **Add new key to all affected anchors**
```bash
stellaops anchor add-key \
--anchor-id ALL \
--key-id emergency-key-$(date +%Y%m%d)
```
4. **Publish updated key material**
```bash
stellaops feed publish --include-keys --urgent
```
### Post-Incident Actions
1. Review all proofs signed with compromised key
2. Determine if any tampering occurred
3. Re-sign critical proofs with new key if needed
4. File incident report
---
## Rotation Warnings
Configure rotation warnings to proactively manage key lifecycle:
```yaml
signer:
rotation:
warningMonths: 2
alerts:
- type: slack
channel: "#security-ops"
- type: email
recipients: ["security@example.com"]
```
### Check Rotation Warnings
```bash
stellaops key rotation-warnings
# Output:
# Key ID Profile Age Max Age Warning
# key-2024-prod default 10mo 12mo ⚠️ Rotation due in 2 months
# key-2024-java fips 6mo 12mo ✓ OK
```
---
## Audit Trail
All key operations are logged to `key_audit_log`:
| Field | Description |
|-------|-------------|
| `event_id` | Unique event identifier |
| `event_type` | `KEY_GENERATED`, `KEY_ADDED`, `KEY_REVOKED`, etc. |
| `key_id` | Affected key identifier |
| `anchor_id` | Affected trust anchor (if applicable) |
| `actor` | User/service that performed action |
| `timestamp` | UTC timestamp |
| `details` | JSON with additional context |
### Query Audit Log
```bash
stellaops audit query \
--type KEY_* \
--from "2025-01-01" \
--to "2025-12-31"
# Via SQL
SELECT * FROM signer.key_audit_log
WHERE event_type LIKE 'KEY_%'
AND timestamp >= '2025-01-01'
ORDER BY timestamp DESC;
```
---
## Database Schema
### key_history Table
```sql
CREATE TABLE signer.key_history (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
anchor_id UUID NOT NULL REFERENCES signer.trust_anchors(id),
key_id TEXT NOT NULL,
public_key TEXT NOT NULL,
algorithm TEXT NOT NULL,
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
revoked_at TIMESTAMPTZ,
revoke_reason TEXT,
metadata JSONB,
UNIQUE(anchor_id, key_id)
);
CREATE INDEX idx_key_history_validity
ON signer.key_history (anchor_id, added_at, revoked_at);
```
### key_audit_log Table
```sql
CREATE TABLE signer.key_audit_log (
event_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_type TEXT NOT NULL,
key_id TEXT,
anchor_id UUID,
actor TEXT NOT NULL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
details JSONB
);
CREATE INDEX idx_audit_log_time ON signer.key_audit_log (timestamp DESC);
CREATE INDEX idx_audit_log_key ON signer.key_audit_log (key_id);
```
---
## Metrics
Key rotation metrics exposed via Prometheus:
| Metric | Type | Description |
|--------|------|-------------|
| `signer_key_age_days` | Gauge | Age of each active key in days |
| `signer_keys_active_total` | Gauge | Number of active keys per profile |
| `signer_keys_revoked_total` | Counter | Total revoked keys |
| `signer_rotation_events_total` | Counter | Key rotation events |
| `signer_verification_key_lookups_total` | Counter | Temporal key lookups |
### Alerting Rules
```yaml
groups:
- name: key-rotation
rules:
- alert: SigningKeyNearExpiry
expr: signer_key_age_days > (365 - 60)
for: 1d
labels:
severity: warning
annotations:
summary: "Signing key approaching rotation deadline"
- alert: SigningKeyExpired
expr: signer_key_age_days > 365
for: 1h
labels:
severity: critical
annotations:
summary: "Signing key exceeded maximum age"
```
---
## Related Documentation
- [Proof Chain API](../api/proofs.md)
- [Attestor Architecture](../modules/attestor/architecture.md)
- [Signer Architecture](../modules/signer/architecture.md)
- [NIST SP 800-57](https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final) - Key Management Guidelines