fix: store the OIDC signing key as a JWK file instead of a keytool keystore #16

Merged
robinp2000 merged 1 commit from fix/oidc-jwk-file into main 2026-10-11 12:14:06 +02:00
Owner

What

  • The OIDC signing key is a JWK file (data/jwk.json, property dachshund_authorization.security.jwk.key-filename) instead of a PKCS12 keystore.
  • The key (RSA 2048, kid = thumbprint) is generated in the program on first start. No keytool process, no keystore password, no alias.
  • The key file is created owner-only (600) via a temporary file and an atomic move, data/ is set to 700, and the rights of an existing key file are tightened on every start.
  • An existing key file is never replaced or deleted. If it is unusable (not a JWK, empty, public part only, not RSA, shorter than 2048 bits), the start fails with a clear message.

Why

  • A wrong keystore password silently deleted the keystore and created a new one, which invalidated every issued token.
  • keytool was started as an external process: exit code ignored, password visible in the process list, and it may be missing in a native image or slim container.
  • The key was stored without restricted file permissions.

Tests

  • OidcJWTSigningKeyTest (13 tests): creation, reuse, never touching an existing file, rights of file and directory, no temporary file left behind, thumbprint as kid, and every kind of unusable key file fails and keeps the file.
  • Not covered by an automated test: signing and verifying a token with the key.

Notes

  • Breaking: a new key replaces the old keystore, so tokens issued before are invalid. The config keys keystore-filename, store-password and alias are no longer read. An old data/*.p12 can be deleted.
## What - The OIDC signing key is a JWK file (`data/jwk.json`, property `dachshund_authorization.security.jwk.key-filename`) instead of a PKCS12 keystore. - The key (RSA 2048, `kid` = thumbprint) is generated in the program on first start. No `keytool` process, no keystore password, no alias. - The key file is created owner-only (`600`) via a temporary file and an atomic move, `data/` is set to `700`, and the rights of an existing key file are tightened on every start. - An existing key file is never replaced or deleted. If it is unusable (not a JWK, empty, public part only, not RSA, shorter than 2048 bits), the start fails with a clear message. ## Why - A wrong keystore password silently deleted the keystore and created a new one, which invalidated every issued token. - `keytool` was started as an external process: exit code ignored, password visible in the process list, and it may be missing in a native image or slim container. - The key was stored without restricted file permissions. ## Tests - `OidcJWTSigningKeyTest` (13 tests): creation, reuse, never touching an existing file, rights of file and directory, no temporary file left behind, thumbprint as `kid`, and every kind of unusable key file fails and keeps the file. - Not covered by an automated test: signing and verifying a token with the key. ## Notes - Breaking: a new key replaces the old keystore, so tokens issued before are invalid. The config keys `keystore-filename`, `store-password` and `alias` are no longer read. An old `data/*.p12` can be deleted.
fix: store the OIDC signing key as a JWK file instead of a keytool keystore
All checks were successful
CI / build (pull_request) Successful in 2m3s
1cd193c591
robinp2000 deleted branch fix/oidc-jwk-file 2026-10-11 12:14:06 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
robinp2000/dachshund-auth-provider!16
No description provided.