Skip to content

Top-level keys

Key Type Default
traces bool false
metrics bool false
production bool true
ssh_key string empty
ssh_key_file string empty
ssh_key_passphrase string empty
ssh_key_passphrase_file string empty
max_cert_lifetime duration 2160h
max_service_cert_lifetime duration 17544h
fips bool false
multi_instance bool false

bool, default false

Enables OpenTelemetry tracing, adding the otelgin middleware to the router. Exporter endpoints come from the standard OTEL_* environment variables.

traces: false

bool, default false

Enables OpenTelemetry metrics. Exporter endpoints come from the standard OTEL_* environment variables.

metrics: false

bool, default true

Selects gin’s release mode rather than debug mode, and gates the development-only escape hatches: notably http.rate_limit_disable_for_dev is honored only when this is false, so rate limiting cannot be switched off in production.

production: true

string, default empty

The SSH CA private key used to sign issued certificates. Inline PEM, not a file path. Exactly one of ssh_key, ssh_key_file or hsm may be set, and one of them must be: startup fails without a CA key.

ssh_key: |
-----BEGIN OPENSSH PRIVATE KEY-----
-----END OPENSSH PRIVATE KEY-----

string, default empty

Reads the CA private key from a file instead of holding it inline, so the key can be a mounted secret, a systemd credential or a file with its own ownership and mode, rather than config text. It is the middle option between an inline key and a PKCS#11 token: the key is still a file on disk that the process reads, but it is no longer part of the config file, so the config can be world-readable, checked into configuration management, or rendered by a template without carrying the CA with it.

Read once at startup, so an unreadable or malformed key is a boot failure rather than a signing failure later. The contents are used verbatim: unlike a PIN or a password, PEM is whitespace-sensitive at its delimiters and nothing is trimmed.

ssh_key_file: /etc/ssoossh/ca-key
ssh_key_file: "/etc/ssoossh/ca-key"

string, default empty

Decrypts a passphrase-protected CA key, from either ssh_key or ssh_key_file. Prefer ssh_key_passphrase_file: this value is a secret sitting in a config file.

Understand what it protects before relying on it. The passphrase guards the key AT REST and nothing else: once parsed, the private key is plaintext in the signer’s memory exactly as an unencrypted one would be. It defends against the key file leaking on its own – a backup, a volume snapshot, a stray copy in a support bundle – and it defends against that only if the passphrase is not stored beside the key. A passphrase in the same config file as ssh_key, or in a file mounted next to ssh_key_file with the same ownership, buys nothing: whoever reads one reads the other.

ssh_key_passphrase: ""

string, default empty

Reads the passphrase from a file instead, so it can come from a mounted secret or a systemd credential with different ownership than the key itself – which is the arrangement that makes a passphrase worth having at all. Exactly one of ssh_key_passphrase or ssh_key_passphrase_file may be set.

Read once at startup. Trailing whitespace is trimmed, since an editor’s newline is never part of a passphrase.

ssh_key_passphrase_file: "/run/secrets/ssoossh-ca-passphrase"

duration, default 2160h

The maximum lifetime for user/service/PAM certificates, enforced as a defense-in-depth check before signing. Must be greater than zero; a non-positive value fails startup.

max_cert_lifetime: 2160h

duration, default 17544h

The maximum lifetime for service certificates, enforced as a defense-in-depth check before signing. Service enrollments default to 8760h (cert_options.service valid_duration), so this cap carries headroom over its default. Must be greater than zero; a non-positive value fails startup.

max_service_cert_lifetime: 17544h

bool, default false

Steers the server toward FIPS 140-3 approved algorithms: the CA key (checked at startup), client-submitted public keys (checked in when a request is approved and again by the signer), and the TLS cipher/curve profile. A non-approved algorithm is a hard error when this is in effect.

Unset is distinguishable from an explicit false: unset follows the Go runtime’s own FIPS 140-3 mode, crypto/fips140.Enabled(), which is why this key ships with no value rather than set to false.

fips: true

bool, default false

Declares that the server is part of a multi-instance deployment (multiple ssoosshd processes sharing a database). When enabled, certain checks are enforced (e.g., cookie_key must be explicitly set) and behaviors adapt to account for cross-instance message delivery (a client waiting on one instance is woken by another) payloads). See docs/dev/multi-instance-safety-plan.md.

multi_instance: false