c3eb59ea04
WARDEN-WP-0026 T06: rotation guidance registry + warden rotate-guide
...
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
- routing model: RotationGuide (method rotate|re-establish, steps, owner,
automatable), RouteEntry.rotation + has_rotation + vends_secret.
- catalog parser: validate rotation block; secret-material screen gains a
prose-safe mode (high-entropy detector only) so authored steps aren't tripped
by substrings like "s."/"exists.".
- CLI: `warden rotate-guide <id>` (human + --json); route show --json now
carries has_rotation + rotation.
- scorecard: catalog_rotation_coverage — every active secret-vending lane must
carry a rotation block (SSH/login/pointer lanes exempt). Promotion checklist
criterion 9.
- data: rotation blocks for all 7 active vending lanes + the draft
railiance-backup lane (re-establish: age keypair regen + re-encrypt).
- fix pre-existing collision: bare `npm` keyword on forgejo-admin -> forgejo-npm
so "npm token" routes to the generic lane (restores test_access expectations).
- tests: rotation parse/coverage/prose-screen/CLI in tests/test_routing.py;
scorecard count 6 -> 7.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 14:40:30 +02:00
f3547acd0b
feat(warden): WARDEN-WP-0003 — test coverage, permissions, status --state-dir
...
- File permissions: os.chmod(cert, 0o600) after every sign in LocalCA and
VaultCA; chmod(privkey, 0o600) and chmod(pubkey, 0o644) after generate_keypair
- Scorecard: add check_file_permissions() that flags world/group-readable
cert and key files; run_scorecard now returns 6 checks
- warden status --state-dir: bypasses config loading entirely for operators
who have a cert but no warden.yaml installed
- tests/test_vault.py: 11 VaultCA unit tests covering success, HTTP 403,
RequestError, missing token, missing role, missing pubkey, TTL enforcement,
eviction, signatures log, and cert mode 600
- tests/test_ca.py: generate_keypair tests (paths, args, overwrite, error,
permissions) and cert mode 600 assertion after sign
- tests/test_scorecard.py: file_permissions check tests (pass, fail cert,
fail keys dir); scorecard count updated to 6
- tests/test_cli.py: covers sign, issue, status, scorecard, inventory, log,
cleanup commands using CliRunner and tmp config/inventory files
- tests/test_integration.py: @pytest.mark.integration tests against real
ssh-keygen; excluded from default suite via pyproject addopts
- pyproject.toml: addopts = "-m 'not integration'", integration marker declared
All 100 unit tests pass; 3 integration tests pass; ruff clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:38 +02:00
9857ed1424
feat(warden): implement WARDEN-WP-0002 correctness and operational completeness
...
T1 — TTL max enforcement:
- models.py: MAX_TTL_HOURS policy constant
- ca.py: _enforce_ttl() raises CAError when spec.ttl_hours > type max
- Called at top of LocalCA.sign() and VaultCA.sign()
- scorecard.py: check_ttl_policy() — flags certs with issued TTL > type max
- run_scorecard() now returns 5 checks
T2 — Stale cert cleanup:
- ca.py: _evict_cert() removes existing cert before writing new one (no accumulation)
- cli.py: warden cleanup [actor] [--dry-run] command
- check_no_stale_certs detail suggests 'warden cleanup' when stale certs found
T3 — Outgoing signatures log:
- ca.py: _append_signature_log() writes JSONL to state_dir/signatures.log
- Called after every successful sign() in LocalCA and VaultCA
- cli.py: warden log [actor] [--last N] [--json] command
- parse_cert_metadata now also returns valid_from (needed for TTL policy check)
61 tests passing, ruff clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 15:53:10 +02:00
42ca370085
feat(bootstrap): WARDEN-WP-0001 initial implementation — 42 tests passing
...
- LocalCA: ssh-keygen -s signing, keypair generation, cert parsing via ssh-keygen -L
- VaultCA: Vault SSH engine backend via httpx
- Inventory: YAML actor registry with ActorType, principals, TTL policy
- Scorecard: four cert-side compliance checks (prefixes, principals, no expired/stale)
- CLI: sign (cert_command interface), issue, status, scorecard, inventory subcommands
- ops-ssh-wrapper: acquire cert and exec SSH command
- Fix: principal parser stops at section headers containing ':' (Critical Options, Extensions)
- Move WARDEN-WP-0001 workplan from ops-bridge; register repo in state-hub (74df727e)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 13:27:49 +02:00