From dd8a0bc2b88fd2b3f19506cffe3102ea2e768591 Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger Date: Tue, 26 May 2026 18:05:34 +0200 Subject: [PATCH 1/3] docs: add Vault Transit Engine integration guide for Identity Hub Documents how to configure Identity Hub to delegate signing operations to HashiCorp Vault's Transit secrets engine, including setup, key lifecycle management, and API usage. Co-Authored-By: Claude Sonnet 4.6 --- .../for-adopters/identity-hub/_index.md | 6 + .../identity-hub/vault-transit.md | 224 ++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 content/en/documentation/for-adopters/identity-hub/vault-transit.md diff --git a/content/en/documentation/for-adopters/identity-hub/_index.md b/content/en/documentation/for-adopters/identity-hub/_index.md index f0f3acc..8b16b72 100644 --- a/content/en/documentation/for-adopters/identity-hub/_index.md +++ b/content/en/documentation/for-adopters/identity-hub/_index.md @@ -174,6 +174,12 @@ For example, let's assume private key A is used to sign Credential CA and public If a private key is compromised, it must be immediately revoked. Revocation involves removing the verification method entry in the DID document and publishing the updated version. This will invalidate all resources signed with the revoked key pair. +#### Using Vault's Transit Engine for signing + +Instead of loading private key material into application memory IdentityHub can delegate sensitive signing operations to Vault's Transit engine. In this setup, Identity Hub generates key pairs in Vault and never has access to the private key material. When a signing operation is required, Identity Hub sends the data to be signed along with the key reference to Vault, which performs the signing and returns the signature. This approach enhances security by eliminating the risk of private key exposure in application memory. + +Find details on how to configure Identity Hub to use Vault's Transit engine in the [Vault Transit documentation](./vault-transit.md). + ### Verifiable Credentials > Support for storing verifiable credentials using the DCP issuance flow is currently in development. In the meantime, adopters must develop custom extensions for storing verifiable credential resources or create them through the Identity API. diff --git a/content/en/documentation/for-adopters/identity-hub/vault-transit.md b/content/en/documentation/for-adopters/identity-hub/vault-transit.md new file mode 100644 index 0000000..f22a6ea --- /dev/null +++ b/content/en/documentation/for-adopters/identity-hub/vault-transit.md @@ -0,0 +1,224 @@ +--- +title: Key Management with HashiCorp Vault Transit Engine +description: > + Explains how to use the HashiCorp Vault Transit secrets engine with Identity Hub to delegate + cryptographic key management and signing operations to Vault. +weight: 10 +--- + + + +- [Overview](#overview) +- [Why Use the Transit Engine?](#why-use-the-transit-engine) +- [How It Works](#how-it-works) + - [Key Generation](#key-generation) + - [Signing Flow](#signing-flow) + - [Key Rotation](#key-rotation) + - [Key Revocation](#key-revocation) +- [Adding the Extension](#adding-the-extension) +- [Vault Setup and Bootstrap](#vault-setup-and-bootstrap) + - [Enabling the Transit Engine](#enabling-the-transit-engine) + - [Vault Policies](#vault-policies) + - [Key Naming Convention](#key-naming-convention) +- [Configuration](#configuration) +- [Creating Key Pairs via the Identity API](#creating-key-pairs-via-the-identity-api) +- [Constraints and Limitations](#constraints-and-limitations) +- [Reference Implementation](#reference-implementation) + + +## Overview + +By default, Identity Hub generates key pairs and stores the private key material in the EDC Vault as a KV secret. While +this is sufficient for development and testing, it means the raw private key bytes must travel in and out of Vault and +are transiently held in process memory. + +The **HashiCorp Vault Transit engine integration** changes this model fundamentally. Instead of storing and using key +material itself, Identity Hub delegates all key generation, storage, and signing operations to Vault's +[Transit secrets engine](https://developer.hashicorp.com/vault/docs/secrets/transit). Private keys are generated +inside Vault, never leave it, and all signing is performed by a remote call to the Vault API. + +## Why Use the Transit Engine? + +| Default (KV) Key Storage | Transit Engine | +| ---------------------------------------------------- | ----------------------------------------- | +| Private key bytes stored as a KV secret | Private key never leaves Vault | +| Key material loaded into memory during signing | Signing is a remote API call to Vault | +| Key rotation requires manual deletion and recreation | Vault natively versions and rotates keys | +| Revocation requires deleting the KV secret | Old key versions are trimmed within Vault | + +The Transit engine is the preferred approach for production deployments because it offers stronger security guarantees +and offloads the operational complexity of key material handling and key lifecycle management to a dedicated secrets management system. + +## How It Works + +### Key Generation + +When a key pair is added to a participant context via the Identity API, the Transit extension calls Vault's +`POST /v1/transit/keys/` API to generate the key inside Vault. The key is marked as **non-exportable**, +meaning the private key bytes can never be retrieved from Vault. Vault returns the public key, which Identity Hub +stores in the `KeyPairResource` record in its database so that it is available locally for DID document assembly +and verification without additional Vault calls. + +The key name is derived from the participant context ID and the key alias, following the convention `participant__` (see below). This allows multiple participants to safely use the same Vault instance without key name collisions. + +NB: the `privateKeyAlias` must only contain alphanumeric characters, dashes, or underscores. + +Supported key types are: `ed25519` (default), `ecdsa-p256`, `ecdsa-p384`, `ecdsa-p521`, `rsa-2048`, `rsa-3072`, +`rsa-4096`. + +> Note: Importing externally generated key material is not supported when using the Transit extension. Any +> `KeyDescriptor` that contains `publicKeyJwk` or `publicKeyPem` will be rejected with a `400 Bad Request` error. +> Keys must always be generated by Vault. + +### Signing Flow + +When Identity Hub needs to sign a JWT — for example, when generating a Verifiable Presentation — the process is: + +1. The `JwsSignerProvider` (provided by this extension) creates a `TransitSigner` for the given key name. +2. `TransitSigner.sign()` base64-encodes the signing input (`BASE64URL(header).BASE64URL(payload)`) and sends it to + Vault's `POST /v1/transit/sign/` endpoint. +3. Vault returns a signature prefixed with `vault:v:`. The extension strips this prefix, decodes the raw + bytes, and returns the `Base64URL`-encoded signature as required by the Nimbus JOSE library. + +This flow means private key bytes never pass through the Identity Hub process at any point during signing. + +No changes are necessary to the verification flow, because the public key material is still stored in the `KeyPairResource` and publicized in the DID document, so it can be used as before to verify signatures. + +### Key Rotation + +Calling the key rotation operation on a `KeyPairResource` triggers `POST /v1/transit/keys//rotate` in Vault. +Vault adds a new key version and begins using it for new signatures. Older key versions are **not immediately invalidated**, so existing signed resources (e.g., active Verifiable Presentations) can still be verified until they +expire. This matches the staged rotation behaviour described in the [Key Pair Resources](../_index.md#key-rotation) section of the main Identity Hub documentation. + +### Key Revocation + +Revoking a key pair performs a two-step operation against Vault: + +1. The key is rotated to a new version. +2. The `min_encryption_version`, `min_decryption_version`, and `min_available_version` fields are all set to the latest version, trimming all older key versions from Vault storage. + +This effectively invalidates all signatures produced by any previous version of the key, which is the desired behaviour when a key is considered compromised. + +## Adding the Extension + +Add the following runtime dependencies to your Identity Hub launcher: + +```kotlin +// build.gradle.kts +dependencies { + runtimeOnly("org.eclipse.edc:identity-hub-keypairs-transit:") // Transit key pair service + runtimeOnly("org.eclipse.edc:vault-hashicorp:") // HashiCorp Vault KV (required base) +} +``` + +If you use a `libs.versions.toml` catalog, the corresponding aliases are: + +```toml +[libraries] +edc-vault-transit = { module = "org.eclipse.edc:identity-hub-keypairs-transit", version.ref = "edc" } +edc-vault-hashicorp = { module = "org.eclipse.edc:vault-hashicorp", version.ref = "edc" } +``` + +The Transit extension registers two `ServiceExtension` implementations: + +- **`TransitSecurityExtension`** — provides `JwsSignerProvider` and the fundamental `TransitEngine` service. +- **`TransitKeyPairServiceExtension`** — provides the `KeyPairService` implementation that replaces the default key pair service, and listens for `ParticipantContextDeleted` events to clean up keys in Vault. + +Because `TransitKeyPairServiceExtension` replaces the default `KeyPairService`, the `KeyPairServiceImpl` is provided as `@Provider(isDefault=true)` so that the `TransitKeyPairService` takes precedence. + +## Vault Setup and Bootstrap + +### Enabling the Transit Engine + +The Transit secrets engine must be enabled in Vault before deploying Identity Hub: + +```sh +vault secrets enable transit +``` + +### Vault Policies + +Each Identity Hub instance (or its Kubernetes service account) requires a Vault policy that grants access to the Transit paths it will use. Because key names are prefixed with the participant context ID (see below), the policy can scope permissions tightly: + +```hcl +# Allow managing keys for participants belonging to this IdentityHub. Each participant only has access to # their own keys due to the participant_ prefix. +path "transit/keys/participant_*" { + capabilities = ["read", "create", "update", "delete", "list"] +} + +path "transit/sign/participant_*" { + capabilities = ["create", "update"] +} + +# add this if verifying signatures via Vault as well, otherwise verification can be done locally with the # public key +path "transit/verify/participant_*" { + capabilities = ["create", "update"] +} +``` + +For Kubernetes-based deployments, Vault's Kubernetes auth method can be used to bind this policy to the service account running Identity Hub. The [JAD reference project](#reference-implementation) demonstrates this setup in +detail. + +### Key Naming Convention + +Transit key names follow the pattern: + +``` +participant__ +``` + +For example, a participant context with ID `alice` and a key alias of `signing-key1` results in the Vault key name +`participant_alice_signing-key1`. + +This prefix-based convention makes it straightforward to write narrow Vault policies and to identify keys by their owning participant context. + +Note that the `privateKeyAlias` must only contain alphanumeric characters, dashes, or underscores to ensure valid Vault key names. + +## Configuration + +The Transit extension uses the same configuration properties as the base HashiCorp Vault integration. No additional +properties are required. + +| Property | Description | Example | +| --------------------------- | ----------------------------------- | ------------------------- | +| `edc.vault.hashicorp.url` | URL of the HashiCorp Vault instance | `http://vault:8200` | +| `edc.vault.hashicorp.token` | Vault token for authentication | set via secret or env var | + +For production deployments, Vault authentication should use a method with short-lived, automatically rotated credentials (e.g., Kubernetes auth, JWT auth or AppRole) rather than a static token. + +## Creating Key Pairs via the Identity API + +When using the Transit extension, key generation happens entirely inside Vault. The `type` of key to generate is +passed through the `keyGeneratorParams` map in the `KeyDescriptor`: + +```json +{ + "keyId": "my-signing-key", + "active": true, + "keyGeneratorParams": { + "type": "ed25519" + } +} +``` + +Omitting `type` defaults to `ed25519`. Accepted values are: `ed25519`, `ecdsa-p256`, `ecdsa-p384`, `ecdsa-p521`, `rsa-2048`, `rsa-3072`, `rsa-4096`. + +As noted above, including `publicKeyJwk` or `publicKeyPem` in the descriptor will result in an error — key material can only originate from Vault. + +## Constraints and Limitations + +- **No key import:** external keys cannot be imported. Key material must always be generated by Vault. This is a conscious limitation of IdentityHub rather than the Transit engine. +- **Activate is a no-op on Vault:** activating a `KeyPairResource` via the Identity API updates the resource state in the database but does not change anything in Vault. Vault has no concept of "inactive" keys — the state is managed entirely by Identity Hub. +- **Non-exportable keys:** keys are created with `exportable: false`. Private key bytes can never be retrieved from Vault, even by an operator. +- **Vault availability is required for signing:** because signing is delegated to Vault, Identity Hub cannot generate Verifiable Presentations or sign any JWTs if Vault is unavailable. Plan Vault HA accordingly. **A service disruption of Vault will effectively cut off the participant from the dataspace!** + +## Reference Implementation + +The [JAD project](https://github.com/eclipse-dataspace-hub/jad) is a community reference +implementation that demonstrates how to use Identity Hub with the Transit engine in a full Kubernetes-based dataspace setup. It includes: + +- A Gradle launcher wiring the Transit extension into the Identity Hub runtime. +- Vault bootstrap `Job` manifests that enable Transit, configure Kubernetes auth, and create per-participant policies. +- Facilities to authenticate to Vault using the JWT auth method + +Reviewing the JAD project is highly recommended before deploying the Transit integration in production. From 209c6a83ad258bad15c5702cf020b0e36c045776 Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger Date: Wed, 27 May 2026 09:07:45 +0200 Subject: [PATCH 2/3] move transit docu into IH repo --- .../for-adopters/identity-hub/_index.md | 2 +- .../identity-hub/vault-transit.md | 224 ------------------ 2 files changed, 1 insertion(+), 225 deletions(-) delete mode 100644 content/en/documentation/for-adopters/identity-hub/vault-transit.md diff --git a/content/en/documentation/for-adopters/identity-hub/_index.md b/content/en/documentation/for-adopters/identity-hub/_index.md index 8b16b72..32c6e3f 100644 --- a/content/en/documentation/for-adopters/identity-hub/_index.md +++ b/content/en/documentation/for-adopters/identity-hub/_index.md @@ -178,7 +178,7 @@ If a private key is compromised, it must be immediately revoked. Revocation invo Instead of loading private key material into application memory IdentityHub can delegate sensitive signing operations to Vault's Transit engine. In this setup, Identity Hub generates key pairs in Vault and never has access to the private key material. When a signing operation is required, Identity Hub sends the data to be signed along with the key reference to Vault, which performs the signing and returns the signature. This approach enhances security by eliminating the risk of private key exposure in application memory. -Find details on how to configure Identity Hub to use Vault's Transit engine in the [Vault Transit documentation](./vault-transit.md). +Find details on how to configure Identity Hub to use Vault's Transit engine in the [Vault Transit documentation](). ### Verifiable Credentials diff --git a/content/en/documentation/for-adopters/identity-hub/vault-transit.md b/content/en/documentation/for-adopters/identity-hub/vault-transit.md deleted file mode 100644 index f22a6ea..0000000 --- a/content/en/documentation/for-adopters/identity-hub/vault-transit.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -title: Key Management with HashiCorp Vault Transit Engine -description: > - Explains how to use the HashiCorp Vault Transit secrets engine with Identity Hub to delegate - cryptographic key management and signing operations to Vault. -weight: 10 ---- - - - -- [Overview](#overview) -- [Why Use the Transit Engine?](#why-use-the-transit-engine) -- [How It Works](#how-it-works) - - [Key Generation](#key-generation) - - [Signing Flow](#signing-flow) - - [Key Rotation](#key-rotation) - - [Key Revocation](#key-revocation) -- [Adding the Extension](#adding-the-extension) -- [Vault Setup and Bootstrap](#vault-setup-and-bootstrap) - - [Enabling the Transit Engine](#enabling-the-transit-engine) - - [Vault Policies](#vault-policies) - - [Key Naming Convention](#key-naming-convention) -- [Configuration](#configuration) -- [Creating Key Pairs via the Identity API](#creating-key-pairs-via-the-identity-api) -- [Constraints and Limitations](#constraints-and-limitations) -- [Reference Implementation](#reference-implementation) - - -## Overview - -By default, Identity Hub generates key pairs and stores the private key material in the EDC Vault as a KV secret. While -this is sufficient for development and testing, it means the raw private key bytes must travel in and out of Vault and -are transiently held in process memory. - -The **HashiCorp Vault Transit engine integration** changes this model fundamentally. Instead of storing and using key -material itself, Identity Hub delegates all key generation, storage, and signing operations to Vault's -[Transit secrets engine](https://developer.hashicorp.com/vault/docs/secrets/transit). Private keys are generated -inside Vault, never leave it, and all signing is performed by a remote call to the Vault API. - -## Why Use the Transit Engine? - -| Default (KV) Key Storage | Transit Engine | -| ---------------------------------------------------- | ----------------------------------------- | -| Private key bytes stored as a KV secret | Private key never leaves Vault | -| Key material loaded into memory during signing | Signing is a remote API call to Vault | -| Key rotation requires manual deletion and recreation | Vault natively versions and rotates keys | -| Revocation requires deleting the KV secret | Old key versions are trimmed within Vault | - -The Transit engine is the preferred approach for production deployments because it offers stronger security guarantees -and offloads the operational complexity of key material handling and key lifecycle management to a dedicated secrets management system. - -## How It Works - -### Key Generation - -When a key pair is added to a participant context via the Identity API, the Transit extension calls Vault's -`POST /v1/transit/keys/` API to generate the key inside Vault. The key is marked as **non-exportable**, -meaning the private key bytes can never be retrieved from Vault. Vault returns the public key, which Identity Hub -stores in the `KeyPairResource` record in its database so that it is available locally for DID document assembly -and verification without additional Vault calls. - -The key name is derived from the participant context ID and the key alias, following the convention `participant__` (see below). This allows multiple participants to safely use the same Vault instance without key name collisions. - -NB: the `privateKeyAlias` must only contain alphanumeric characters, dashes, or underscores. - -Supported key types are: `ed25519` (default), `ecdsa-p256`, `ecdsa-p384`, `ecdsa-p521`, `rsa-2048`, `rsa-3072`, -`rsa-4096`. - -> Note: Importing externally generated key material is not supported when using the Transit extension. Any -> `KeyDescriptor` that contains `publicKeyJwk` or `publicKeyPem` will be rejected with a `400 Bad Request` error. -> Keys must always be generated by Vault. - -### Signing Flow - -When Identity Hub needs to sign a JWT — for example, when generating a Verifiable Presentation — the process is: - -1. The `JwsSignerProvider` (provided by this extension) creates a `TransitSigner` for the given key name. -2. `TransitSigner.sign()` base64-encodes the signing input (`BASE64URL(header).BASE64URL(payload)`) and sends it to - Vault's `POST /v1/transit/sign/` endpoint. -3. Vault returns a signature prefixed with `vault:v:`. The extension strips this prefix, decodes the raw - bytes, and returns the `Base64URL`-encoded signature as required by the Nimbus JOSE library. - -This flow means private key bytes never pass through the Identity Hub process at any point during signing. - -No changes are necessary to the verification flow, because the public key material is still stored in the `KeyPairResource` and publicized in the DID document, so it can be used as before to verify signatures. - -### Key Rotation - -Calling the key rotation operation on a `KeyPairResource` triggers `POST /v1/transit/keys//rotate` in Vault. -Vault adds a new key version and begins using it for new signatures. Older key versions are **not immediately invalidated**, so existing signed resources (e.g., active Verifiable Presentations) can still be verified until they -expire. This matches the staged rotation behaviour described in the [Key Pair Resources](../_index.md#key-rotation) section of the main Identity Hub documentation. - -### Key Revocation - -Revoking a key pair performs a two-step operation against Vault: - -1. The key is rotated to a new version. -2. The `min_encryption_version`, `min_decryption_version`, and `min_available_version` fields are all set to the latest version, trimming all older key versions from Vault storage. - -This effectively invalidates all signatures produced by any previous version of the key, which is the desired behaviour when a key is considered compromised. - -## Adding the Extension - -Add the following runtime dependencies to your Identity Hub launcher: - -```kotlin -// build.gradle.kts -dependencies { - runtimeOnly("org.eclipse.edc:identity-hub-keypairs-transit:") // Transit key pair service - runtimeOnly("org.eclipse.edc:vault-hashicorp:") // HashiCorp Vault KV (required base) -} -``` - -If you use a `libs.versions.toml` catalog, the corresponding aliases are: - -```toml -[libraries] -edc-vault-transit = { module = "org.eclipse.edc:identity-hub-keypairs-transit", version.ref = "edc" } -edc-vault-hashicorp = { module = "org.eclipse.edc:vault-hashicorp", version.ref = "edc" } -``` - -The Transit extension registers two `ServiceExtension` implementations: - -- **`TransitSecurityExtension`** — provides `JwsSignerProvider` and the fundamental `TransitEngine` service. -- **`TransitKeyPairServiceExtension`** — provides the `KeyPairService` implementation that replaces the default key pair service, and listens for `ParticipantContextDeleted` events to clean up keys in Vault. - -Because `TransitKeyPairServiceExtension` replaces the default `KeyPairService`, the `KeyPairServiceImpl` is provided as `@Provider(isDefault=true)` so that the `TransitKeyPairService` takes precedence. - -## Vault Setup and Bootstrap - -### Enabling the Transit Engine - -The Transit secrets engine must be enabled in Vault before deploying Identity Hub: - -```sh -vault secrets enable transit -``` - -### Vault Policies - -Each Identity Hub instance (or its Kubernetes service account) requires a Vault policy that grants access to the Transit paths it will use. Because key names are prefixed with the participant context ID (see below), the policy can scope permissions tightly: - -```hcl -# Allow managing keys for participants belonging to this IdentityHub. Each participant only has access to # their own keys due to the participant_ prefix. -path "transit/keys/participant_*" { - capabilities = ["read", "create", "update", "delete", "list"] -} - -path "transit/sign/participant_*" { - capabilities = ["create", "update"] -} - -# add this if verifying signatures via Vault as well, otherwise verification can be done locally with the # public key -path "transit/verify/participant_*" { - capabilities = ["create", "update"] -} -``` - -For Kubernetes-based deployments, Vault's Kubernetes auth method can be used to bind this policy to the service account running Identity Hub. The [JAD reference project](#reference-implementation) demonstrates this setup in -detail. - -### Key Naming Convention - -Transit key names follow the pattern: - -``` -participant__ -``` - -For example, a participant context with ID `alice` and a key alias of `signing-key1` results in the Vault key name -`participant_alice_signing-key1`. - -This prefix-based convention makes it straightforward to write narrow Vault policies and to identify keys by their owning participant context. - -Note that the `privateKeyAlias` must only contain alphanumeric characters, dashes, or underscores to ensure valid Vault key names. - -## Configuration - -The Transit extension uses the same configuration properties as the base HashiCorp Vault integration. No additional -properties are required. - -| Property | Description | Example | -| --------------------------- | ----------------------------------- | ------------------------- | -| `edc.vault.hashicorp.url` | URL of the HashiCorp Vault instance | `http://vault:8200` | -| `edc.vault.hashicorp.token` | Vault token for authentication | set via secret or env var | - -For production deployments, Vault authentication should use a method with short-lived, automatically rotated credentials (e.g., Kubernetes auth, JWT auth or AppRole) rather than a static token. - -## Creating Key Pairs via the Identity API - -When using the Transit extension, key generation happens entirely inside Vault. The `type` of key to generate is -passed through the `keyGeneratorParams` map in the `KeyDescriptor`: - -```json -{ - "keyId": "my-signing-key", - "active": true, - "keyGeneratorParams": { - "type": "ed25519" - } -} -``` - -Omitting `type` defaults to `ed25519`. Accepted values are: `ed25519`, `ecdsa-p256`, `ecdsa-p384`, `ecdsa-p521`, `rsa-2048`, `rsa-3072`, `rsa-4096`. - -As noted above, including `publicKeyJwk` or `publicKeyPem` in the descriptor will result in an error — key material can only originate from Vault. - -## Constraints and Limitations - -- **No key import:** external keys cannot be imported. Key material must always be generated by Vault. This is a conscious limitation of IdentityHub rather than the Transit engine. -- **Activate is a no-op on Vault:** activating a `KeyPairResource` via the Identity API updates the resource state in the database but does not change anything in Vault. Vault has no concept of "inactive" keys — the state is managed entirely by Identity Hub. -- **Non-exportable keys:** keys are created with `exportable: false`. Private key bytes can never be retrieved from Vault, even by an operator. -- **Vault availability is required for signing:** because signing is delegated to Vault, Identity Hub cannot generate Verifiable Presentations or sign any JWTs if Vault is unavailable. Plan Vault HA accordingly. **A service disruption of Vault will effectively cut off the participant from the dataspace!** - -## Reference Implementation - -The [JAD project](https://github.com/eclipse-dataspace-hub/jad) is a community reference -implementation that demonstrates how to use Identity Hub with the Transit engine in a full Kubernetes-based dataspace setup. It includes: - -- A Gradle launcher wiring the Transit extension into the Identity Hub runtime. -- Vault bootstrap `Job` manifests that enable Transit, configure Kubernetes auth, and create per-participant policies. -- Facilities to authenticate to Vault using the JWT auth method - -Reviewing the JAD project is highly recommended before deploying the Transit integration in production. From 2e49e2c252d26d38727d25f83cb2149184deda01 Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger Date: Wed, 27 May 2026 09:27:09 +0200 Subject: [PATCH 3/3] fix link --- content/en/documentation/for-adopters/identity-hub/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/documentation/for-adopters/identity-hub/_index.md b/content/en/documentation/for-adopters/identity-hub/_index.md index 32c6e3f..f663bde 100644 --- a/content/en/documentation/for-adopters/identity-hub/_index.md +++ b/content/en/documentation/for-adopters/identity-hub/_index.md @@ -178,7 +178,7 @@ If a private key is compromised, it must be immediately revoked. Revocation invo Instead of loading private key material into application memory IdentityHub can delegate sensitive signing operations to Vault's Transit engine. In this setup, Identity Hub generates key pairs in Vault and never has access to the private key material. When a signing operation is required, Identity Hub sends the data to be signed along with the key reference to Vault, which performs the signing and returns the signature. This approach enhances security by eliminating the risk of private key exposure in application memory. -Find details on how to configure Identity Hub to use Vault's Transit engine in the [Vault Transit documentation](). +Find details on how to configure Identity Hub to use Vault's Transit engine in the [Vault Transit documentation](https://github.com/eclipse-edc/IdentityHub/blob/main/docs/developer/architecture/vault-transit.md). ### Verifiable Credentials