diff --git a/docs/developer/decision-records/2024-08-05-custom-jwssigners/README.md b/docs/developer/decision-records/2024-08-05-custom-jwssigners/README.md new file mode 100644 index 00000000000..7943b1527dd --- /dev/null +++ b/docs/developer/decision-records/2024-08-05-custom-jwssigners/README.md @@ -0,0 +1,52 @@ +# Allowing custom `JWSSigner` implementations + +## Decision + +To allow custom `JWSSigner` implementations, the `TokenGenerationService` needs to be refactored, in particular the way +how `PrivateKey` objects are handled. + +## Rationale + +In the current EDC implementation, the private key is always resolved from the vault, and a `JWSSigner` implementation +is instantiated based on the algorithm of the key. + +Some High-Security Modules (HSMs) have a feature where the signing of content can be done with a remote call while +the private key material does not leave the HSM itself. + +To support this feature in EDC, the `TokenGenerationService` and its implementation, the `JwtGenerationService` must be +refactored to accommodate the custom `JWSSigner`. + +## Approach + +- refactor the `generate()` method: instead of taking a `Supplier { + // marker interface + } + ``` + Note that this will expose Nimbus classes in the SPI module! +- the `JwtGenerationService` takes in its constructor a `JwsSignerProvider`, which is then used upon token generation to + get a `JWSSigner` for a particular private key ID. + ```java + @Override + public Result generate(String privateKeyId, @NotNull TokenDecorator... decorators) { + var tokenSigner = jwsGeneratorFunction.apply(privateKeyId); + if (tokenSigner == null) { + return Result.failure("JWSSigner cannot be generated for private key '%s'".formatted(privateKeyId)); + } + //... + } + ``` +- The default implementation will simply resolve the private key from + the vault and create a `JWSSigner` for it: + ```java + @Provider(isDefault = true) + public JwsSignerProvider defaultSignerProvider() { + return privateKeyId -> { + var pk = privateKeyResolver.resolvePrivateKey(privateKeyId).orElseThrow(/*exception*/); + return CryptoConverter.createSignerFor(pk); + }; + } + ``` \ No newline at end of file diff --git a/docs/developer/decision-records/README.md b/docs/developer/decision-records/README.md index 30b04ade5fb..e576b183595 100644 --- a/docs/developer/decision-records/README.md +++ b/docs/developer/decision-records/README.md @@ -58,3 +58,4 @@ - [2024-05-24 Dataplane Selection Improvements](./2024-05-24-dataplane-selection-improvements/) - [2024-06-24 Api Authentication Configuration](./2024-06-24-api-authentication-configuration/) - [2024-07-03 Additional CatalogRequest scope parameter](./2024-07-03-additional-catalogrequest-param/) +- [2024-08-05 Custom JWSSigner Implementations](./2024-08-05-custom-jwssigners/)