Configuration
All the environment variables the kubelatch binary reads, with their default value, format, and what they do. There is no config file or server flags.
At startup, kubelatch validates all the variables and, if there are errors, shows them all together and does not start. The CLI subcommands read the same variables with the same rules: they also need DATABASE_URL, KUBELATCH_BASE_URL and KUBELATCH_ENCRYPTION_KEY.
Each variable has an anchor with its name in lowercase: configuration.md#kubelatch_base_url, configuration.md#database_url, configuration.md#github_app_id.
| Format |
What it accepts |
| Duration |
A number of days <n>d (no leading zeros, up to 3650d) or a Go duration greater than zero (720h, 90m), up to 10 years. |
| List |
Comma-separated values; spaces around them and empty items are ignored. |
| Boolean |
Exactly true or false. Any other value is an error. |
| URL |
Absolute, http or https, with no user, query (?) or fragment (#). |
Server
| Variable |
Required |
Default |
Format |
What it does |
KUBELATCH_LISTEN |
No |
:8080 |
host:port |
Listen address and port. The manifests in deploy/k8s/base use :8443. |
KUBELATCH_BASE_URL |
Yes |
|
URL |
Public URL kubelatch is reached at. It is normalized: no trailing slash, scheme and host lowercased, no default port. Decides the Secure attribute of cookies (if https), the only trusted origin for cross-origin request protection, the URL of invitation links (<base>/cuenta#kli_…), the server of the kubeconfigs (<base>/clusters/<id>), the audience (aud) GitHub Actions tokens must carry, and the GitHub App callback (<base>/api/auth/github/callback). |
KUBELATCH_ENCRYPTION_KEY |
Yes |
|
Standard Base64, exactly 32 bytes |
Master key. From it, with distinct labels, kubelatch derives the key that signs session cookies, the one that signs GitHub login state cookies, and the AES-256-GCM key that encrypts each cluster's ServiceAccount tokens. Rotating it closes every session and requires re-pasting each cluster's tokens. |
KUBELATCH_INSTANCE_ID |
No |
default |
Kubernetes label value: alphanumeric, -, _, ., up to 63 characters |
Value of the kubelatch.io/instance label on the objects kubelatch creates in the clusters. That instance's cleanup and garbage collector only touch their own objects, which lets you move a cluster to another instance. Cleanup does restore the shared kubelatch-proxy ClusterRole to the uids-only rule. It is not meant for two instances to share a cluster at the same time. |
KUBELATCH_TRUSTED_PROXIES |
No |
empty |
List of CIDRs (10.0.0.1/32 for a single host) |
Networks from which X-Forwarded-For is trusted, read right to left up to the first untrusted hop. Affects the source IP recorded in the audit log and the control plane, and the per-IP limits on login, the CI exchange and proxy failures. A bare IP is an error, and so is a prefix wider than /8 (IPv4) or /16 (IPv6). Empty behind an L4 LoadBalancer; mandatory behind an Ingress. |
To generate KUBELATCH_ENCRYPTION_KEY:
head -c32 /dev/urandom | base64
Database
| Variable |
Required |
Default |
Format |
What it does |
DATABASE_URL |
Yes |
|
Postgres connection string (postgres://user:password@host:5432/kubelatch?sslmode=require) |
Database holding all state. kubelatch applies its migrations at startup, and so does every CLI subcommand. |
TLS
| Variable |
Required |
Default |
Format |
What it does |
KUBELATCH_TLS_CERT |
With KUBELATCH_TLS_KEY |
empty |
Path to a PEM file |
Server certificate. With both variables, kubelatch serves HTTPS (TLS 1.2 or higher, HTTP/2 and HTTP/1.1). Reloads the pair when it changes on disk (checks at most every 10 s); an invalid pair is ignored and logged. An invalid pair at startup prevents startup. Every hour it warns if fewer than 30 days of validity remain. Without them, kubelatch serves plain HTTP. |
KUBELATCH_TLS_KEY |
With KUBELATCH_TLS_CERT |
empty |
Path to a PEM file |
Certificate's private key. The two variables go together: one without the other is an error. |
KUBELATCH_KUBECONFIG_CA |
No |
empty |
Path to a regular PEM file, CERTIFICATE blocks only, up to 1 MiB |
CA embedded as certificate-authority-data in every kubeconfig it issues. Only needed with a private CA. A block that is not a certificate (a key pasted by mistake) prevents startup. |
Permissions
| Variable |
Required |
Default |
Format |
What it does |
KUBELATCH_PROTECTED_NAMESPACES |
No |
empty |
List of namespace names |
Namespaces that admit no permission of any tier, in addition to kube-system, kube-public, kube-node-lease and kubelatch-system, which are always protected. |
KUBELATCH_REQUIRE_PSA |
No |
true |
Boolean |
With false, developer, debugger and admin stop requiring the namespace to carry pod-security.kubernetes.io/enforce=baseline or restricted. Permisos (Permissions) warns about it. See Tiers before changing it. |
Limits and TTLs
| Variable |
Required |
Default |
Format |
What it does |
KUBELATCH_MAX_TTL_USER |
No |
30d |
Duration |
Maximum lifetime of a person's credential. |
KUBELATCH_MAX_TTL_BOT |
No |
90d |
Duration |
Maximum lifetime of a bot's credential, including CI ones. |
Audit
| Variable |
Required |
Default |
Format |
What it does |
KUBELATCH_AUDIT_RETENTION |
No |
90d |
Duration of at least 1 day, or 0 / 0d |
How long audit_events and control_events are kept. A periodic job on each replica deletes hourly (the first pass, one minute after startup), in batches of 5,000 rows. 0 or 0d disables deletion. The same job deletes CI jtis one hour after their token expires, regardless of this value. |
CI
| Variable |
Required |
Default |
Format |
What it does |
KUBELATCH_CI_TOKEN_TTL |
No |
1h |
Duration, no greater than KUBELATCH_MAX_TTL_BOT |
Lifetime of the credentials a GitHub Actions workflow gets when it exchanges its OIDC token. |
KUBELATCH_GITHUB_ACTIONS_ISSUER |
No |
https://token.actions.githubusercontent.com |
URL; http only on a loopback host |
Issuer (iss) of GitHub Actions OIDC tokens. Its keys are read from <issuer>/.well-known/jwks. For GitHub Enterprise Server: https://<host>/_services/token. |
Identity and GitHub
These variables configure login with your organization's GitHub App (see GitHub login). Without any of them, kubelatch works with local passwords only.
The five core variables (GITHUB_APP_ID, GITHUB_APP_CLIENT_ID, GITHUB_APP_CLIENT_SECRET, GITHUB_APP_PRIVATE_KEY, GITHUB_ORG) go together. With any of them present, or with GITHUB_WEBHOOK_SECRET, all five are required and kubelatch does not start if any is missing. GITHUB_REQUIRE_ORG_2FA, GITHUB_URL and GITHUB_API_URL alone activate nothing. All of them have surrounding spaces stripped.
| Variable |
Required |
Default |
Format |
What it does |
GITHUB_APP_ID |
With GitHub |
|
Positive integer |
App ID of the GitHub App. Signs the JWT kubelatch uses to get installation tokens. |
GITHUB_APP_CLIENT_ID |
With GitHub |
|
Text (Iv1.…, Iv23…) |
App's Client ID, for OAuth login. |
GITHUB_APP_CLIENT_SECRET |
With GitHub |
|
Text |
App's client secret, to exchange the login code server-side. |
GITHUB_APP_PRIVATE_KEY |
With GitHub |
|
Full RSA PEM (PKCS#1 RSA PRIVATE KEY or PKCS#8 PRIVATE KEY), 2048 to 8192 bits; accepted on one line with literal \n |
App's private key. It is the file's content, not a path. |
GITHUB_ORG |
With GitHub |
|
GitHub organization login (acme-corp) |
Only active members of this organization can sign in. The hourly member sync walks it. |
GITHUB_WEBHOOK_SECRET |
No |
empty |
Text |
Activates POST /v1/github/webhook (HMAC-SHA256 signature in X-Hub-Signature-256), which instantly disables anyone who leaves the organization. Its presence turns on GitHub mode. |
GITHUB_REQUIRE_ORG_2FA |
No |
true |
Boolean |
Rejects GitHub logins while kubelatch knows the organization does not require two-factor. It can only know this if the App has Organization → Administration: read; otherwise it lets people in and warns on every sync. |
GITHUB_URL |
No |
https://github.com |
URL; http only on a loopback host |
Only for GitHub Enterprise Server: https://<host>. Base for the OAuth authorization routes. |
GITHUB_API_URL |
No |
https://api.github.com |
URL; http only on a loopback host |
Only for GitHub Enterprise Server: https://<host>/api/v3. |
Member sync runs every hour; that interval is not configurable.
What goes in a Secret
In Kubernetes, DATABASE_URL, KUBELATCH_ENCRYPTION_KEY and the sensitive GITHUB_* variables go in the kubelatch-secrets Secret, which the Deployment loads whole. Everything else goes in deploy/k8s/base/config.env, which becomes the kubelatch-config ConfigMap.