HashiCorp Vault Transit Secrets Engine

When using the HashiCorp Vault integration with the Enterprise Stack Key Management Service, the Enterprise Stack can leverage HashiCorp Vault's Transit Secrets Engine to hook into the "cryptography as a service" or "encryption as a service" features provided by HashiCorp Vault. With that, services like issuer or credential-status can sign credentials whilst keeping the secrets (signing keys) in an external secure environment.

HashiCorp Vault Setup

If you are new to HashiCorp Vault, make sure to check out the guides here. The rest of this document assumes you already know how Vault works and have a transit secrets engine setup and running.

Setting Up Authentication Method

Once you have the HashiCorp Server up and running and enabled the transit secrets engine mentioned above, we need to either enable AppRole Authentication or User/Pass Authentication to use HashiCorp Vault with the walt.id Enterprise Stack.

Setup Policy

Before enabling and configuring authentication methods, a policy must be created to define the permissions and actions that authenticated users or roles are allowed to perform.

Create The Policy File

echo 'path "transit/*" {
  capabilities = ["create", "update", "read", "delete", "list"]
}' > transit-policy.hcl

Check the Client Configuration

If you are configuring vault locally make sure that the client is configured to communicate via HTTP. This can be achieved by setting the VAULT_ADDR environment variable.

export VAULT_ADDR=https://127.0.0.1:8200

Upload the Policy

vault policy write transit-policy transit-policy.hcl
# Expected result:
# Success! Uploaded policy: transit-policy

Setup Auth Method

AppRole Auth
User/Pass Auth

To enable AppRole auth you have two options, the Web UI of HashiCorp Vault or the CLI:

Web UI
CLI
  1. Navigate to Access.
  2. Choose Authentication Methods.
  3. Click on Enable new method.
  4. Select Generic / AppRole.
  5. Click Enable method.

Please note: You might want to disable lockout: select the created approle method, press "Configure", scroll to "User lockout configuration" and select "Disable lockout for this mount".

Configure AppRole

Add a Role

vault write auth/approle/role/my-role token_type=batch
# Additional parameters can include:
# secret_id_ttl, token_num_uses, token_ttl, token_max_ttl, secret_id_num_uses

Show Role ID

vault read auth/approle/role/my-role/role-id
# Save the value of role_id for later use.

Issue a Secret ID

vault write -f auth/approle/role/my-role/secret-id
# Save the value of secret_id for later use.

Associate Policy with AppRole

vault write auth/approle/role/my-role token_policies="transit-policy"
# Expected result:
# Success! Data written to: auth/approle/role/my-role

If you already have a token policy with the AppRole:

vault write auth/approle/role/my-role token_policies="existing-policy,transit-policy"

KMS Service Setup in the Enterprise Stack

Setup Key Service

In the following section, we will setup a KMS service inside of a tenant. If you don't have a tenant yet, you can learn how to create one here.

When configuring the KMS service, you can set default access credentials for the Enterprise API to authenticate with HashiCorp Vault. This means that whenever you call the key generation endpoint without specifying any authentication credentials for HashiCorp Vault, the system will automatically use the default credentials you provided during setup.

Without Access Credentials
With Access Credentials
CURL

Endpoint: /v1/{target}/resource-api/services/create | API Reference

Example Request

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/resource-api/services/create' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "kms"
}'

Body

{
  "type": "kms"
}

Path Parameters

  • orgID: - When performing operations within an organization, it is essential to use the organization's Base URL or another valid host alias. For example, if your organization is named test, your default Base URL will be test.enterprise-sandbox.waltid.dev when using the sandbox environment.
  • target: resourceIdentifier - The target indicates the organization + tenant in which to create the new KMS service and the service's ID ({organizationID}.{tenantID}.[NewKmsServiceID]), e.g. waltid.tenant1.kms1

Body Parameters

  • type: serviceType - Specifies the type of service to create. In our case kms

Response Codes

  • 201 - Service created successfully.

Key Creation

Use backend: "tse" to create keys in the HashiCorp Vault Transit Secrets Engine. The Enterprise API accepts walt.id keyType values and maps them to the matching Vault Transit key type before calling Vault.

walt.id keyTypeVault Transit key type
Ed25519ed25519
secp256r1ecdsa-p256
secp384r1ecdsa-p384
secp521r1ecdsa-p521
RSArsa-2048
RSA3072rsa-3072
RSA4096rsa-4096

secp256k1 is not supported by the TSE integration. See the HashiCorp Vault Transit Secrets Engine key types full list for the provider-side names.

Without Default Access Credentials
With Default Access Credentials
CURL

Endpoint:/v1/{target}/kms-service-api/keys/generate | API Reference

Example Request

AppRole Auth
User/Pass Auth
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/kms-service-api/keys/generate' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "backend": "tse",
  "keyType": "Ed25519",
  "config": {
    "server": "http://127.0.0.1:8200/v1/transit",
    "auth": {
      "roleId": "6823b3c7-60f7-db0b-c663-7359f17c0c30",
      "secretId": "aba4f28b-524c-db63-bae2-67a0e094f46a"
    }
  }
}'

Body

{
  "backend": "tse",
  "keyType": "Ed25519",
  "config": {
    "server": "http://127.0.0.1:8200/v1/transit",
    "auth": {
      "roleId": "6823b3c7-60f7-db0b-c663-7359f17c0c30",
      "secretId": "aba4f28b-524c-db63-bae2-67a0e094f46a"
    }
  }
}

Path Parameters

  • orgID: - When performing operations within an organization, it is essential to use the organization's Base URL or another valid host alias. For example, if your organization is named test, your default Base URL will be test.enterprise-sandbox.waltid.dev when using the sandbox environment.
  • target: resourceIdentifier - The target indicates the organization + tenant + kmsService in which to create the new key and the key's ID ({organizationID}.{tenantID}.{kmsServiceID}.[newKeyID]), e.g. waltid.tenant1.kms1.key1

Body Parameters

  • backend: String - in our case tse indicating the key will be managed by HashiCorp Vault.
  • keyType: String - the algorithm used to generate the key. For Vault TSE, use one of Ed25519, secp256r1, secp384r1, secp521r1, RSA, RSA3072, or RSA4096.
  • config
    • server: URL - The endpoint of your Vault instance. Following the structure of https://<yourHost>/v1/<pathOfTransitEngine>, e.g. "https://vault.walt.id/v1/transit". By default the transit engine will live at /transit.
    • auth:
    • AppRole Auth:
      • roleId: String - The Role ID for AppRole authentication.
      • secretId: String - The Secret ID for AppRole authentication.
    • User/Pass Auth:
      • username: String - The username for user/pass authentication.
      • password: String - The password for user/pass authentication.
    • AccessToken Auth (Deprecated):
      • accessKey: String - The access token for token-based authentication.
    • namespace: String (optional) - The namespace within the Vault instance.

Response Codes

  • 201 - Key created successfully.
Last updated on July 3, 2026