Configuration
Client configuration
Options, environment variables and defaults for each client in the secretserver-clients repository.
Environment variables
| Variable | Read by | Meaning |
|---|---|---|
SS_API_KEY | Python, Node.js, PHP, Ansible | API key when none is passed |
SS_API_URL | Python, Node.js, PHP, Ansible | Base URL when none is passed. Default https://api.secretserver.io |
SS_PARTIAL_UPDATES | Python, Node.js, PHP | 1 enables partial updates without an ETag. Only safe against server build 3075630 or newer. |
SS_CA_PATH | Ansible | PEM CA bundle added to the system roots |
NODE_EXTRA_CA_CERTS | Node.js runtime | Trust a private CA in the Node.js client |
SECRETSERVER_URL | MCP bridge | API origin (required) |
SECRETSERVER_TOKEN_FILE | MCP bridge | Owner-only file holding the API key (required) |
SECRETSERVER_ENABLE_SECRET_RESOLUTION | MCP bridge | 1 registers resolve_secret_template |
SECRETSERVER_RESOLVE_ALLOW | MCP bridge | Comma-separated allowlist of variable names |
The Go library reads no environment variables. Explicit constructor arguments always win over the environment, except in PHP, where
SS_PARTIAL_UPDATES=1 enables partial updates even when the argument is false.Python
SecretServerClient(api_key=None, api_url=None, timeout=10,
verify_ssl=True, ca_file=None, partial_updates=None)| Option | Default | Notes |
|---|---|---|
api_key | SS_API_KEY | Required; AuthError if missing. CR, LF and NUL are rejected. |
api_url | SS_API_URL, then https://api.secretserver.io | https, or http to a loopback host. A trailing /api/v1 is removed. |
timeout | 10 | Seconds; must be positive |
verify_ssl | True | Anything else raises ValueError |
ca_file | None | PEM bundle added to the default trust store |
partial_updates | SS_PARTIAL_UPDATES == "1" | Read from the environment only when not passed |
Fixed behavior: TLS 1.2 minimum, User-Agent secretserver-python/1.3.0, 4 MiB JSON and 16 MiB download caps.
Node.js / TypeScript
new SecretServerClient({ apiKey, apiUrl, fetchFn, timeoutMs, partialUpdates })| Option | Default | Notes |
|---|---|---|
apiKey | SS_API_KEY | Required; AuthError if missing |
apiUrl | SS_API_URL, then https://api.secretserver.io | https, or http to localhost, 127.0.0.1 or ::1 |
fetchFn | global fetch | Custom fetch implementation |
timeoutMs | 10000 | Milliseconds; must be positive |
partialUpdates | SS_PARTIAL_UPDATES === "1" | An explicit false wins over the environment |
Fixed behavior: redirects rejected, User-Agent secretserver-node/1.3.0.
PHP
new SecretServerClient(?string $apiKey = null, ?string $apiUrl = null, int $timeout = 10,
bool $verifySsl = true, ?string $caFile = null, bool $partialUpdates = false)| Option | Default | Notes |
|---|---|---|
$apiKey | SS_API_KEY | Required; AuthException if empty |
$apiUrl | SS_API_URL, then https://api.secretserver.io | https, or http to a loopback host; no credentials, query or fragment |
$timeout | 10 | Seconds |
$verifySsl | true | false throws |
$caFile | null | Must exist if given |
$partialUpdates | false | Also enabled by SS_PARTIAL_UPDATES=1 or setPartialUpdates(true) |
Fixed behavior: cURL without redirect following, User-Agent secretserver-php/1.3.0.
Go
ss.NewClient(&ss.Config{APIURL, APIKey, HTTPClient, UserAgent, PartialUpdates})| Field | Default | Notes |
|---|---|---|
APIKey | none | Required |
APIURL | https://api.secretserver.io | https, or http to a loopback host |
HTTPClient | 30 s timeout, TLS 1.2 minimum, no redirects | Its Transport must be nil or an *http.Transport. InsecureSkipVerify and custom TLS dialers are refused. The transport is cloned and TLS raised to 1.2. |
UserAgent | Go default | Sent when set |
PartialUpdates | false | Allow Secrets.Update and JKS.Update without an ETag |
Ansible
| Option | Environment | ansible.cfg [secretserver] | Default |
|---|---|---|---|
api_key | SS_API_KEY | api_key | required |
api_url | SS_API_URL | api_url | https://api.secretserver.io |
ca_path | SS_CA_PATH | ca_path | system roots |
timeout | none | none | 10 |
version | none | none | not set (1 to 12) |
render | none | none | false |
ansible.cfg
[secretserver] api_url = https://api.secretserver.io ca_path = /etc/ssl/private-ca.pem # api_key: prefer SS_API_KEY or an encrypted variable over a plaintext file
The lookup honors the standard proxy environment variables.
Desktop app
| Setting | Where it is stored | Default |
|---|---|---|
| API URL | Fyne preferences for app ID com.afterdarksys.secretserver, key api_url | https://api.secretserver.io |
| API key | OS keychain, service com.afterdarksys.secretserver, account = API URL | none |
MCP bridge
| Variable | Required | Rules |
|---|---|---|
SECRETSERVER_URL | yes | https, or http to a loopback host; no credentials, query or fragment. A path prefix is kept and a trailing /api/v1 removed. |
SECRETSERVER_TOKEN_FILE | yes | Regular file with no group or other permissions; 16 to 8192 bytes after trimming |
SECRETSERVER_ENABLE_SECRET_RESOLUTION | no | Exactly 1 to enable |
SECRETSERVER_RESOLVE_ALLOW | when resolution is on | Names matching [A-Z_][A-Z0-9_]{0,127} |
Fixed behavior: TLS 1.2 minimum, 30 second timeout, no redirects, 4 MiB response cap.
Live test variables
The live integration tests in each library refuse to run unless they point at a loopback server. They never fall back to SS_API_URL or SS_API_KEY.
| Variable | Meaning |
|---|---|
SS_LIVE_URL | Loopback test server URL |
SS_LIVE_KEY | Test API key |
SS_LIVE_WRITE_KEY | Test key with write scopes (Go smoke test) |
SS_LIVE_CONTAINER | Container used by the Go smoke test |