Commit Graph

3 Commits

Author SHA1 Message Date
Jarvis
7524d6e919 fix(federation): address #494 review findings (FED-M2-04)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
H1: Replace HS256/HMAC signing with real JWK signing (ES256/RS256/ES384)
    via jose SignJWT. Algorithm derived from JWK kty/crv. Provisioner
    password dropped as signing input; kept only as optional env var for
    PBES2-decrypt path at startup.
H2: Clamp cert TTL to 900s (15 min) in both DTO validator and issueCert().
    Default changed to 300s (5 min). @Max reduced to 15*60.
H3: Real CSR validation via @peculiar/x509: parse PEM, verify self-
    signature, reject weak keys (RSA<2048, bad EC curves), reject MD5/SHA-1.
    New validateCsr() throws CaServiceError code INVALID_CSR on failure.
H4: Replace hardcoded \x24 DER length in federation.tpl with dynamic
    printf "%c" (len ...) encoding. Add UUID-shape validation for grantId
    and subjectUserId in buildOtt() with code INVALID_GRANT_ID.
H5: Load JWK into KeyObject once (lazy, cached). provisionerKeyJson raw
    string not stored as class field. provisionerPassword not stored.

M1: Set JWT sub to CSR CN (extracted via @peculiar/x509) instead of URL.
M2: Add jti: crypto.randomUUID() to OTT claims.
M3: Drop top-level sha claim; keep only step.sha.
M4: extractSerial() throws CaServiceError code CERT_PARSE instead of
    returning 'unknown' on failure.
M5: Set timeout: 5000 on https.RequestOptions + req.setTimeout(5000).
M6: OTT signature verified with jose.jwtVerify in tests. Added real P-256
    CSR test via @peculiar/x509 generator. Added provisionerPassword
    leak-check test.
M7: Constructor validates STEP_CA_URL must be https://.

Verification: typecheck ✓, 385 tests pass (16 new), lint ✓, format ✓.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 22:34:05 -05:00
Jarvis
9f5c28c0ce feat(federation): Step-CA client service for grant certs (FED-M2-04)
- Add CaService (@Injectable) that POSTs CSRs to step-ca /1.0/sign over
  HTTPS with a pinned CA root cert; builds HS256 OTT with custom claims
  mosaic_grant_id and mosaic_subject_user_id plus step.sha CSR fingerprint
- Add CaServiceError with cause + remediation for fail-loud contract
- Add IssueCertRequestDto and IssuedCertDto with class-validator decorators
- Add FederationModule exporting CaService; wire into AppModule
- Replace federation.tpl TODO placeholder with real step-ca Go template
  emitting OID 1.3.6.1.4.1.99999.1 (grantId) and .2 (subjectUserId) as
  DER UTF8String extensions (tag 0x0C, length 0x24, base64-encoded value)
- Update infra/step-ca/init.sh to patch mosaic-fed provisioner config with
  templateFile path via jq on first boot (idempotent)
- Append OID assignment registry and CA env var table to docs/federation/SETUP.md
- 11 unit tests pass: happy path, certChain fallbacks, HTTP 401/4xx, malformed
  CSR (no HTTP call), non-JSON response, connection error, JWT claim assertions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 22:34:05 -05:00
c56dda74aa feat(federation): Step-CA sidecar in federated compose [FED-M2-02] (#490)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline failed
2026-04-22 02:21:49 +00:00