TKeeper reads config in this order:
- JVM system properties
- external config from
KEEPER_CONFIG_LOCATIONor-Dkeeper.config.location - profile config from
KEEPER_PROFILEor-Dkeeper.profile - bundled
application.conf - bundled
reference.conf
External config can be:
- a file
- a directory with
application.conf,application.json, orapplication.properties classpath:...http://...orhttps://...
Multiple external locations are comma-separated. Earlier locations win because they are loaded first.
Profile config uses bundled files named application-{profile}.conf, application-{profile}.json, or application-{profile}.properties.
Dev auth config is separate. Enable it with:
-Dkeeper.dev.enabled=true
-Dkeeper.dev.config.location=/etc/tkeeper
When the dev location is a directory, TKeeper looks for dev.conf, dev.json, or dev.properties. A direct file path also works.
Example:
java \
-Dkeeper.config.location=/etc/tkeeper \
-Dkeeper.dev.config.location=/etc/tkeeper \
-jar build/libs/tkeeper-2.0.0.jar
Minimal node config:
auth { type = "dev" }
boot { token = "change-me" }
keeper {
database { path = "/var/lib/tkeeper/db" }
providers {
selected = "shamir"
shamir {
total = 5
threshold = 3
}
}
server {
public {
host = "0.0.0.0"
port = 8080
}
internal {
host = "0.0.0.0"
port = 9090
}
}
peers = [
{ id = 2, internal-url = "http://keeper-2:9090" },
{ id = 3, internal-url = "http://keeper-3:9090" }
]
}
Common fields:
| Field | Meaning |
|---|---|
keeper.database.path |
RocksDB path |
keeper.server.public |
API users call this |
keeper.server.internal |
Peers call this |
keeper.peers |
Other peers in the cluster; self is omitted |
keeper.providers.selected |
Seal provider id |
keeper.client.tls |
TLS for peer clients |
keeper.approval.ttl |
Four eye approval lifetime |
keeper.session.* |
DKG, FROST, GG20, ECIES, destroy session limits |
Coordinator-only endpoints can be disabled on a node:
-Dkeeper.coordinator.enabled=false
or:
KEEPER_COORDINATOR_ENABLED=false
Use that for peers that only participate in threshold protocols.
Server TLS
TLS can use a keystore:
keeper.server.public.tls {
enabled = true
key-store-path = "/etc/tkeeper/public.p12"
key-store-password = "..."
key-store-type = "PKCS12"
}
or certificate files:
keeper.server.public.tls {
enabled = true
certificate-chain-path = "/etc/tkeeper/tls.crt"
private-key-path = "/etc/tkeeper/tls.key"
}
Public and internal servers have separate TLS blocks:
keeper.server.public.tls { enabled = true }
keeper.server.internal.tls { enabled = true }
The peer client must trust the internal server certificate when internal TLS is enabled:
keeper.client {
tls = true
trust-store-path = "/etc/tkeeper/internal-truststore.p12"
trust-store-password = "..."
}
Authentication
JWT authentication is configured under auth.jwt:
auth {
type = "jwt"
jwt {
jwks-location = "https://issuer.example/.well-known/jwks.json"
issuer = "https://issuer.example"
audience = "tkeeper"
refresh = 15m
clock-skew = 15s
}
}
When issuer is configured, it must match the token iss claim. Configure it in production to bind tokens to the expected identity provider.
audience must be present in the token aud claim. Tokens must contain exp; nbf is honored when present.
clock-skew defaults to 15s and must not be negative.
Sessions
Session limits live under keeper.session:
keeper.session {
dkg { expire = 5m }
destroy { expire = 5m }
frost {
expire = 5m
max-rounds = 5
}
gg20 {
expire = 15m
max-rounds = 3
}
ecies {
max-rounds = 3
}
}
Audit
Minimal file audit:
keeper.audit {
enabled = true
timeout = 1000
file {
directory = "/var/lib/tkeeper/audit"
extension = "ndjson"
}
}
Socket audit supports TLS, SPKI pins, client certificates, batching, timeouts, and reconnect backoff. See Audit Logging.
ORAS
ORAS config is used by authority OCI pulls:
oras {
insecure = false
username = "robot"
password = "secret"
}
For HTTPS registries, set insecure = false. For a local plain HTTP registry, set insecure = true.
UI CSP
The UI has its own CSP config under keeper.csp. See Enabling UI.
Environment Aliases
Common environment variables:
| Variable | Config field |
|---|---|
KEEPER_AUTH_TYPE |
auth.type |
KEEPER_BOOT_TOKEN |
boot.token |
KEEPER_DATABASE_PATH |
keeper.database.path |
KEEPER_AUDIT_ENABLED |
keeper.audit.enabled |
KEEPER_SEAL_SELECTED |
keeper.providers.selected |
KEEPER_SEAL_SHAMIR_TOTAL |
keeper.providers.shamir.total |
KEEPER_SEAL_SHAMIR_THRESHOLD |
keeper.providers.shamir.threshold |
KEEPER_HOST |
keeper.server.public.host |
KEEPER_PORT |
keeper.server.public.port |
KEEPER_INTERNAL_HOST |
keeper.server.internal.host |
KEEPER_INTERNAL_PORT |
keeper.server.internal.port |
KEEPER_TLS_ENABLED |
keeper.server.public.tls.enabled |
KEEPER_INTERNAL_TLS_ENABLED |
keeper.server.internal.tls.enabled |
KEEPER_CLIENT_TLS |
keeper.client.tls |
Frequent Problems
Peer calls fail
Check keeper.peers. Each node lists the other peers, not itself.
Authority OCI pull fails with TLS errors
Local registry over plain HTTP:
oras { insecure = true }
Real registry over HTTPS:
oras { insecure = false }