TL;DR
Bring Your Own Key (BYOK) for the Marturia Audit tier lets an enterprise keep a 32-byte KEK entirely under its control. Marturia receives only a wrapped form of that KEK and uses HKDF to derive tenant-specific and session-specific Ed25519 signing keys; the KEK itself is never stored or seen by Marturia. The result is that a fully compromised Marturia deployment still cannot produce signatures that verify under the customer’s published public key.
Threat model¶
A BYOK customer buys a simple guarantee: even if every Marturia server, operator, and database is under attacker control, the attacker cannot mint receipts that appear to come from that tenant.
Because the root KEK never leaves the customer’s hardware token or HSM, the only way an attacker can produce a valid Ed25519 signature for the tenant is to obtain that KEK. All downstream keys are derived with HKDF using tenant-specific labels and per-session nonces; compromise of any derived key therefore yields nothing about the KEK or other tenants.
HKDF derivation tree¶
Marturia uses a two-level HKDF tree:
The public key published to the verifier is derived from the session seed; the verifier never needs the KEK or any private material.
Step-by-step setup¶
1. Generate the KEK offline¶
Create a 32-byte secret on a machine or hardware token that never touches the network:
# On an air-gapped workstation or HSM
openssl rand -out kek.bin 32
sha256sum kek.bin # record the fingerprint
Store kek.bin in your organization’s key-management system (HSM, Vault, or equivalent). This file is the only long-term secret you must protect.
2. Wrap the KEK for transport (future API, current pattern)¶
At Audit-tier launch the provisioning endpoint will accept an RSA-OAEP-wrapped KEK or an HPKE ciphertext. Until that endpoint exists, Marturia supplies a short-lived transport key via the session-bound pattern documented in the closed-beta SDK. The same wrapping code will work unchanged once the production endpoint is available:
# Pseudocode that will be identical at launch
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
transport_pub = get_marturia_transport_key() # ephemeral, session-scoped
wrapped = transport_pub.encrypt(
kek.bin,
padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None)
)
3. Bootstrap derivation parameters¶
POST the wrapped KEK together with a tenant UUID and an HKDF salt:
POST /v1/byok/bootstrap
Content-Type: application/json
{
"tenant_id": "123e4567-e89b-12d3-a456-426614174000",
"wrapped_kek": "<base64>",
"salt": "<32-byte random>"
}
Marturia stores only the wrapped blob and the salt; the plaintext KEK is decrypted inside an enclave, used for a single HKDF expansion, and immediately discarded.
4. Verify the first signed receipt¶
After bootstrap, request any audit operation. The returned receipt contains the Ed25519 public key and signature. Verify with the public marturia-verify tool:
pip install marturia-verify
marturia-verify receipt.json \
--tenant 123e4567-e89b-12d3-a456-426614174000
A successful verification proves the receipt was signed under a key ultimately derived from your KEK.
Trade-offs¶
BYOK removes Marturia from the trust boundary for signature authenticity, but it shifts operational responsibility to you. You must:
- Safeguard the KEK for the lifetime of the tenant.
- Rotate or escrow it according to your own policies.
- Accept that loss of the KEK permanently prevents new receipts from being issued under that tenant (existing receipts remain verifiable).
Most organizations therefore keep the KEK in an HSM with strict access controls and maintain a sealed escrow copy for disaster recovery.
Compatibility with marturia-verify¶
The public verifier package never changes. It only requires the Ed25519 public key embedded in each receipt and the tenant’s published root public key. Whether that key was generated from a platform-managed seed or from your own KEK is invisible to the verifier.
Roadmap note¶
The Audit tier and its BYOK capability are scheduled for Phase 2. During the current closed beta all tenants use platform-managed keys. The steps above are provided now so that security teams can prepare policies, HSM integrations, and runbooks ahead of launch.
Related Marturia resources - /docs/api.html - /learn/lesson_05_how_marturia_signs_a_receipt.html