feat(pki): add CRL generation, distribution endpoint, and enrollment bundle extension (#26)
All checks were successful
CI Pipeline / Rust Format Check (push) Successful in 6s
CI Pipeline / Clippy Lints (push) Successful in 52s
CI Pipeline / Rust Unit Tests (push) Successful in 1m10s
CI Pipeline / Security Audit (push) Successful in 1m26s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 15s
CI Pipeline / Build .deb & Release (push) Has been skipped
All checks were successful
CI Pipeline / Rust Format Check (push) Successful in 6s
CI Pipeline / Clippy Lints (push) Successful in 52s
CI Pipeline / Rust Unit Tests (push) Successful in 1m10s
CI Pipeline / Security Audit (push) Successful in 1m26s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 15s
CI Pipeline / Build .deb & Release (push) Has been skipped
* feat(pki): add CRL generation, distribution endpoint, and enrollment bundle extension Implements manager-side CRL infrastructure for issue #7: - Add CertAuthority::generate_crl() using rcgen 0.13 - Add GET /api/v1/pki/crl.pem public endpoint - Extend PkiBundle with ca_chain and crl_pem fields - Update enrollment route to include CRL in bundle - Mount pki route as public endpoint - Add proptest dev-dependency * style: fix cargo fmt in enrollment.rs --------- Co-authored-by: Draco Lunaris <331325+Draco-Lunaris@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
80ffb6b62f
commit
5aec9e629c
84
tasks/issue-7-pr1-todo.md
Normal file
84
tasks/issue-7-pr1-todo.md
Normal file
@ -0,0 +1,84 @@
|
||||
# PR 1: Manager-side CRL generation + endpoint + enrollment bundle
|
||||
|
||||
**Branch:** `feat/7-crl-manager-side`
|
||||
**Target issue:** https://github.com/Draco-Lunaris/Linux-Patch-Manager/issues/7
|
||||
|
||||
## Pre-implementation
|
||||
|
||||
- [x] Read existing `pm-ca/src/ca.rs` to understand CA structure
|
||||
- [x] Confirm rcgen 0.13 is the chosen library
|
||||
- [x] Confirm sub-CA handling: extend `PkiBundle` with `ca_chain` field
|
||||
- [x] Read design doc decisions table (concerns 1-12)
|
||||
|
||||
## Code changes
|
||||
|
||||
- [ ] **pm-ca/src/ca.rs**: Add `generate_crl(db: &PgPool) -> Result<String>` function
|
||||
- Query `certificates` for `status='revoked' AND not_after > NOW()`
|
||||
- Build CRL using rcgen 0.13 `CertificateRevocationList`
|
||||
- Sign with CA private key
|
||||
- Return PEM-encoded CRL
|
||||
|
||||
- [ ] **pm-core/src/models.rs**: Extend `PkiBundle` with `ca_chain: String` field
|
||||
- Concatenated PEM bundle of full chain (intermediate + root) for sub-CA mode
|
||||
- For root mode, contains just the root cert (same as ca_crt)
|
||||
|
||||
- [ ] **pm-web/src/routes/pki.rs** (NEW): `GET /api/v1/pki/crl.pem` route
|
||||
- Public endpoint (no auth, CRLs are self-authenticating)
|
||||
- `Cache-Control: max-age=3600`
|
||||
- Returns latest cached CRL (regenerated on schedule or on revoke)
|
||||
|
||||
- [ ] **pm-web/src/routes/enrollment.rs**: Include CRL in enrollment response
|
||||
- Fetch current CRL via `generate_crl()`
|
||||
- Add `crl_pem: String` to response
|
||||
|
||||
- [ ] **pm-web/src/main.rs**: Wire up background CRL regeneration task
|
||||
- Regenerate every 12 hours
|
||||
- Hook into `revoke_cert` to trigger immediate regeneration
|
||||
- Store latest CRL in shared state (ArcSwap or similar)
|
||||
|
||||
- [ ] **crates/pm-web/src/state.rs** (or similar): Shared state for cached CRL
|
||||
|
||||
## Tests
|
||||
|
||||
- [ ] **Unit tests** in `pm-ca/src/ca.rs`:
|
||||
- `generate_crl` produces valid X.509 CRL signed by test CA
|
||||
- Revoked serials appear in CRL
|
||||
- Non-revoked serials do not appear
|
||||
- Expired certs (not_after < now) are excluded
|
||||
- Empty table produces CRL with zero revoked entries
|
||||
|
||||
- [ ] **Property tests** (proptest):
|
||||
- Random revoked cert data: CRL is always parseable, signature always verifies
|
||||
- Single-byte mutations to CRL fail signature verification
|
||||
|
||||
- [ ] **Fuzz harness** (cargo-fuzz):
|
||||
- Target: `pm_ca::ca::generate_crl`
|
||||
- Target: `pm_ca::ca::parse_crl` (if we add parsing)
|
||||
|
||||
- [ ] **Integration tests** in `pm-web/tests/`:
|
||||
- `GET /pki/crl.pem` returns 200 + valid PEM + correct Cache-Control
|
||||
- Enrollment bundle includes CRL
|
||||
- Enrollment bundle includes `ca_chain` field
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ ] **docs/security/revocation.md** (NEW): Revocation policy and operational behavior
|
||||
- [ ] **docs/api/REST_API.md** (or equivalent): Document `GET /pki/crl.pem`
|
||||
- [ ] **Inline doc comments** on new public functions/structs
|
||||
- [ ] **CHANGELOG.md** entry for the release
|
||||
|
||||
## Pre-PR checklist
|
||||
|
||||
- [ ] `cargo build` clean
|
||||
- [ ] `cargo test` all pass
|
||||
- [ ] `cargo clippy --all-targets --all-features -- -D warnings` clean
|
||||
- [ ] `cargo fmt --check` clean
|
||||
- [ ] CI on GitHub passes
|
||||
|
||||
## Out of scope for PR 1 (deferred to later PRs)
|
||||
|
||||
- Agent-side consumption (PR 2, in linux-patch-api repo)
|
||||
- Health check schema additions (PR 3)
|
||||
- Agent health response field (PR 4)
|
||||
- Health aggregation logic (PR 5)
|
||||
- E2E test harness (PR 6)
|
||||
Reference in New Issue
Block a user