---
title: "HashiCorp Vault Transit Secrets Engine"
description: "Leverage HashiCorp Vault's Transit Secrets Engine to secure keys of wallets managed by the wallet API."
stack: "Community Stack (open source) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/community-stack/wallet/key-management/hashicorp-vault
generated: 2026-07-08
---
# HashiCorp Vault Transit Secrets Engine

Leverage HashiCorp
Vault's [Transit Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/transit)
to secure keys of wallets managed by the wallet API.

If you are new to HashiCorp Vault, make sure to check out the
guides [here](https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-intro).
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 issuer API.

### 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**

```bash
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.

```bash
export VAULT_ADDR=https://127.0.0.1:8200
```

**Upload the Policy**
```bash
vault policy write transit-policy transit-policy.hcl
# Expected result:
# Success! Uploaded policy: transit-policy
```

### Setup Auth Method

**Option: AppRole Auth**

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

**Option: Web UI**

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"._

**Option: CLI**

In the CLI enter:

```bash
vault auth enable approle
```

_Please note: You might want to disable lockout: Use the `disable_lockout` parameter._

### Configure AppRole

**Add a Role**

```bash
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**
```bash
vault read auth/approle/role/my-role/role-id
# Save the value of role_id for later use.
```

**Issue a Secret ID**

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

**Associate Policy with AppRole**
```bash
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:
```bash
vault write auth/approle/role/my-role token_policies="existing-policy,transit-policy"
```

**Option: User/Pass Auth**

**Option: CLI**

**Enable Userpass**

```bash
vault auth enable userpass
# Alternatively with a custom path
vault auth enable -path=<path> userpass
# Expected result:
# Success! Enabled userpass auth method at: userpass/
```

**Add User**

```bash
vault write auth/<userpass:path>/users/myuser password=mypassword policies=mypolicy
# Creates user "myuser", password "mypassword", associated with "mypolicy".
# Example policy: transit-policy (see above).
```

## Key Creation

Below you find an example call to create a key in HashiCorp Vault and associate it with a wallet managed by the Wallet API.

The Wallet API accepts walt.id `keyType` values and maps them to the matching HashiCorp Vault Transit key type before creating or resolving the key.

| walt.id `keyType` | Vault Transit key type |
|---|---|
| `Ed25519` | `ed25519` |
| `secp256r1` | `ecdsa-p256` |
| `secp384r1` | `ecdsa-p384` |
| `secp521r1` | `ecdsa-p521` |
| `RSA` | `rsa-2048` |
| `RSA3072` | `rsa-3072` |
| `RSA4096` | `rsa-4096` |

`secp256k1` is not supported by the TSE integration. See the HashiCorp Vault Transit Secrets Engine key types [full list](https://developer.hashicorp.com/vault/docs/secrets/transit#key-types) for the provider-side names.

**Option: CURL**

**Endpoint:
** `/keys/generate` | [API Reference](https://wallet.demo.walt.id/swagger/index.html#/Keys/post_wallet_api_wallet__wallet__keys_generate)

**Example Request**

```bash
curl -X 'POST' \
  'https://wallet.demo.walt.id/wallet-api/wallet/f01f8f55-d098-4c53-b47b-c97552829b39/keys/generate' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "backend": "tse",
  "config": {
    "server": "https://2ab1-2001-871-25f-3c00-f8ac-11f4-dce2-9f1a.ngrok-free.app/v1/transit",
    "auth": {
      "roleId": "b50427bd-5070-0bec-3a00-dfe470ba349d",
      "secretId": "22ffc0f4-c308-e6d6-f5a4-246cd89bc17c"
    }
  },
  "keyType": "Ed25519"
}'
```

**Body**

```json
{
  "backend": "tse",
  "config": {
    "server": "https://2ab1-2001-871-25f-3c00-f8ac-11f4-dce2-9f1a.ngrok-free.app/v1/transit",
    "auth": {
      "roleId": "b50427bd-5070-0bec-3a00-dfe470ba349d",
      "secretId": "22ffc0f4-c308-e6d6-f5a4-246cd89bc17c"
    }
  },
  "keyType": "Ed25519"
}
```

**Body Parameters**

- `backend`: _String_ - The location where the key is stored. In our case `tse` as we want to store it HashiCorp Vault.
- `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.
- `keyType`: _String_ - the algorithm used to generate the key. For Vault TSE, use one of `Ed25519`, `secp256r1`, `secp384r1`, `secp521r1`, `RSA`, `RSA3072`, or `RSA4096`.

---

**Example Response**

The API will respond with the ID of the key. This ID is the internal reference and can be used in operations such as DID
create or key delete.

```
Kki22j4lUwo1gtDfdvdCgOE0hhKcNHgIZSzSxU0CugE
```
