Skip to content

feat(pki): add Device CA for IoT fleet mTLS device identity - #25

Merged
fcraviolatti merged 3 commits into
mainfrom
feat/device-ca-mtls
Aug 2, 2026
Merged

feat(pki): add Device CA for IoT fleet mTLS device identity#25
fcraviolatti merged 3 commits into
mainfrom
feat/device-ca-mtls

Conversation

@fcraviolatti

Copy link
Copy Markdown
Contributor

Summary

  • Vault PKI-backed Device CA — X.509 counterpart to the existing PAM SSH CA, kept as a fully separate implementation/Vault mount so the two CAs never share a blast radius.
  • Enrollment via a one-time, per-device bootstrap secret (not a fleet-wide shared credential) — a leaked secret only lets an attacker mint a certificate for the one device it was issued to.
  • Self-service certificate renewal over a dedicated mTLS listener, authenticated by the device's current certificate — no operator or bootstrap secret involved, runs unattended indefinitely.
  • Per-certificate revocation independent of CA rotation — a stolen device doesn't have to wait for natural expiry.
  • Staged CA rotation state machine mirroring the SSH CA's idle/rotating/cutover_ready/rollback dual-CA grace-period pattern.
  • New connector events (device.enrolled, device.cert.revoked) always carry device_id/tenant_id/serial.

Test plan

  • go build ./...
  • go vet ./...
  • go test ./... — full suite green
  • Apply migration 000182_device_pki against a live Postgres instance
  • Exercise enroll/renew/revoke against a real Vault PKI mount

Vault PKI-backed Device CA, the X.509 counterpart to the existing PAM
SSH CA (internal/sshca/) — a deliberately separate implementation and
Vault mount so the two CAs never share a blast radius.

- Per-device one-time bootstrap secret for first enrollment (not a
  fleet-wide shared credential): a leaked secret only mints a cert for
  the one device it was issued to.
- Self-service certificate renewal over a dedicated mTLS listener,
  authenticated by the device's current certificate — no operator or
  bootstrap secret involved, runs unattended indefinitely.
- Per-certificate revocation (device_certificates.status), independent
  of CA rotation — a stolen device doesn't have to wait for natural
  expiry.
- Staged CA rotation state machine mirroring the SSH CA's
  idle/rotating/cutover_ready/rollback dual-CA grace-period pattern.
- Revocation events dispatched via the connector with device_id/
  tenant_id/serial always populated from the start.
Comment thread internal/vaultpki/vaultpki.go Dismissed
Comment thread internal/vaultpki/vaultpki.go Dismissed
golangci-lint: defense -> defence (misspell), lowercase the
ErrNotConfigured message (staticcheck ST1005).
@fcraviolatti
fcraviolatti merged commit f532ed8 into main Aug 2, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants