Releases: oriolrius/pki-manager-web
Release list
v3.9.4 — Require ECDSA host keys for SSH
SSH host keys must now be ecdsa-sha2-nistp256 — a single key that serves as both
the certificate subject and the ECIES recipient for encrypted KRL distribution (an
ed25519 signing key cannot do ECDH key agreement, so it can never receive an
encrypted KRL). Host registration and the fleet sign-host path reject non-P256
keys with an actionable message, and the register form now guides you to
/etc/ssh/ssh_host_ecdsa_key.pub — so a host can no longer be registered in a
state where it silently can't receive its revocation list.
Fix
- ssh: require ecdsa-sha2-nistp256 host keys, fix register-form guidance
Full Changelog: v3.9.3...v3.9.4
v3.9.3 — SSH certificate UX & revocation modernisation
Adds a certificate details/delivery view on the SSH Users page, brings the host
deploy panel up to date (syntax-highlighted config blocks and signed ECIES
revocation in place of the obsolete unsigned-KRL cron), and fixes a theme bug
that made several boxes unreadable in light mode.
Feat
- ssh: cert details & delivery modal on the Users page — open any issued
certificate to see its full details and re-download the signed*-cert.pub
plus the ready-to-send delivery blocks. - ssh: modernise the host deploy panel — syntax-highlighted config/key
blocks, and revocation guidance pointing at the signed ECIESkrl-client
channel instead of cron-curling the unsigned per-CA KRL.
Fix
- frontend: bind Tailwind's
dark:variant to the theme class, so an
OS-dark user on the light theme no longer sees unreadable dark-mode text on
light backgrounds (and vice-versa). - frontend: order issued SSH certificates newest-first by serial.
Full Changelog: v3.9.2...v3.9.3
v3.9.2 — Resolve all 141 container-scan CVE alerts
🔒 Security — container-image CVE cleanup
Resolves all 141 open Trivy code-scanning alerts (backend 127 → 0, frontend 14 → 0). Every alert came from the Trivy scan of the published container images — there were no source/CodeQL findings. Both images were rebuilt and re-scanned locally with Trivy (0 vulnerabilities); this tag build re-scans them in CI.
Container images (docker/Dockerfile)
apk upgradein both final stages patches base-image OS CVEs (libexpat, c-ares).- The runtime backend stage is pure
node, so it no longer installs corepack/pnpm and removes the bundlednpm/npx— dropping the shipped pnpm cache (tar, minimatch, glob, ip-address, brace-expansion) and npm's sigstore/tar CVEs. Build pnpm bumped to10.34.5.
Dependencies
- Bumped vulnerable backend prod deps:
@fastify/swagger9.8,@fastify/swagger-ui6.1 (pulls patched@fastify/static/glob/minimatch),@trpc/server11.8,drizzle-orm0.45.2,fastify5.10,js-yaml4.2,node-forge1.4. pnpm.overridespin patched transitives shipped in the backend image (axios, dompurify, qs, ajv, fast-uri, yaml, uuid, lodash, seroval, immutable, form-data, follow-redirects, brace-expansion, shell-quote, minimatch).- Frontend
@trpc/*client bumped to 11.8 to match the server.
Code
external.routes.ts: typed thesetErrorHandlererrorparam asFastifyError(fastify 5.10 now infers it asunknown).
Verification
backend typecheck/build + 620 tests · frontend typecheck + 45 tests + build · pnpm install --frozen-lockfile · local Trivy scan of both freshly built images (0 vulnerabilities).
Merged via #6. Full changelog: v3.9.1...v3.9.2
v3.9.1 — Sharper project positioning: README, repo description & topics
Highlights
Documentation & project-metadata polish — no code or runtime changes.
Docs
- README tagline & Overview rewritten to surface the SSH certificate authority and the Kubernetes cert-manager external issuer alongside X.509, and to lead with "self-hosted."
- Fixed a long-standing wording bug: the Overview described a "Private Key Infrastructure" — PKI is Public Key Infrastructure.
Repository metadata (GitHub)
- Description rewritten to name the X.509 and SSH lifecycle, Cosmian KMS, the cert-manager external issuer, and CRL/KRL revocation.
- Topics curated to 20, adding the project's differentiators:
self-hosted,cosmian-kms,cert-manager,kubernetes,ssh-ca,ssh-certificates,crl,tls,mtls,code-signing,smime,oidc.
Full Changelog: v3.9.0...v3.9.1
Full Changelog: v3.9.0...v3.9.1
v3.9.0 — OpenAPI SSH/external schemas, root-route hygiene, edge proxy & test-suite health
Highlights
API / OpenAPI
- SSH & external routes now document request/response schemas (
/ssh/*,/external/*,/external/ssh/*). Generated clients (e.g.openapi-python-client) get typed request bodies instead of body-less stubs. (TASK-207) - The
/api/v1spec no longer advertises unreachable URLs — root-mounted public trust-material/KRL/CRL/CA-download routes and/trpc/{path}are hidden from the document. (TASK-208) - External issuer validation failures now return the standard
{error:{code,message}}shape.
Deployment
docker/nginx.confsingle-origin edge proxy routes the public/ssh/*and/krl/*trust-material paths to the backend while the SPA keeps its/ssh/*UI routes — fixes trust material being shadowed by the frontend on single-origin deployments. Documented inDEPLOYMENT.md. (TASK-209)
Fixes
generateCSRnow applies X.509 extensions (node-forgesetAttributes) — previously every CSR extension threw during ASN.1 serialization.
Testing
pnpm testauto-provisions a migrated, isolateddata/test.db— no manualdb:migrateneeded. Suite: 620 passed / 0 failed / 0 skipped (backend), 45 passed (frontend).
Full history: PR #5.
What's Changed
- fix(api): SSH/external OpenAPI schemas, root-route hiding, edge proxy + test-suite health by @oriolrius in #5
Full Changelog: v3.8.0...v3.9.0
v3.8.0 — SSH REST surface + module-driven Ansible (oriolrius.pki_manager)
SSH automation is now Ansible-native and REST-only. The ssh_host_cert role and every PKI Manager SSH operation moved to the oriolrius.pki_manager collection (2.3.0); this repo consumes it.
Backend
- New SSH REST endpoints so the collection drives the whole workflow over REST (no tRPC):
POST/GET /api/v1/ssh/tokens(+ revoke),GET /api/v1/ssh/hosts(lookup by?fqdn=),POST /api/v1/ssh/principals/grant. - Fleet-token
auth_principalshost-fetch endpoint (ANS-01).
Ansible — Integration milestone (ANS-00..ANS-11)
ssh_host_certgrown into a full SSH-CA node: host cert, User/Host-CA trust anchors, login-RBAC principals, authoritative sshd drop-in, unattended renewal, and a KRL revocation channel (public cron or encryptedkrl-client). Now published in the collection and consumed here viasite.yml+ YAML inventory +requirements.yml.- Dockerized containers-as-hosts e2e wired into CI (
ansible-e2e.yml): converge + idempotence (changed=0) + real ssh login (no TOFU) + principal RBAC + revocation on both KRL channels.
Docs
docs/ssh/deploy-server-and-user.md— module-driven, end-to-end operator guide.
Full changelog: v3.7.1...v3.8.0
v3.7.1 — Idle-session auth fix + KRL puller cleanup
Idle-session auth fix + puller cleanup
Monorepo version bump 3.7.0 → 3.7.1 (root/frontend/backend). Patch release.
Fixes
fix(auth)(TASK-193) — stop tRPC 401s after an idle session. In production the
app authenticates via the hand-rolled manual token flow, whose tokens live in
localStoragebut are not managed byoidc-client-ts— soautomaticSilentRenew
never renewed them. Once the short-lived access token expired, requests went out with no
Authorizationheader → backend401("Error loading hosts"), recoverable only by a full
page reload.token.tsnow transparently refreshes on demand using the stored
refresh_token(grant_type=refresh_token) when the token is expired or within a 60s
buffer, with single-flight dedup so batched/racing requests trigger at most one refresh.
Rotated tokens are persisted; a rejected refresh clears the stored token so the app falls
back to the login redirect (same recovery a reload gives).
Cleanup
chore(ssh)(TASK-194) — removed the obsoleteservices/krl-distributor/shell
puller. It was the first-generation host-side KRL puller (host_puller.sh+ systemd
unit/timer) that decrypted via the KMS-resident ECIES model (cosmian kms ec decrypt).
That model was retired by decision-015 / KRLC-02 in favour of local-key decryption, so
the shell puller could no longer decrypt what the backend produces. The Gokrl-client
is now the single supported puller; the Ansible README/role and the SSH host-blocks runbook
were updated to match.
Release artifacts (krl-client)
| Asset | Purpose |
|---|---|
krl-client-linux-amd64 |
static, CGO_ENABLED=0, -trimpath linux/amd64 binary |
checksums.txt |
SHA-256 checksum of the binary |
krl-client-linux-amd64.sig |
keyless cosign signature |
krl-client-linux-amd64.pem |
cosign certificate (Fulcio) |
krl-client-linux-amd64.spdx.json |
SPDX SBOM (syft) |
Full Changelog: v3.7.0...v3.7.1
v3.7.0 — SSH management UX polish, RBAC e2e coverage & krl-client observability
SSH management UX polish, RBAC e2e coverage & krl-client observability
Monorepo version bump 3.6.1 → 3.7.0 (root/frontend/backend). This release focuses
on the SSH manager UI, adds an end-to-end RBAC test suite, and fixes a krl-client
reporting bug — no breaking changes.
Highlights
Frontend / SSH UI
- Searchable
Combobox— a new in-menu-search select component, used for block-host
selection and other long option lists. - Live search filters on the SSH Hosts and Users lists.
- Redesigned identity "Access blocks" section for clarity, with clearer KRL
enforcement-state labels and tooltips. - Themed toasts & dialogs everywhere — native browser
alert()/confirm()pop-ups
are replaced with the app's themed toast/confirm components, and previously-silent
mutations now surface success/error toasts.
Fixes
fix(ssh)— block actions now record the acting identity (not the source IP)
and show the full timestamp.fix(krl-client)(TASK-192) — the singlerun_summaryevent now reports the
installed KRL header number onup_to_date(HTTP 304) and error runs instead of
0. A healthy steady-state 304 poll previously loggedkrl_number=0, indistinguishable
from an unprovisioned host and causing false "not installed" monitoring alerts.0now
means "nothing installed", full stop.
Testing & QA
- RBAC end-to-end suite (
tests/e2e-rbac.spec.ts, TASK-107/108): verifies admins can
create/issue/revoke/delete certificates and revoke/delete CAs, while regular users
receive 403 FORBIDDEN on every privileged operation. Admin destructive-op tests run
on throwaway objects they create, so they never touch real data. - Dedicated e2e ports — the local e2e stack moved to non-conflicting ports
(frontend 58080, backend 53000, Keycloak 58180) so it starts cleanly
alongside other local services. Full suite verified 23/23 passing against a
from-source stack.
CI / Security
- gitleaks secret-scanning workflow + allowlist config.
Docs
- README screenshots and surfaced Kubernetes issuer, CRL, REST/OpenAPI, and
SSH capabilities; new SSH principals guide with cross-links; companion-repo links.
Release artifacts (krl-client)
The tagged release attaches the standard krl-client supply-chain bundle:
| Asset | Purpose |
|---|---|
krl-client-linux-amd64 |
static, CGO_ENABLED=0, -trimpath linux/amd64 binary |
checksums.txt |
SHA-256 checksum of the binary |
krl-client-linux-amd64.sig |
keyless cosign signature |
krl-client-linux-amd64.pem |
cosign certificate (Fulcio) |
krl-client-linux-amd64.spdx.json |
SPDX SBOM (syft) |
Full Changelog: v3.6.1...v3.7.0
v3.6.1 — Re-seed the SSH KRL sequence allocator at startup
Re-seed the SSH KRL sequence allocator at startup
Monorepo version bump 3.6.0 → 3.6.1 (root/frontend/backend). Patch release.
Fixes
fix(backend)— re-seed thessh_krl_seqallocator row at startup, so the global
monotonic KRL numbering always has its sequence row present. This prevents per-host KRL
number allocation from failing on a database where the allocator row was missing.
Release artifacts (krl-client)
| Asset | Purpose |
|---|---|
krl-client-linux-amd64 |
static, CGO_ENABLED=0, -trimpath linux/amd64 binary |
checksums.txt |
SHA-256 checksum of the binary |
krl-client-linux-amd64.sig |
keyless cosign signature |
krl-client-linux-amd64.pem |
cosign certificate (Fulcio) |
krl-client-linux-amd64.spdx.json |
SPDX SBOM (syft) |
Full Changelog: v3.6.0...v3.6.1
v3.6.0 — Lift a per-host user block from the Users page
Lift a per-host user block from the Users page
Monorepo version bump 3.5.1 → 3.6.0 (root/frontend/backend).
Highlights
feat(frontend)— a per-host user block can now be lifted directly from the Users
page, closing the loop on the per-host access-blocks workflow introduced in 3.5.0 (you
no longer have to go to the host to unblock an identity).
Release artifacts (krl-client)
| Asset | Purpose |
|---|---|
krl-client-linux-amd64 |
static, CGO_ENABLED=0, -trimpath linux/amd64 binary |
checksums.txt |
SHA-256 checksum of the binary |
krl-client-linux-amd64.sig |
keyless cosign signature |
krl-client-linux-amd64.pem |
cosign certificate (Fulcio) |
krl-client-linux-amd64.spdx.json |
SPDX SBOM (syft) |
Full Changelog: v3.5.1...v3.6.0