Skip to content

Commit

Permalink
docs: add decision record about customizable JWSSigners (#4396)
Browse files Browse the repository at this point in the history
  • Loading branch information
paullatzelsperger authored Aug 7, 2024
1 parent ba42f13 commit eec3df0
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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<PrivateKey`, the `TokenGenerationService` will take a
plain String containing the private key ID.
- a new interface `JwsSignerProvider` is added in its own SPI module `jwt-signer-spi`:
```java
public interface JwsSignerProvider extends Function<String, JWSSigner> {
// 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<TokenRepresentation> 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);
};
}
```
1 change: 1 addition & 0 deletions docs/developer/decision-records/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/)

0 comments on commit eec3df0

Please sign in to comment.