[5.28.0] - 2026-09-30
๐ Security
Extractable/NeverExtractablenot enforced on key export paths (GHSA-8mmx-f92q-2gq8):Get,Export, and PKCS#12 export now enforceExtractable/NeverExtractable, deny non-extractable keys withResultReason::Not_Extractable, require a non-empty password for sensitive PKCS#12 exports, and unconditionally latch server-managedNeverExtractableacross creation/import andReKey/ReKeyKeyPairrotations (#1198)- Reserved UID
*bypassable viaAtomicOperation::UpsertandCertifydestination overwrite (GHSA-pvw2-jxwc-95xq):Database::atomicnow screens bothCreateandUpsertagainst the reserved-UID guard,Certifyvalidates/authorizes destination UIDs, and all backends (SQLite, PostgreSQL, MySQL, Redis) atomically enforce ownership onUpsertwithout partial tag mutations (#1198) Sensitive/Extractableattribute stripping via read-onlyGetgrant (GHSA-c75c-3cmm-48h7):DeleteAttributenow rejects server-managed attributes (includingSensitiveandExtractable) under both the by-value and by-tag branches, and mutating these attributes requires explicit operation grants or ownership instead of a read-onlyGetgrant (#1198)- SPIRE PKI
sign-intermediateissues CA certificates to any Vault token (COSMIAN-2026-022, #1234):POST /v1/{pki_mount}/root/sign-intermediatenow requires the caller's KMS identity (spire:<AppRole name>) to hold thecertifygrant on the CA private key; CA keys are looked up only among keys owned bydefault_username, and CSRs requestingbasicConstraintsare rejected to preservepathlen:0(Upgrade action: runckms access-rights grant spire:<AppRole name> certify --object-uid <ca-private-key-uid>) - SPIRE transit key substitution via shared tags (COSMIAN-2026-023, #1234): transit key resolution (
sign,GET /keys/{name}, list, delete) now restricts lookups to keys owned by the caller, preventing key substitution via shared tags; creating an existing key name is idempotent - Any user can publish a key on the unauthenticated JWKS endpoint (COSMIAN-2026-024, #1234):
/.well-known/jwks.jsonnow publishes only keys owned bydefault_username, preventing unauthorized key injection via shared keys - JOSE tag endpoints allow tag changes with any grant (COSMIAN-2026-025, #1234):
POST/DELETE /v1/crypto/keys/{kid}/tagsnow enforceadd_attribute/delete_attributepermissions instead of general read access - PKCS#11 module buffer overflows in
C_GetAttributeValueandC_Encrypt(COSMIAN-2026-026, #1234): caller buffer length is verified before writing output to prevent buffer overflow; returnsCKR_BUFFER_TOO_SMALL;C_GenerateKeynow rejects a nullphKeywithCKR_ARGUMENTS_BAD - CRL/OCSP revocation status could be lost, stale or wrong (COSMIAN-2026-027, #1234):
Destroypreserves issuer link and revocation metadata so destroyed certificates remain reported as revoked (RFC 5280 ยง3.3); certificate serials are generated as random 159-bit integers instead of SHA-1(SPKI) to avoid serial collisions onReCertify; OCSP response cache is keyed by fullCertID, bounded, respectsnextUpdate, and skips cachingunknown; OCSP requires CA match for allCertIDs; automatic CRL regeneration runs on behalf of the CA owner; stored CRL is re-read from the DB every 60 s; wrapped CA keys are unwrapped for CRL/OCSP signing;Validate/ImportCRL cache enforces 5-minute freshness and does not hold locks during network I/O - SSRF check bypass via
kms_public_urlprefix match in CRL fetching (COSMIAN-2026-028, #1234): URL comparison in CRL fetching compares parsed scheme, host, port, and base path, rejecting URLs with embedded credentials to prevent SSRF bypass - Harden asymmetric
DeriveKeycurve validation to check the OpenSSL keyIdactually constructed from each referenced object's key material, closing an Ed25519/X25519 key-type confusion edge case (both curves share a 32-byte raw key length) (#1170) - Remove unmaintained/unsound transitive dependencies:
smol-toml1.6.1 โ 1.8.0 (CVE-2026-85730),axum-server0.7 โ 0.8 to drop unmaintainedrustls-pemfile(RUSTSEC-2025-0134, #1180),rustls0.23.43 โ 0.23.45, and upgradedkubeto remove unmaintained deps
๐ Features
Audit Logging & SIEM Export
- Add a tamper-evident, cryptographically-chained JSONL audit log of every KMIP operation (#934): each event carries an
id,prev_hash, androw_hash(SHA-256), fsync'd after every write; truncation/reordering/modification breaks the chain and is detected by the newckms audit verifycommand - Add per-
BatchItemaudit events with a shared UUID v4request_id(fan-out of batchRequestMessagecalls) for SIEM/log correlation - Add a
ckms audit verify --path <file|dir>CLI command: verifies eachrow_hashandprev_hashlink, validates every*.jsonlchain in a directory, and confirms sealedaudit:reanchorevidence files still exist and hash-match on disk - Add Common Event Format (CEF) serialization (
to_cef_line()) for direct ArcSight/Splunk/QRadar ingestion, with adevicePayloadId=<uuid>extension whenrequest_idis present - Add drop-detection: when the bounded audit channel is full, an
audit:evictionsentinel event is written into the chain so lost events are detectable byckms audit verify - Add configurable trusted-proxy CIDR validation for
X-Forwarded-For, preventing client IP spoofing in audit logs (--audit-trusted-proxy-cidrs) - Add configurable audit failure mode (
--audit-failure-mode continue|reject):rejectreturns HTTP 503 when an event cannot be queued - Add an always-start recovery model (#1126): startup no longer aborts on a corrupted audit tail โ torn writes are truncated and continued (with an
audit:torn-write-recoveredsentinel), tampered rows trigger seal-and-roll to a forensic<name>.<ts>.<hex>.corrupt.<ext>file plus a freshaudit:reanchorchain, the entire hash chain is verified on every boot, a best-effort cross-platform exclusive lock prevents two KMS instances corrupting a shared-volume log, and an unwritable path self-heals via periodic retry - Add optional
--audit-file-max-size-byteswrite-stop cap (no rotation/retention)
SPIFFE / Workload Identity (#1206)
- Add opt-in SPIFFE JWT-SVID workload authentication (
--jwt-svid-auth/KMS_JWT_SVID_AUTH/[idp_auth] jwt_svid_auth): a validated JWT without anemailclaim is accepted whensubstarts withspiffe://, becoming the KMS user/owner (audit methodJwtSvid); audience is required, and mTLS client-cert CN takes precedence over JWT-SVID - Add
ckms login spire --audience <aud> [--spiffe-id <id>] [--socket-path <path|uri>](SPIRE Agent Workload API) - Add
POST /ui/login_svidBFF endpoint andGET /ui/auth_methodadvertisingSPIFFE; thekms setupwizard now asks whether JWT/OIDC providers issue SPIFFE JWT-SVIDs
X25519 ECDH (#1170)
- Add non-FIPS X25519 key agreement to KMIP
DeriveKey, including repeated base-object identifiers for asymmetric two-key derivation (DeriveKey::new_single_base/new_asymmetric); shared secrets are stored as non-extractableSecretDatawith reciprocal derivation links - Add
ckms derive-key --x25519 --private-key-id <ID> --peer-public-key-id <ID>and a WASM exportderive_key_asymmetric_ttlv_requestfor the Web UI - Add an "X25519 ECDH" derivation method to the Derive Key Web UI page (private-key and peer-public-key selectors, fixed 256-bit
SecretDataoutput)
JOSE / REST Crypto API (#1033)
- Add ECDH-ES decrypt support to
/v1/crypto/decrypt(RFC 7518 ยง4.6):ECDH-ES,ECDH-ES+A128KW,ECDH-ES+A256KWwithA128GCM/A192GCM/A256GCMcontent encryption, over P-256/P-384/P-521 (FIPS) and X25519 (non-FIPS) - Add
/v1/crypto/keyskey creation forECDH-ES*algorithms (KeyAgreement usage), and publish X25519 static public keys via/.well-known/jwks.json(kty=OKP) - Add an
ecdh_key_agreementprimitive and RFC 7518 Appendix C / NIST SP 800-56A Concat KDF tocosmian_kms_crypto
Database TDE Integrations (#1162)
- Add SAP ASE (Adaptive Server Enterprise) TDE support via
cosmian_pkcs11, and IBM Db2 LUW TDE support via the native IBM GSKit KMIP client over mutual TLS
๐ Bug Fixes
Database
- Fix
kms.keys.active.countmetric never updating on PostgreSQL (JSONB?operator applied to aVARCHARcolumn); now castsobject::jsonband logs failures atwarn!level (#1203) - Enable Redis TLS (
rediss://) for the Redis-findex backend by enablingtls-native-tls/tokio-native-tls-comp(#1195, #1204) - Add a
(tag, id)index on all three SQL backends to turn tag-basedLocatelookups into index-only scans (#1224) - Add JSON-expression indexes for keyset resolution (
find_by_rotate_name), the auto-rotation scheduler, and ObjectType filters on PostgreSQL/SQLite, and makekms.keys.active.countfilter on theObjectTypeattribute instead of parsing every row's JSON (#1224) - Rewrite
Locate-by-tags as per-tagINNER JOINs withEXISTS-based read-access probes, pushingLIMIT/server cap and destroyed-object exclusion into the query so the DB stops after the requested page (#1224)
Permissions / Access Control
GET /access/obtainedand KMIPLocatenow include permissions granted to the wildcard user*, consistent with per-object permission checks (#1188)- Fix
RedisWithFindex::list_user_operations_grantedmispairing permission entries with objects byzip-ing two independently-orderedHashMaps instead of joining by object uid (#1188)
Cache
- Fix cross-node cache invalidation: the per-process object cache now performs bounded-revalidation checks against shared state so revoked/destroyed keys are not served stale from a peer node's cache (#1199)
JOSE
- Fix
/.well-known/jwks.jsonpublishing EC keys authorized forKeyAgreement(but notVerify) with a signatureuse/algclaim (ES256/ES384) instead ofuse=encwith noalg
โป๏ธ Refactor
crate/server: introduce the audit middleware/extension-injection architecture andAuditFileStoresingle-writer task, splitting the KMIP route module intoroutes/kmip/(handlers.rs,audit.rs)crate/access: addaudit::{event, hash, cef, file_hash}with canonical event hashing, CEF serialization, and file-tail hash helperscrate/server_database: rework the SQLLocatequery builder (locate_query.rs) and shared SQL/MySQL/SQLite query files for index-backed lookups and JSONB-aware predicatescrate/kmip: widenDeriveKeyidentifier fields toVec(KMIP 1.4unique_identifierand 2.1object_unique_identifier) for asymmetric derivationcrate/crypto: addconcat_kdf(RFC 7518 Appendix C) and a generic P-256/P-384/P-521ecdh_key_agreementprimitive
๐งช Testing
- Add SIEM integration suites:
mise test:audit(hash-chain integrity, required fields),mise test:cef(CEF v27 format + UDP/TCP syslog with RFC 6587 octet-counting),mise test:siem(Filebeat/Fluent Bit),mise test:monitoring(OTel Collector + VictoriaMetrics + Grafana), plus live-audit-fixture generation and OpenSearch/Splunk JSONL compat checks in CI (#1115, #1150, #1131) - Add SAP ASE (
test:ase) and IBM Db2 LUW (test:db2) Docker-based TDE integration suites (#1162) - Add X25519
DeriveKeyKMIP vectors, RFC 7518 Appendix C Concat KDF known-answer vectors, and an ECDH-ES test suite (round trips,kidlink-following, AAD binding, and negative key-confusion/FIPS-rejection cases) - Add SPIFFE JWT-SVID end-to-end suite (
spire-jwt-svid) minting an SVID against a live SPIRE server - Add
always-sensitiveand attribute-read-only security regression tests, plus wildcard-grant and shared-DB (KMS_TEST_DB=postgresql|mysql|redis-findex) test coverage โ the full external-DB nextest run now passes 2085/2085 (#1188) - Expand
mise testto run every task under.mise/tasks/test/, auto-skipping groups whose infra/credentials are unavailable, with a final PASS/SKIP/FAIL summary (#1188)
โ๏ธ Build
- Sign Windows installers with Azure Trusted Signing (#1101); embed Windows
VERSIONINFOresources inckms.exe,cosmian_kms.exe,cosmian_pkcs11.dll, andcosmian_cng.dll - Flatten the Windows build artifact for signing (#1229); set up pnpm 10 and Node 22 in the Windows packaging workflow (#1197)
- Bump UI dependencies (
brace-expansion,js-yaml,nanoid,moment,@vitest/mocker) (#1163, #1185, #1230, #1231) - Consolidate AWS XKS, Splunk, and OpenSearch audit-compat tests into
test_all.yml; pin Splunk/OpenSearch images and regenerate live audit fixtures instead of static samples
๐ Documentation
- Add audit-logging, CEF-export, and SIEM configuration references (
configuration/audit-logs.md,configuration/cef-export.md,configuration/siems.md) with Mermaid sequence diagrams, plus ADRs for the single-writer design, middleware extension injection, CEF export format, always-start recovery, and SPIFFE JWT-SVID authentication - Add SAP ASE and IBM Db2 LUW TDE integration guides with architecture walkthroughs, and update the README database integration table (#1162)
- Add SPIFFE guides for the CLI, Web UI gateway/BFF flow, and workload authentication, plus the X25519 โ HKDF โ
ChaCha20Poly1305sealing workflow - Reorganize observability docs (rename
otlp-metrics.mdโotlp-telemetry.md) and document the Windows signing-certificate trust model inkms_clients/installation.md