Private
Public Access
1
0
Files
linux_patch_manager/tasks/issue-7-pr1-todo.md
Draco-Lunaris-Echo 5aec9e629c
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 (#26)
* 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>
2026-06-05 12:54:14 -05:00

85 lines
3.1 KiB
Markdown

# 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)