Compliance
This section describes TKeeper compliance-oriented controls:
- Audit logging and verification: signed, tamper-evident records for security-relevant operations.
- Asset inventory: machine-readable inventory of managed keys for oversight and reporting.
Regulatory packet (KMS suitability overview):
https://cdn.exploit.org/tkeeper-regulatory.pdf
Audit logging and verification
Audit logging is an enforceable control in TKeeper. When audit logging is enabled, every security-relevant operation emits a signed audit record. If no configured sink can accept the record at the time of the operation, the operation is denied.
Enabling audit logging
keeper {
audit {
enabled = true
}
}
Operational rule:
- enabled = false: audit records are not produced; sinks are not required.
- enabled = true: at least one sink must be functional; otherwise secured operations are denied.
Log format
Audit logs are emitted as NDJSON (.ndjson): one JSON object per line.
Each line is a SignedLine with two fields:
event: JSON object describing the audit eventsignature: Base64-encoded Ed25519 signature over the exact UTF-8 bytes of theeventobject
Example (schema-level):
{
"event": { "...": "..." },
"signature": "base64(ed25519(event_bytes))"
}
AuditEvent fields
event contains structured data about what happened. Not every field is present on every record; unused sections may be null or absent depending on the event type.
Common fields:
id: unique event identifierpeerId: keeper instance that emitted the recordintegrityKeyVersion: version of the integrity signing key used for this recordtimestamp: epoch milliseconds (UTC)event: event category identifier (for exampleevent.frost.init)auth.subject: authenticated subject (if available)context.sid: session identifier for multi-party operationsrequest.method,request.path,request.remoteAddress: HTTP request contextcrypto.algo,crypto.kid,crypto.curve: cryptographic context (algorithm, key id, curve)digest.purpose: label for the hashed payload (for exampleauditorrequestBody)digest.hmacKeyVersion: version of the local HMAC key used to compute the body hashdigest.bodyHash.alg:HMAC_SHA256digest.bodyHash.value64: Base64-encoded HMAC-SHA256 of the request body (request bodies are not persisted)outcome.statusCode,outcome.error,outcome.details: HTTP outcome and error details (including failures)imposters: Malicious nodes detected during this requestdead: Dead nodes detected during this requests
Integrity key and rotation
Each SignedLine is signed using an Ed25519 integrity key. The signing key version is recorded in integrityKeyVersion.
Integrity key rotation is performed via the Integrity API family. On rotation: - TKeeper generates a new integrity key and increments the version. - Prior integrity key versions remain available for verification of existing audit records.
Audit sinks
A sink is a destination that receives SignedLine records. TKeeper supports:
- File sink (
keeper.audit.file) - Socket sink (
keeper.audit.socket)
Sinks can be enabled independently or together. When keeper.audit.enabled = true, at least one sink must be able to accept records.
File sink
The file sink writes SignedLine records as NDJSON to local files and supports rotation and retention controls.
keeper {
audit {
file {
directory = "audit"
extension = "ndjson"
max-file-size-bytes = 67108864
prefix = "audit"
# Optional
roll-every = 1h
max-files = 10
retention-days = 30
gzip = false
fsync = false
}
}
}
| Key | Meaning | Default |
|---|---|---|
directory |
Output directory. | audit |
extension |
Filename extension. | ndjson |
max-file-size-bytes |
Rotate when file exceeds this size. | 64 MiB |
prefix |
Prefix for rotated file names. | audit |
roll-every |
Time-based rotation interval. | unset |
max-files |
Maximum number of rotated files to keep. | 10 |
retention-days |
Maximum age (days) for rotated files. | unset |
gzip |
Compress rotated files. | false |
fsync |
Call fsync() after writes. |
false |
Socket sink
The socket sink streams SignedLine records over a persistent TCP connection, optionally protected with TLS.
keeper {
audit {
socket {
host = "collector.example.com"
port = 443
connect-timeout-millis = 2000
read-timeout-millis = 2000
tcp-no-delay = true
keep-alive = true
so-linger-seconds = 0
tls {
protocols = ["TLSv1.3", "TLSv1.2"]
verify-hostname = true
trust {
mode = "system" # or "custom"
path = "/etc/tkeeper/truststore.jks"
password = "change-me"
type = "JKS"
}
spki-pins = ["base64(spki)"]
client {
keystore-path = "/etc/tkeeper/client.p12"
keystore-password = "change-me"
keystore-type = "PKCS12"
}
}
}
}
}
| Key | Meaning | Default |
|---|---|---|
host / port |
Collector address. | localhost / 443 |
connect-timeout-millis |
TCP connect timeout. | 2000 |
read-timeout-millis |
Read timeout. | 2000 |
tcp-no-delay |
Disable Nagle’s algorithm. | true |
keep-alive |
Enable TCP keep-alive. | true |
so-linger-seconds |
Linger time on close. | 0 |
tls.protocols |
Allowed TLS versions. | ["TLSv1.3","TLSv1.2"] |
tls.verify-hostname |
Verify TLS hostname. | true |
tls.trust.* |
Trust configuration (optional store). | unset |
tls.spki-pins |
Base64 SPKI pins for certificate pinning. | unset |
tls.client.* |
Client keystore for mTLS. | unset |
Verification endpoints
TKeeper exposes verification endpoints for SignedLine records:
POST /v1/keeper/audit/verify(single record)POST /v1/keeper/audit/verify/batch(multiple records)
Required permission:
tkeeper.audit.log.verify
Verification checks:
- Verify the detached Ed25519 signature using the
integrityKeyVersionreferenced by the event. - If the record includes a request-body digest, recompute and verify the HMAC body hash.
Peer constraint:
- The keeper that emitted a record holds the HMAC key material referenced by
peerId/digest.hmacKeyVersion. - For digest verification, submit verification requests to the same keeper identified by
peerIdin the audit record.
Asset inventory
Tip
You can also access Asset Inventory via TKeeper Control Plane available at /ui.
Asset inventory provides a machine-readable snapshot of keys and their lifecycle state. This is designed for compliance reporting, operational oversight, and internal governance.
Endpoint
- GET
/v1/keeper/compliance/inventory
Required permission:
tkeeper.compliance.inventory
Query parameters
| Parameter | Meaning | Default |
|---|---|---|
logicalId |
Filter by key logicalId. |
unset |
historical |
Include historical entries. Logical ID should be specified | false |
lastSeen |
Pagination cursor from the previous response. | unset |
limit |
Maximum items to return (capped at 200). | 200 |
assetOwner |
Asset Owner filter passed during generation | unset |
Response overview
The response is a paginated snapshot and typically includes:
- snapshot metadata (generation time, emitting peer)
- cluster snapshot fields (
threshold,totalPeers) items[]with per-key information (logical id, status, current generation, timestamps, policy if set)
Inventory is intended to be safe for reporting workflows. It describes key metadata and state and does not expose private key material.