HSM-backed State and Secrets
CyberVault KMS stores its state in data objects on the HSM instead of an external database.
These objects hold the Key Manager's own runtime state such as configuration, user and MFA state, partition registry data, and integration secrets. They govern how the service behaves after restart or unseal.
Their persistence is covered by the HSM's normal clustering and backup mechanisms, so no separate database-style backup process is needed for Key Manager state. Even though the data objects use up storage on the partition, the footprint is small because they are control-plane objects rather than bulk application data.
Because they are plain data objects, they are visible through the normal HSM API interfaces. This documentation explains which data objects exist, how they are named, and what purpose they serve. This helps operators understand the objects that they see on their HSM partition.
For an operator, the important question is usually:
- which data object should I inspect
- what kind of content should I expect there
- which objects contain plaintext metadata versus sealed or encrypted content
Do not attempt to edit these data objects directly. Instead, use the Key Manager UI or API to edit them.
Available Data Objects
The easiest way to inspect the HSM keystore is through the Retrieve Data Object API on the TSB. This should mainly be used for inspection, troubleshooting, or break-glass recovery.
The main object families are:
kms.config.public
kms.secret.*
kms.users
kms.users.<username>
kms.app.partitions
kms.app.partition.<id>
kms.config.public
Use this object when you want to inspect the non-secret platform configuration.
Conceptually:
{
// Non-secret runtime configuration.
"schema_version": 1,
"general": { "...": "..." },
"jwt": { "...": "..." },
"oauth": { "...": "..." },
"totp": { "...": "..." },
"kmip": { "...": "..." },
"llm": { "...": "..." },
"mcp": { "...": "..." },
"audit": { "...": "..." },
"notifications": { "...": "..." },
"syslog": { "...": "..." }
}
// No secret values are stored here.
kms.secret.*
Use these objects when you want to inspect admin-managed secret types.
Current secret objects:
kms.secret.tsb
kms.secret.oauth.microsoft
kms.secret.oauth.github
kms.secret.oauth.keycloak
kms.secret.llm
kms.secret.audit
kms.secret.smtp
kms.secret.syslog
Fields by object:
kms.secret.tsb -> access_token of the base-partition
kms.secret.oauth.microsoft -> client_secret
kms.secret.oauth.github -> client_secret
kms.secret.oauth.keycloak -> client_secret
kms.secret.llm -> api_key
kms.secret.audit -> signing_key_password
kms.secret.smtp -> password
kms.secret.syslog -> ca_cert, client_cert, client_key
Conceptually:
{
// One object per secret type.
"v": 1,
"type": "oauth.microsoft",
"version": 3,
"fields": {
"client_secret": {
// Protection class for this field.
"mode": "ml-kem-only",
"updated_at": "2026-05-29T08:00:00Z",
"updated_by": "admin",
"envelope": {
"...": "encrypted field payload"
}
}
},
"updated_by": "admin",
"updated_at": "2026-05-29T08:00:00Z"
}
// Plaintext secret values are not stored directly in the object.
Important note:
ml-kem-onlymeans application-side envelope protectionska-gatedmeans the field is wrapped behind SKA-approval-gated key (SKA policy is enforced by the HSM)kms.secret.audit.signing_key_passwordis the main secret that defaults toska-gated
kms.users
Use this object when you want to inspect the user index.
Conceptually:
{
// Username -> HSM data object key.
"users": {
"alice": "kms.users.alice"
},
"version": "3.0"
}
This object is an index only. It does not hold user passwords, TOTP secrets, or partition credentials.
kms.users.username
Use these objects when you want to inspect an individual user record.
Conceptually:
{
"username": "alice",
// bcrypt hash, not plaintext password.
"password_hash": "$2a$10$...",
"provider": "hsm_auth",
"role": "admin",
"partitions": [
{
// Reference only, not inline credentials.
"id": "9b8d0a6c4d3147f1a2b3c4d5e6f70809",
"default": true,
"color": "#e30613"
}
],
// Shared TOTP secret.
"totp_secret": "JBSWY3DPEHPK3PXP",
"totp_pending": false,
"recovery_codes": [
// Stored as hashes, not plaintext recovery codes.
"4f5c..."
],
"enabled": true,
"created_at": "2026-05-29T08:00:00Z"
}
Important note:
- local user passwords are stored as bcrypt hashes
- recovery codes are stored as hashes
- user records do not contain inline partition
api_urloraccess_token
kms.app.partitions
Use this object when you want to inspect the partition registry index.
Conceptually:
{
// Partition ID -> HSM data object key.
"partitions": {
"9b8d0a6c4d3147f1a2b3c4d5e6f70809": "kms.app.partition.9b8d0a6c4d3147f1a2b3c4d5e6f70809"
},
"version": "1.0"
}
// This index is plaintext because it stores only IDs and object references.
This object helps you discover which concrete partition objects exist.
kms.app.partition.id
Use these objects when you want to inspect a concrete shared partition entry.
Logical content:
{
"id": "9b8d0a6c4d3147f1a2b3c4d5e6f70809",
"display_name": "Production",
// Secret-bearing partition connection details.
"api_url": "https://tsb.example.local",
"access_token": "eyJ...",
"color": "#e30613",
"description": "Primary production partition",
"created_at": "2026-05-29T08:00:00Z",
"updated_at": "2026-05-29T08:10:00Z",
"created_by": "admin"
}
// This is the logical content, not the at-rest wrapper.
At rest, the stored object is a sealed wrapper:
{
// Stored in the HSM data object.
"v": 1,
"envelope": {
"...": "encrypted partition payload"
},
"updated_at": "2026-05-29T08:10:00Z"
}
// The sensitive partition entry is inside the envelope.
Important note:
kms.app.partition.<id>is the place to look for stored partition credentials- at rest, those credentials are sealed and not visible as plaintext fields
Operator summary
When using the TSB Data Object inspection APIs:
- look at
kms.config.publicfor non-secret runtime configuration - look at
kms.secret.*for admin-managed secret types - look at
kms.usersto discover user object names - look at
kms.users.<username>for user-specific MFA and password-hash state - look at
kms.app.partitionsto discover partition object IDs - look at
kms.app.partition.<id>for sealed partition connection entries
If an object contains an envelope or per-field secret envelope, the sensitive value is stored in protected form rather than as plaintext JSON.