Malcador — Vault-Backed Key Management Service (1.0.0)

Download OpenAPI specification:

Health

Health Check

View the current status of the Malcador key management service, including PKCS#11 module details and HSM token information.

Responses

Response samples

Content type
application/json
{
  • "status": "ok",
  • "pkcs11": {
    }
}

Tenants

Create Tenant

Create a new tenant. This provisions a dedicated HSM token for the tenant via SoftHSM2 (C_InitToken), initializes the user PIN, and persists the tenant record to the database.

The tenant's HSM token is isolated — each tenant gets its own token in the HSM, ensuring cryptographic isolation between tenants.

Authorizations:
API Key
Request Body schema: application/json
required
id
string <uuid>

Optional UUID for the tenant. If omitted, a random UUID is generated.

name
required
string

Human-readable name for the tenant. Must be unique.

token_label
required
string

Label for the HSM token. Must be unique per tenant.

user_pin
string [ 4 .. 255 ] characters

The user PIN for the tenant's HSM token. If omitted, a random PIN is generated. Must be 4-255 characters if provided (PKCS#11 HSM limit).

Responses

Request samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "production",
  • "token_label": "prod-tenant-01",
  • "user_pin": "my-secure-pin-123"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "token_label": "string",
  • "user_pin": "string",
  • "created_at": "2026-07-09 19:00:00"
}

List Tenants

Retrieve a list of all tenants in the system.

Authorizations:
API Key

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get Tenant

Retrieve a single tenant by its UUID.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "token_label": "string",
  • "user_pin": "string",
  • "created_at": "2026-07-09 19:00:00"
}

Update Tenant

Update a tenant's token label or user PIN. Only provided fields are updated.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

Request Body schema: application/json
required
token_label
string

New token label for the HSM token.

user_pin
string [ 4 .. 255 ] characters

New user PIN for the HSM token. Must be 4-255 characters if provided.

Responses

Request samples

Content type
application/json
{
  • "token_label": "prod-tenant-01-renamed",
  • "user_pin": "new-secure-pin-456"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "token_label": "string",
  • "user_pin": "string",
  • "created_at": "2026-07-09 19:00:00"
}

Delete Tenant

Delete a tenant. This destroys the tenant's HSM token and removes the database record. All cryptographic keys belonging to this tenant are permanently lost.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

Responses

Keys

Create Key

Generate a new encryption key inside the tenant's HSM token. The key material never leaves the HSM in plaintext.

Optionally pass a kid (UUID v4) to use a specific key identifier. If omitted, a random UUID is generated.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

Request Body schema: application/json
optional
kid
string <uuid>

Optional key identifier (UUID v4). If omitted, a random UUID is generated.

Responses

Request samples

Content type
application/json
{
  • "kid": "550e8400-e29b-41d4-a716-446655440000"
}

Response samples

Content type
application/json
{
  • "kid": "string",
  • "state": "enabled",
  • "created_at": "2026-07-09 19:00:00"
}

List Keys

List all cryptographic keys belonging to a tenant.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Update Key

Update a key's state. Set state to enabled or disabled. Disabled keys cannot be used for cryptographic operations.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

kid
required
string

The key identifier (KID).

Request Body schema: application/json
required
state
required
string
Enum: "enabled" "disabled"

Set to enabled or disabled.

Responses

Request samples

Content type
application/json
{
  • "state": "enabled"
}

Delete Key

Permanently destroy a key in the HSM and remove its database record.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

kid
required
string

The key identifier (KID).

Responses

Crypto

Encrypt

Encrypt plaintext data using a key inside the HSM. Returns the ciphertext, IV, and authentication tag (AES-256-GCM).

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

kid
required
string

The key identifier (KID).

Request Body schema: application/json
required
plaintext
required
string <byte>

Base64-encoded plaintext to encrypt.

aad
string <byte>

Optional base64-encoded additional authenticated data (AAD) for AES-GCM.

Responses

Request samples

Content type
application/json
{
  • "plaintext": "SGVsbG8gV29ybGQ=",
  • "aad": "dXNlci1pZD0xMjM="
}

Response samples

Content type
application/json
{
  • "ciphertext": "string",
  • "iv": "string",
  • "tag": "string"
}

Decrypt

Decrypt ciphertext using a key inside the HSM (AES-256-GCM).

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

kid
required
string

The key identifier (KID).

Request Body schema: application/json
required
ciphertext
required
string <byte>

Base64-encoded ciphertext.

iv
required
string <byte>

Base64-encoded initialization vector.

tag
required
string <byte>

Base64-encoded authentication tag.

aad
string <byte>

Optional base64-encoded additional authenticated data (AAD).

Responses

Request samples

Content type
application/json
{
  • "ciphertext": "string",
  • "iv": "string",
  • "tag": "string",
  • "aad": "string"
}

Response samples

Content type
application/json
{
  • "plaintext": "string"
}

Generate Data Key

Generate a random data encryption key (DEK). Returns the plaintext DEK and a wrapped copy encrypted by the key. Useful for envelope encryption patterns.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

kid
required
string

The key identifier (KID).

Request Body schema: application/json
required
object (Generate Data Key Request)

Payload for generating a data encryption key (DEK). The key identifier (KID) is provided in the URL path.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "plaintext_key": "string",
  • "wrapped_key": "string",
  • "iv": "string",
  • "tag": "string"
}

Import (BYOK)

Get Import Parameters

Retrieve the wrapping key parameters needed for Bring Your Own Key (BYOK) import. Returns a transient RSA-4096 public key. Use this to wrap your key material with RSA-OAEP-SHA-256 before calling the import endpoint.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

Responses

Response samples

Content type
application/json
{
  • "wrapping_transient_key": "string",
  • "wrapping_public_key": "string",
  • "wrapping_algorithm": "rsa_oaep_sha_256",
  • "wrapping_key_spec": "rsa_4096"
}

Import Key (BYOK)

Import externally-generated key material wrapped with the transient wrapping key obtained from the import-parameters endpoint. The wrapped material is unwrapped inside the HSM — the plaintext key never leaves the HSM boundary.

Authorizations:
API Key
path Parameters
tenant_id
required
string <uuid>

The UUID of the tenant.

Request Body schema: application/json
required
kid
string <uuid>

Optional key identifier (UUID v4). If omitted, a random UUID is generated.

wrapping_transient_key
required
string

The transient wrapping key reference obtained from the import-parameters endpoint.

wrapped_key_material
required
string <byte>

Base64-encoded key material wrapped with the wrapping public key (RSA-OAEP-SHA-256).

Responses

Request samples

Content type
application/json
{
  • "kid": "550e8400-e29b-41d4-a716-446655440000",
  • "wrapping_transient_key": "string",
  • "wrapped_key_material": "string"
}

Response samples

Content type
application/json
{
  • "kid": "string"
}