Environment variables
Every KINDGI_* variable the Kindgi runtime (the server) and the pack
service read. Generated from @kindgi/env-schema, Kindgi's own list, so
it matches this version.
The KINDGI_ prefix is reserved for Kindgi: a pack can't declare such a
name in its env, and kindgi dev never resolves one as a secret, so an
app's own variables stay its own.
Core server config
Section titled “Core server config”KINDGI_API_PORT
Section titled “KINDGI_API_PORT”Synopsis
KINDGI_API_PORT=<value>HTTP port the Kindgi API server listens on. The first that's set wins: the --port flag, KINDGI_API_PORT, the platform's PORT (Cloud Run, Render, Heroku and Fly set it and send traffic only there), the config file's port, then 4000.
Values
- Read by: the server
- Required: no
- Default: the platform's
PORTwhen set, else4000
Example
KINDGI_API_PORT=4000See also
KINDGI_API_HOST
Section titled “KINDGI_API_HOST”Synopsis
KINDGI_API_HOST=<value>Address the API server binds. Default: all interfaces (what a container platform such as Cloud Run needs). 127.0.0.1 keeps it off the network; kindgi dev sets that on Linux, where the runtime container shares the host network.
Values
- Read by: the server
- Required: no
- Default: none: binds all interfaces
Example
KINDGI_API_HOST=127.0.0.1See also
KINDGI_PUBLIC_URL
Section titled “KINDGI_PUBLIC_URL”Synopsis
KINDGI_PUBLIC_URL=<value>The URL clients reach the API server at, when it isn't the address the server binds: behind a proxy or a load balancer, or in a container whose port is published on another one (kindgi dev sets it). The startup banner names it, with the docs and console links. An http(s) URL with no query or fragment. Default: the address the server binds.
Values
- Read by: the server
- Required: no
- Default: none: the address the server binds (shown as
http://localhost:<port>when it binds all interfaces)
Example
KINDGI_PUBLIC_URL=https://kindgi.example.comSee also
KINDGI_DATABASE_URL
Section titled “KINDGI_DATABASE_URL”Synopsis
KINDGI_DATABASE_URL=<value>Postgres connection string. Default postgres://localhost:5432/kindgi (dev only).
Values
- Read by: the server
- Required: no
- Default:
postgres://localhost:5432/kindgi
Example
KINDGI_DATABASE_URL=postgres://user:pass@postgres.internal:5432/kindgiSee also
KINDGI_OPENFGA_API_URL
Section titled “KINDGI_OPENFGA_API_URL”Synopsis
KINDGI_OPENFGA_API_URL=<value>OpenFGA HTTP API URL. Set → per-tenant FGA stores are bootstrapped and authorization is enforced; unset → routes mount without enforcement (dev only; production MUST set it).
Values
- Read by: the server
- Required: no
- Default: none: authorization is not enforced
Example
KINDGI_OPENFGA_API_URL=http://openfga.internal:8080See also
KINDGI_OPENFGA_PRESHARED_KEY
Section titled “KINDGI_OPENFGA_PRESHARED_KEY”Synopsis
KINDGI_OPENFGA_PRESHARED_KEY=<value>Used from runtime 0.1.8; earlier runtimes ignore it. OpenFGA's preshared key, for an OpenFGA run with --authn-method=preshared (OPENFGA_AUTHN_PRESHARED_KEYS): the server sends it with every call, as Authorization: Bearer <key>, so nothing else on the network can read or write permissions. Needs KINDGI_OPENFGA_API_URL; KINDGI_TENANCY=multi starts only with both. Set it by reference to a secret, pinned to a version. Use a long random value (openssl rand -hex 32); the server drops surrounding whitespace and refuses spaces, commas or control characters inside (it travels in an HTTP header, and OpenFGA's list is comma-separated). To rotate it without a refusal: add the new key to OpenFGA's list, then point the server at it, then drop the old one, each step its own deploy.
Values
- Read by: the server
- Required: no
- Default: none: calls to OpenFGA carry no key
Example
# long random value without spaces or commasKINDGI_OPENFGA_PRESHARED_KEY="$(openssl rand -hex 32)"See also
KINDGI_OPENFGA_AUTH
Section titled “KINDGI_OPENFGA_AUTH”Synopsis
KINDGI_OPENFGA_AUTH=none|google-id-tokenUsed from runtime 0.1.8; earlier runtimes ignore it. What the server sends OpenFGA besides the preshared key. none (default). google-id-token: also a Google ID token for KINDGI_OPENFGA_API_URL, from the server's own identity, for an OpenFGA on Cloud Run behind IAM; the URL must be https. It goes in X-Serverless-Authorization, which Cloud Run checks in place of Authorization (and passes on without its signature), because Authorization carries the key.
Values
- Read by: the server
- Required: no
- Values:
none,google-id-token - Default:
none
Example
KINDGI_OPENFGA_AUTH=noneSee also
KINDGI_TENANT_ID
Section titled “KINDGI_TENANT_ID”Synopsis
KINDGI_TENANT_ID=<value>Tenant UUID to seed / reuse. Default: fresh UUID printed at boot.
Values
- Read by: the server
- Required: no
- Default: none: a new tenant with a generated UUID is created at each start and printed in the startup banner
Example
KINDGI_TENANT_ID=00000000-0000-4000-8000-000000000001See also
KINDGI_TENANCY
Section titled “KINDGI_TENANCY”Synopsis
KINDGI_TENANCY=single|multiUsed from runtime 0.1.8; earlier runtimes ignore it. How many tenants the runtime serves. single (default): one, KINDGI_TENANT_ID's, as before. multi: many, each created through POST /v1/system/tenants. A request's tenant comes from its key or session, so KINDGI_TENANT_ID is refused, and KINDGI_API_TOKEN acts as the operator (kindgi:system) in no tenant. The first multi boot keeps the existing tenant, with its data, keys and people, as the first of many. multi starts only with all of these: KINDGI_TENANT_HOST_ACCESS=isolated, KINDGI_PACK_ROUTING=per-deployment with KINDGI_PACK_ENDPOINT_HOSTS, KINDGI_OPENFGA_API_URL with KINDGI_OPENFGA_PRESHARED_KEY, KINDGI_PRODUCTION_GATE=on and KINDGI_USAGE_METERING=on. A start that lacks any is refused, naming each.
Values
- Read by: the server
- Required: no
- Values:
single,multi - Default:
single: the runtime serves one tenant,KINDGI_TENANT_ID's
Example
KINDGI_TENANCY=singleSee also
KINDGI_API_TOKEN
Section titled “KINDGI_API_TOKEN”Synopsis
KINDGI_API_TOKEN=<value>Bearer token to seed / reuse. Default: fresh kgi_bt_... token per boot.
Values
- Read by: the server
- Required: no
- Default: none: a new
kgi_bt_token is generated at each start and printed in the startup banner
Example
KINDGI_API_TOKEN=kgi_bt_my_stable_local_tokenSee also
- Security
- Run with authorization
- Deploy on Azure Container Apps
- Back up and restore the runtime's database
KINDGI_SEED_USER_ID
Section titled “KINDGI_SEED_USER_ID”Synopsis
KINDGI_SEED_USER_ID=<value>The user the runtime's API token (KINDGI_API_TOKEN) acts as, made a tenant admin at every boot. Unset: the user that token had at an earlier boot (kept by the token's hash), or a new one the first time a token is used. Set it to keep one user across token changes.
Values
- Read by: the server
- Required: no
- Default: none: the user the token had at an earlier start, else a new user
Example
KINDGI_SEED_USER_ID=00000000-0000-4000-8000-000000000002See also
- Run with authorization
- Deploy on Google Cloud Run
- Operate a self-hosted runtime
- People, API keys and service accounts
KINDGI_DOCS
Section titled “KINDGI_DOCS”Synopsis
KINDGI_DOCS=true|false|1|0Mount /docs (Scalar API reference). true (default) | false.
Values
- Read by: the server
- Required: no
- Values:
true,false,1,0 - Default:
true
Example
KINDGI_DOCS=trueSee also
KINDGI_DEV
Section titled “KINDGI_DEV”Synopsis
KINDGI_DEV=true|false|1|0Development mode: true enables development-only settings (the dotenv secrets backend, KINDGI_PACK_DIR, KINDGI_DEV_CONSOLE_LOGIN, KINDGI_DEV_HOST_ALIAS). The server refuses those settings when this is off. Never set it in production.
Values
- Read by: the server
- Required: no
- Values:
true,false,1,0 - Default:
false
Example
KINDGI_DEV=falseSee also
KINDGI_TENANT_HOST_ACCESS
Section titled “KINDGI_TENANT_HOST_ACCESS”Synopsis
KINDGI_TENANT_HOST_ACCESS=local|deployed|isolatedHow far what tenants register may reach into the server's own host. deployed refuses a stdio MCP endpoint (a command the server would run in its container, as its user) at registration (403 host-access-denied) and at connect; run MCP servers over HTTP instead. It also refuses the server's connections to the cloud metadata endpoints (link-local addresses, and the few that clouds serve outside that range, such as Azure's 168.63.129.16) and to its own host (loopback) when a tenant chose the host: an MCP endpoint, a model provider's base URL, an HTTP tool, an image reference. Private networks stay reachable. isolated is for a server whose tenants don't trust one another: it refuses all that deployed does, plus private networks (RFC 1918, CGNAT 100.64.0.0/10, IPv6 unique-local, IPv6 site-local), and the server's own cloud credentials: a model provider can't sign in as the server (a Gemini provider on Vertex AI needs secret_ref rather than Application Default Credentials, and Azure OpenAI's auth: entra and Bedrock's auth: aws-identity are refused). The server won't start with it and KINDGI_DEV, KINDGI_WEBHOOK_PRIVATE_NETWORKS=allow or KINDGI_AUTH_PRIVATE_IDP_ORIGINS. KINDGI_TENANCY=multi starts only with it. isolated is used from runtime 0.1.8; earlier runtimes refuse it at startup. local allows all of it: only for a machine where every token holder may run commands. Unset: local with KINDGI_DEV, deployed otherwise; a value set here always wins.
Values
- Read by: the server
- Required: no
- Values:
local,deployed,isolated - Default:
localwhenKINDGI_DEVis on, elsedeployed
Example
KINDGI_TENANT_HOST_ACCESS=deployedSee also
KINDGI_WEBHOOK_PRIVATE_NETWORKS
Section titled “KINDGI_WEBHOOK_PRIVATE_NETWORKS”Synopsis
KINDGI_WEBHOOK_PRIVATE_NETWORKS=allow|denyWhether a webhook may go to a private network address: for a receiver on the same VPC or compose network as a self-hosted server. allow accepts a receiver whose host resolves to a private address: RFC 1918, CGNAT (100.64.0.0/10), IPv6 unique-local or IPv6 site-local. Loopback, the cloud metadata endpoints (link-local addresses, and the few that clouds serve elsewhere, some inside CGNAT or IPv6 unique-local) and unroutable addresses stay refused, even with allow, and webhooks stay https only. Unset or deny: public addresses only. Development mode (KINDGI_DEV) allows http and every address anyway. KINDGI_TENANT_HOST_ACCESS=isolated refuses allow.
Values
- Read by: the server
- Required: no
- Values:
allow,deny - Default:
deny
Example
KINDGI_WEBHOOK_PRIVATE_NETWORKS=allowSee also
KINDGI_PRODUCTION_GATE
Section titled “KINDGI_PRODUCTION_GATE”Synopsis
KINDGI_PRODUCTION_GATE=on|offUsed from runtime 0.1.8; earlier runtimes ignore it. Whether putting a project in production needs the tenant to be allowed it, for example once it has paid. on: PUT /v1/projects/{projectId}/production refuses with 403 production-not-allowed while the tenant isn't allowed (its productionAllowed is false, set through the system API); a project already in production stays so. A tenant is allowed unless it's switched off, so turning the gate on keeps existing tenants' production. Unset or off: no gate, and any tenant admin can put a project in production. KINDGI_TENANCY=multi starts only with on.
Values
- Read by: the server
- Required: no
- Values:
on,off - Default:
off: no gate, and any tenant admin can put a project in production
Example
KINDGI_PRODUCTION_GATE=onSee also
KINDGI_PRODUCTION_NEXT_URL
Section titled “KINDGI_PRODUCTION_NEXT_URL”Synopsis
KINDGI_PRODUCTION_NEXT_URL=<value>Used from runtime 0.1.8; earlier runtimes ignore it. Where a tenant goes to put more projects in production, for example a billing page: an https URL. It's the details.next of two refusals: production-not-allowed, for a tenant that isn't allowed to put projects in production, and production-limit-reached, for one at its limit on projects in production. It's also GET /v1/tenant's productionNext while the tenant isn't allowed. Unset: the first refusal says to ask whoever runs the server, and the second to take a project out of production or ask whoever runs the server to raise the limit.
Values
- Read by: the server
- Required: no
- Default: none:
production-not-allowedsays to ask whoever runs the server, andproduction-limit-reachedto take a project out of production or ask whoever runs the server to raise the limit
Example
KINDGI_PRODUCTION_NEXT_URL=https://platform.example.com/account/billingSee also
KINDGI_USAGE_METERING
Section titled “KINDGI_USAGE_METERING”Synopsis
KINDGI_USAGE_METERING=on|offUsed from runtime 0.1.8; earlier runtimes ignore it. Whether the server counts usage. on: it records each run when it's created (with its class: production, staging, dry-run, replay, eval or child) and when it ends, each approval asked for and decided, each model call, and each project put in production or taken out. Each is counted exactly once, in the same transaction as what it counts. /v1/cost/* reads a tenant's own counts. Unset or off: model calls are counted as before, and nothing else. KINDGI_TENANCY=multi starts only with on.
Values
- Read by: the server
- Required: no
- Values:
on,off - Default:
off: model calls are counted, nothing else
Example
KINDGI_USAGE_METERING=onSee also
KINDGI_LICENSE_KEY
Section titled “KINDGI_LICENSE_KEY”Synopsis
KINDGI_LICENSE_KEY=<value>The commercial license key (kgi_lk_...) Kindgi issues: signed, checked offline at startup, with no call to Kindgi. Required outside development mode: without a valid key the server refuses to start, naming this variable. KINDGI_DEV=true needs none. A production key comes with a commercial license; a free non-production key covers staging and CI. A secret: give it from your secrets store.
Values
- Read by: the server
- Required: no
- Default: none: outside development mode the server refuses to start; development mode needs none
Example
KINDGI_LICENSE_KEY=kgi_lk_<payload>.<signature>See also
KINDGI_LICENSE_KEY_REF
Section titled “KINDGI_LICENSE_KEY_REF”Synopsis
KINDGI_LICENSE_KEY_REF=<value>Where this deployment keeps its license key, as kindgi license renew --key names it (gcp:projects/<p>/secrets/<name>, azure:https://<vault>.vault.azure.net/secrets/<name>, aws:<region>:<name>, env-file:<path>#<NAME>). Only the expiry warnings read it, to print the exact renew command; the deployment modules set it. Not the key: the key is KINDGI_LICENSE_KEY.
Values
- Read by: the server
- Required: no
- Default: none: expiry warnings print a placeholder in the renew command
Example
KINDGI_LICENSE_KEY_REF=gcp:projects/acme-prod/secrets/kindgi-license-keySee also
KINDGI_LICENSE_RENEWER_REF
Section titled “KINDGI_LICENSE_RENEWER_REF”Synopsis
KINDGI_LICENSE_RENEWER_REF=<value>Where this deployment keeps its renewer's key, as kindgi license renew --renewer names it. Only the expiry warnings read it, to print the exact renew command; the deployment modules set it.
Values
- Read by: the server
- Required: no
- Default: none: expiry warnings print a placeholder in the renew command
Example
KINDGI_LICENSE_RENEWER_REF=gcp:projects/acme-prod/secrets/kindgi-license-renewerSee also
KINDGI_ENV
Section titled “KINDGI_ENV”Synopsis
KINDGI_ENV=<value>The env this runtime serves. The secrets and env values a tool declares by name (needsSpec.secrets, needsSpec.env) resolve under this env name. Unset: local in development mode (secrets from the .env and .env.local files, env values from /v1/env); otherwise a tool that declares either fails its calls, naming this variable.
Values
- Read by: the server
- Required: no
- Default: none:
localin development mode, else no env (a tool that declares secrets or env values fails its calls)
Example
KINDGI_ENV=productionSee also
KINDGI_PUBLIC_TOKEN_SIGNING_KEY_PATH
Section titled “KINDGI_PUBLIC_TOKEN_SIGNING_KEY_PATH”Synopsis
KINDGI_PUBLIC_TOKEN_SIGNING_KEY_PATH=<value>Absolute path to the Ed25519 private key (PKCS#8 PEM, mode 0600) that signs public run tokens (kgi_pt_…): the short-lived, read-only tokens a browser uses to follow a run. Use a key for this alone (openssl genpkey -algorithm ed25519). Unset: in development mode the server signs with a key generated at startup (tokens end at restart); otherwise public run tokens are off.
Values
- Read by: the server
- Required: no
- Default: none: in development mode a key generated at start; otherwise public run tokens are off
Example
KINDGI_PUBLIC_TOKEN_SIGNING_KEY_PATH=/etc/kindgi/public-token-signing.pemSee also
KINDGI_PUBLIC_TOKEN_SIGNING_KEY
Section titled “KINDGI_PUBLIC_TOKEN_SIGNING_KEY”Synopsis
KINDGI_PUBLIC_TOKEN_SIGNING_KEY=<value>The same key's PEM file, base64 (base64 < key.pem): for platforms that give secrets as environment variables (Cloud Run with Secret Manager), where a key file's mode can't be 0600. Set this or KINDGI_PUBLIC_TOKEN_SIGNING_KEY_PATH, not both.
Values
- Read by: the server
- Required: no
- Default: none: same as
KINDGI_PUBLIC_TOKEN_SIGNING_KEY_PATH(development key, or public run tokens off)
Example
# base64 of an Ed25519 private key in PKCS#8 PEMKINDGI_PUBLIC_TOKEN_SIGNING_KEY="$(openssl genpkey -algorithm ed25519 | base64 | tr -d '\n')"See also
KINDGI_AUTH_SECRET_PATH
Section titled “KINDGI_AUTH_SECRET_PATH”Synopsis
KINDGI_AUTH_SECRET_PATH=<value>Turns on sign-in with identity providers (OIDC, SAML): absolute path to a 32-byte random key (mode 0600) the browser sign-in flow signs its state with (openssl rand 32 > auth-secret). Needs KINDGI_PUBLIC_URL: identity providers send people back there. Unset (with KINDGI_AUTH_SECRET unset too): sign-in is off, and the API takes only API keys.
Values
- Read by: the server
- Required: no
- Default: none (with
KINDGI_AUTH_SECRETunset): sign-in with identity providers is off
Example
KINDGI_AUTH_SECRET_PATH=/etc/kindgi/auth-secretSee also
KINDGI_AUTH_SECRET
Section titled “KINDGI_AUTH_SECRET”Synopsis
KINDGI_AUTH_SECRET=<value>The same key, base64 (base64 < auth-secret): for platforms that give secrets as environment variables (Cloud Run with Secret Manager), where a key file's mode can't be 0600. Set this or KINDGI_AUTH_SECRET_PATH, not both.
Values
- Read by: the server
- Required: no
- Default: none (with
KINDGI_AUTH_SECRET_PATHunset): sign-in with identity providers is off
Example
# 32 random bytes, base64KINDGI_AUTH_SECRET="$(openssl rand -base64 32)"See also
KINDGI_AUTH_PRIVATE_IDP_ORIGINS
Section titled “KINDGI_AUTH_PRIVATE_IDP_ORIGINS”Synopsis
KINDGI_AUTH_PRIVATE_IDP_ORIGINS=<value>Comma-separated origins of identity providers on a private network (a self-hosted Keycloak or AD FS behind a VPN, e.g. https://sso.corp.internal) that tenants may register. Only public HTTPS identity providers are allowed otherwise: a tenant admin can't point the runtime at the deployment's own network. KINDGI_TENANT_HOST_ACCESS=isolated refuses this setting, since every tenant could name a listed origin.
Values
- Read by: the server
- Required: no
- Default: none: none; only public HTTPS identity providers are allowed
Example
KINDGI_AUTH_PRIVATE_IDP_ORIGINS=https://sso.corp.internalSee also
KINDGI_AUTH_VERIFIED_DOMAINS
Section titled “KINDGI_AUTH_VERIFIED_DOMAINS”Synopsis
KINDGI_AUTH_VERIFIED_DOMAINS=<value>Comma-separated domain:tenant pairs (the tenant by id, or by a unique slug): email domains whose sign-in routes to that tenant's identity providers. A runtime that serves one tenant routes that tenant's domains without this. One that serves several routes a domain only once it's listed here: otherwise a tenant could list another company's domain and catch its people. An unlisted domain's people can still use their provider's own sign-in link (kindgi sso providers test prints it). A malformed entry, or a tenant this runtime doesn't serve, stops the runtime at start.
Values
- Read by: the server
- Required: no
- Default: none: none; a runtime serving one tenant routes that tenant's domains without it, one serving several routes no domain
Example
KINDGI_AUTH_VERIFIED_DOMAINS=acme.com:3f8e2c1a-0b7d-4e9a-9c5f-2d1e6b8a7c40See also
KINDGI_AUTH_TENANT_PROVIDERS
Section titled “KINDGI_AUTH_TENANT_PROVIDERS”Synopsis
KINDGI_AUTH_TENANT_PROVIDERS=<value>Whether a tenant's admins may add, change and remove its identity providers: on or off. Default on. off when the operator manages sign-in: then only the deployment's own token (KINDGI_API_TOKEN) can, and a tenant's change answers 403 identity-providers-operator-managed. The providers already there keep signing people in either way, and anyone may still read them.
Values
- Read by: the server
- Required: no
- Default:
on
Example
KINDGI_AUTH_TENANT_PROVIDERS=offSee also
KINDGI_AUTH_GOOGLE_CLIENT_ID
Section titled “KINDGI_AUTH_GOOGLE_CLIENT_ID”Synopsis
KINDGI_AUTH_GOOGLE_CLIENT_ID=<value>Turns on "Continue with Google": the client id of the deployment's own Google app (an OAuth client (Web application)). People who've been added to a workspace sign in with their Google account, by its verified email. The app allows the redirect URI <KINDGI_PUBLIC_URL>/auth/kindgi/social/callback/google. Needs sign-in on (KINDGI_AUTH_SECRET_PATH) and the app's secret (KINDGI_AUTH_GOOGLE_CLIENT_SECRET or …_SECRET_PATH).
Values
- Read by: the server
- Required: no
- Default: none: "Continue with Google" is off
Example
KINDGI_AUTH_GOOGLE_CLIENT_ID=<client id of your Google OAuth app>See also
KINDGI_AUTH_GOOGLE_CLIENT_SECRET
Section titled “KINDGI_AUTH_GOOGLE_CLIENT_SECRET”Synopsis
KINDGI_AUTH_GOOGLE_CLIENT_SECRET=<value>The Google app's client secret, for platforms that give secrets as environment variables. Set this or KINDGI_AUTH_GOOGLE_CLIENT_SECRET_PATH, not both.
Values
- Read by: the server
- Required: no
- Default: none: no secret (the client id then needs
KINDGI_AUTH_GOOGLE_CLIENT_SECRET_PATH)
Example
KINDGI_AUTH_GOOGLE_CLIENT_SECRET=<client secret of your Google OAuth app>See also
KINDGI_AUTH_GOOGLE_CLIENT_SECRET_PATH
Section titled “KINDGI_AUTH_GOOGLE_CLIENT_SECRET_PATH”Synopsis
KINDGI_AUTH_GOOGLE_CLIENT_SECRET_PATH=<value>A file (mode 0600) holding the Google app's client secret. Set this or KINDGI_AUTH_GOOGLE_CLIENT_SECRET, not both.
Values
- Read by: the server
- Required: no
- Default: none: no secret file
Example
KINDGI_AUTH_GOOGLE_CLIENT_SECRET_PATH=/etc/kindgi/google-client-secretSee also
KINDGI_AUTH_MICROSOFT_CLIENT_ID
Section titled “KINDGI_AUTH_MICROSOFT_CLIENT_ID”Synopsis
KINDGI_AUTH_MICROSOFT_CLIENT_ID=<value>Turns on "Continue with Microsoft": the client id of the deployment's own Microsoft app (an app registration (multitenant, with the ID-token optional claims email and xms_edov)). People who've been added to a workspace sign in with their Microsoft account, by its verified email. The app allows the redirect URI <KINDGI_PUBLIC_URL>/auth/kindgi/social/callback/microsoft. Needs sign-in on (KINDGI_AUTH_SECRET_PATH) and the app's secret (KINDGI_AUTH_MICROSOFT_CLIENT_SECRET or …_SECRET_PATH).
Values
- Read by: the server
- Required: no
- Default: none: "Continue with Microsoft" is off
Example
KINDGI_AUTH_MICROSOFT_CLIENT_ID=<application id of your Microsoft app>See also
KINDGI_AUTH_MICROSOFT_CLIENT_SECRET
Section titled “KINDGI_AUTH_MICROSOFT_CLIENT_SECRET”Synopsis
KINDGI_AUTH_MICROSOFT_CLIENT_SECRET=<value>The Microsoft app's client secret, for platforms that give secrets as environment variables. Set this or KINDGI_AUTH_MICROSOFT_CLIENT_SECRET_PATH, not both.
Values
- Read by: the server
- Required: no
- Default: none: no secret (the client id then needs
KINDGI_AUTH_MICROSOFT_CLIENT_SECRET_PATH)
Example
KINDGI_AUTH_MICROSOFT_CLIENT_SECRET=<client secret of your Microsoft app>See also
KINDGI_AUTH_MICROSOFT_CLIENT_SECRET_PATH
Section titled “KINDGI_AUTH_MICROSOFT_CLIENT_SECRET_PATH”Synopsis
KINDGI_AUTH_MICROSOFT_CLIENT_SECRET_PATH=<value>A file (mode 0600) holding the Microsoft app's client secret. Set this or KINDGI_AUTH_MICROSOFT_CLIENT_SECRET, not both.
Values
- Read by: the server
- Required: no
- Default: none: no secret file
Example
KINDGI_AUTH_MICROSOFT_CLIENT_SECRET_PATH=/etc/kindgi/microsoft-client-secretSee also
KINDGI_AUTH_GITHUB_CLIENT_ID
Section titled “KINDGI_AUTH_GITHUB_CLIENT_ID”Synopsis
KINDGI_AUTH_GITHUB_CLIENT_ID=<value>Turns on "Continue with GitHub": the client id of the deployment's own GitHub app (an OAuth App). People who've been added to a workspace sign in with their GitHub account, by its verified email. The app allows the redirect URI <KINDGI_PUBLIC_URL>/auth/kindgi/social/callback/github. Needs sign-in on (KINDGI_AUTH_SECRET_PATH) and the app's secret (KINDGI_AUTH_GITHUB_CLIENT_SECRET or …_SECRET_PATH).
Values
- Read by: the server
- Required: no
- Default: none: "Continue with GitHub" is off
Example
KINDGI_AUTH_GITHUB_CLIENT_ID=<client id of your GitHub OAuth app>See also
KINDGI_AUTH_GITHUB_CLIENT_SECRET
Section titled “KINDGI_AUTH_GITHUB_CLIENT_SECRET”Synopsis
KINDGI_AUTH_GITHUB_CLIENT_SECRET=<value>The GitHub app's client secret, for platforms that give secrets as environment variables. Set this or KINDGI_AUTH_GITHUB_CLIENT_SECRET_PATH, not both.
Values
- Read by: the server
- Required: no
- Default: none: no secret (the client id then needs
KINDGI_AUTH_GITHUB_CLIENT_SECRET_PATH)
Example
KINDGI_AUTH_GITHUB_CLIENT_SECRET=<client secret of your GitHub OAuth app>See also
KINDGI_AUTH_GITHUB_CLIENT_SECRET_PATH
Section titled “KINDGI_AUTH_GITHUB_CLIENT_SECRET_PATH”Synopsis
KINDGI_AUTH_GITHUB_CLIENT_SECRET_PATH=<value>A file (mode 0600) holding the GitHub app's client secret. Set this or KINDGI_AUTH_GITHUB_CLIENT_SECRET, not both.
Values
- Read by: the server
- Required: no
- Default: none: no secret file
Example
KINDGI_AUTH_GITHUB_CLIENT_SECRET_PATH=/etc/kindgi/github-client-secretSee also
KINDGI_AUTH_EMAIL_SMTP_URL
Section titled “KINDGI_AUTH_EMAIL_SMTP_URL”Synopsis
KINDGI_AUTH_EMAIL_SMTP_URL=<value>Turns on the emailed sign-in link: people who've been added to a workspace can ask for a one-time link (ten minutes) by email. The SMTP server to send it through, with its credentials: smtps://user:password@smtp.example.com:465. Any provider works (Resend, Postmark, Amazon SES, your own relay). Needs sign-in on (KINDGI_AUTH_SECRET_PATH) and KINDGI_AUTH_EMAIL_FROM. Set this or KINDGI_AUTH_EMAIL_SMTP_URL_PATH, not both.
Values
- Read by: the server
- Required: no
- Default: none (with
KINDGI_AUTH_EMAIL_SMTP_URL_PATHunset): the emailed sign-in link is off
Example
KINDGI_AUTH_EMAIL_SMTP_URL=smtps://<user>:<password>@smtp.example.com:465See also
KINDGI_AUTH_EMAIL_SMTP_URL_PATH
Section titled “KINDGI_AUTH_EMAIL_SMTP_URL_PATH”Synopsis
KINDGI_AUTH_EMAIL_SMTP_URL_PATH=<value>A file (mode 0600) holding the SMTP URL with its credentials. Set this or KINDGI_AUTH_EMAIL_SMTP_URL, not both.
Values
- Read by: the server
- Required: no
- Default: none: no SMTP URL file
Example
KINDGI_AUTH_EMAIL_SMTP_URL_PATH=/etc/kindgi/smtp-urlSee also
KINDGI_REVIEWER_EMAIL
Section titled “KINDGI_REVIEWER_EMAIL”Synopsis
KINDGI_REVIEWER_EMAIL=<value>on emails reviewers when an approval waits for them: the people the approvals inbox would show it to (its assigned reviewer, else every active reviewer of its required role or above), and only those who may read its project. The first email goes at once; anything more for the same person within five minutes comes as one digest. Each email has the approval's title, project, required role and a link, never what it's about (that stays behind sign-in). Sent through the emailed sign-in link's server, so it needs KINDGI_AUTH_EMAIL_SMTP_URL (or _PATH) and KINDGI_AUTH_EMAIL_FROM; turned on without them, the runtime refuses to start. Off by default: emailing people is the operator's choice.
Values
- Read by: the server
- Required: no
- Default:
off
Example
KINDGI_REVIEWER_EMAIL=onSee also
KINDGI_AUTH_EMAIL_FROM
Section titled “KINDGI_AUTH_EMAIL_FROM”Synopsis
KINDGI_AUTH_EMAIL_FROM=<value>The emailed sign-in link's From address, on a domain your SMTP provider may send for (SPF and DKIM set up): Kindgi <sign-in@acme.com>.
Values
- Read by: the server
- Required: no
- Default: none: the emailed sign-in link is off (required with the SMTP URL)
Example
KINDGI_AUTH_EMAIL_FROM=Kindgi <sign-in@acme.com>See also
KINDGI_AUTH_EMAIL_LINK_DAILY_CAP
Section titled “KINDGI_AUTH_EMAIL_LINK_DAILY_CAP”Synopsis
KINDGI_AUTH_EMAIL_LINK_DAILY_CAP=<value>The emailed sign-in link's backstop: at most this many links a day to one address from one client network (IPv4 /24, IPv6 /64). Default 20. Before it: one a minute and 3 per 15 minutes to an address, except for the browser that already got a link for it, so someone else's requests can't keep its person out. At a limit the request answers as usual, and nothing is sent.
Values
- Read by: the server
- Required: no
- Default:
20links a day (a whole number from 1 to 1000)
Example
KINDGI_AUTH_EMAIL_LINK_DAILY_CAP=20See also
KINDGI_AUTH_TURNSTILE_SECRET
Section titled “KINDGI_AUTH_TURNSTILE_SECRET”Synopsis
KINDGI_AUTH_TURNSTILE_SECRET=<value>A Cloudflare Turnstile secret key: asking for an emailed link then needs the widget's token, checked with Cloudflare. Required when the runtime serves several tenants. Without it (one tenant), the link is still sent only to people who can sign in, within the per-address limits (see KINDGI_AUTH_EMAIL_LINK_DAILY_CAP), and requests are rate-limited per client. Set this or KINDGI_AUTH_TURNSTILE_SECRET_PATH, not both, with KINDGI_AUTH_TURNSTILE_SITE_KEY.
Values
- Read by: the server
- Required: no
- Default: none (with
KINDGI_AUTH_TURNSTILE_SECRET_PATHunset): no Turnstile check on emailed-link requests
Example
KINDGI_AUTH_TURNSTILE_SECRET=<Cloudflare Turnstile secret key>See also
KINDGI_AUTH_TURNSTILE_SECRET_PATH
Section titled “KINDGI_AUTH_TURNSTILE_SECRET_PATH”Synopsis
KINDGI_AUTH_TURNSTILE_SECRET_PATH=<value>A file (mode 0600) holding the Turnstile secret key. Set this or KINDGI_AUTH_TURNSTILE_SECRET, not both.
Values
- Read by: the server
- Required: no
- Default: none: no Turnstile secret file
Example
KINDGI_AUTH_TURNSTILE_SECRET_PATH=/etc/kindgi/turnstile-secretSee also
KINDGI_AUTH_TURNSTILE_SITE_KEY
Section titled “KINDGI_AUTH_TURNSTILE_SITE_KEY”Synopsis
KINDGI_AUTH_TURNSTILE_SITE_KEY=<value>The Turnstile site key the sign-in page shows the widget with (public). Set with the secret.
Values
- Read by: the server
- Required: no
- Default: none: no Turnstile widget
Example
KINDGI_AUTH_TURNSTILE_SITE_KEY=<Cloudflare Turnstile site key>See also
KINDGI_TRUSTED_PROXIES
Section titled “KINDGI_TRUSTED_PROXIES”Synopsis
KINDGI_TRUSTED_PROXIES=<value>Which proxies in front of the runtime to trust for the client's address, which rate limits and audit records use. Unset: the connection's peer, and X-Forwarded-For is ignored (anyone can send it). A hop count (1 behind one proxy such as a cloud load balancer or ingress, 2 behind two) or comma-separated IPs/CIDR ranges of your proxies: the client is the first X-Forwarded-For hop, from the right, that isn't one of them; never the leftmost on its own. Behind a proxy without this, every client counts as the proxy, so rate limits are shared by everyone.
Values
- Read by: the server
- Required: no
- Default: none: no trusted proxies; the connection's peer is the client address and
X-Forwarded-Foris ignored
Example
KINDGI_TRUSTED_PROXIES=1See also
KINDGI_SESSION_TTL_MS
Section titled “KINDGI_SESSION_TTL_MS”Synopsis
KINDGI_SESSION_TTL_MS=<value>A browser session's absolute lifetime, in milliseconds: the person signs in again after it. Default 43200000 (12 hours); at least 60000.
Values
- Read by: the server
- Required: no
- Default:
43200000(12 hours); at least60000
Example
KINDGI_SESSION_TTL_MS=43200000See also
KINDGI_SESSION_IDLE_TIMEOUT_MS
Section titled “KINDGI_SESSION_IDLE_TIMEOUT_MS”Synopsis
KINDGI_SESSION_IDLE_TIMEOUT_MS=<value>How long a browser session may sit idle before it ends, in milliseconds. Default 3600000 (60 minutes); at least 60000, and no longer than KINDGI_SESSION_TTL_MS.
Values
- Read by: the server
- Required: no
- Default:
3600000(60 minutes); at least60000, at most the session lifetime
Example
KINDGI_SESSION_IDLE_TIMEOUT_MS=3600000See also
KINDGI_CONSOLE_TOKEN_SIGN_IN
Section titled “KINDGI_CONSOLE_TOKEN_SIGN_IN”Synopsis
KINDGI_CONSOLE_TOKEN_SIGN_IN=<value>Whether a person may sign in to the console with an API token: on or off. Default off, and on in local development (kindgi dev). The token is exchanged once for a browser session (the same cookie as sign-in with an identity provider) and never kept in the browser. Only a person's full key opens a session, never a service account's or a narrowed key. API tokens work for the API, CLI and SDKs either way. Set on to keep signing in to the console by pasting a token when it has no identity provider.
Values
- Read by: the server
- Required: no
- Default:
off, andonwhenKINDGI_DEVis on
Example
KINDGI_CONSOLE_TOKEN_SIGN_IN=onSee also
KINDGI_EXPORT_SIGNING_KEY_PATH
Section titled “KINDGI_EXPORT_SIGNING_KEY_PATH”Synopsis
KINDGI_EXPORT_SIGNING_KEY_PATH=<value>Absolute path to the private key (PKCS#8 PEM, mode 0600) that signs exports: approval audit bundles, run provenance and compliance evidence. An Ed25519 key signs ed25519 (openssl genpkey -algorithm ed25519); an EC P-256 key signs ecdsa-p256-sha256. Use a key for this alone; GET /v1/export-signing-keys publishes its public half. Set one of this, KINDGI_EXPORT_SIGNING_KEY or KINDGI_EXPORT_SIGNING_KMS_KEY. None: in development mode the server signs with a key generated at startup; otherwise exports answer 404 signing-not-configured.
Values
- Read by: the server
- Required: no
- Default: none (with the other two export key variables unset): in development mode a key generated at start; otherwise exports answer
404 signing-not-configured
Example
KINDGI_EXPORT_SIGNING_KEY_PATH=/etc/kindgi/export-signing.pemSee also
KINDGI_EXPORT_SIGNING_KEY
Section titled “KINDGI_EXPORT_SIGNING_KEY”Synopsis
KINDGI_EXPORT_SIGNING_KEY=<value>The same key's PEM file, base64 (base64 < key.pem): for platforms that give secrets as environment variables, such as Cloud Run with Secret Manager. A production path in its own right.
Values
- Read by: the server
- Required: no
- Default: none: same as
KINDGI_EXPORT_SIGNING_KEY_PATH
Example
# base64 of an Ed25519 or EC P-256 private key in PKCS#8 PEMKINDGI_EXPORT_SIGNING_KEY="$(openssl genpkey -algorithm ed25519 | base64 | tr -d '\n')"See also
KINDGI_EXPORT_SIGNING_KMS_KEY
Section titled “KINDGI_EXPORT_SIGNING_KMS_KEY”Synopsis
KINDGI_EXPORT_SIGNING_KMS_KEY=<value>Optional: a KMS key version that signs exports, so the private key never leaves the KMS. Its shape picks the KMS. Cloud KMS: projects/<p>/locations/<l>/keyRings/<r>/cryptoKeys/<k>/cryptoKeyVersions/<n>, an EC_SIGN_ED25519 key (it signs ed25519) or an EC_SIGN_P256_SHA256 key (ecdsa-p256-sha256); the server's service account needs roles/cloudkms.signerVerifier on it (and roles/cloudkms.publicKeyViewer, to read its public key at boot). Azure Key Vault: https://<vault>.vault.azure.net/keys/<name>/<version>, with its version, an EC P-256 key allowed to sign (ecdsa-p256-sha256: Key Vault has no Ed25519); the server's identity needs Key Vault Crypto User on it. Any other value stops the server at boot, naming both shapes.
Values
- Read by: the server
- Required: no
- Default: none: the export key comes from
KINDGI_EXPORT_SIGNING_KEY_PATHorKINDGI_EXPORT_SIGNING_KEY
Example
KINDGI_EXPORT_SIGNING_KMS_KEY=projects/acme/locations/global/keyRings/kindgi/cryptoKeys/exports/cryptoKeyVersions/1See also
KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS_PATH
Section titled “KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS_PATH”Synopsis
KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS_PATH=<value>Absolute path to a file of one or more PEM public keys (-----BEGIN PUBLIC KEY-----, concatenated): export keys this deployment signed with before a rotation. GET /v1/export-signing-keys lists them after the active key, with active: false, so kindgi exports verify --from-runtime still trusts what they signed; they never sign. Ed25519 or EC P-256 keys, public halves only: a private key in the file stops the server at boot. Works with any signing key, file or KMS. Set this or KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS, not both.
Values
- Read by: the server
- Required: no
- Default: none: no retired export keys are listed
Example
KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS_PATH=/etc/kindgi/export-signing-retired.pemSee also
KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS
Section titled “KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS”Synopsis
KINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS=<value>The same file's content, base64 (base64 < retired.pem): for platforms that give settings as environment variables, such as Cloud Run.
Values
- Read by: the server
- Required: no
- Default: none: no retired export keys are listed
Example
# base64 of a file of PEM public keysKINDGI_EXPORT_SIGNING_RETIRED_PUBLIC_KEYS="$(openssl pkey -in old-key.pem -pubout | base64 | tr -d '\n')"See also
KINDGI_CORS_ORIGINS
Section titled “KINDGI_CORS_ORIGINS”Synopsis
KINDGI_CORS_ORIGINS=<value>Comma-separated browser origins allowed to call, cross-origin, the routes a public run token can use (GET /v1/runs/{runId}/progress and its stream). Exact origins, no wildcards. Unset: no CORS headers on any route.
Values
- Read by: the server
- Required: no
- Default: none: no CORS headers on any route
Example
KINDGI_CORS_ORIGINS=https://app.example.comSee also
KINDGI_RUN_LEASE_MS
Section titled “KINDGI_RUN_LEASE_MS”Synopsis
KINDGI_RUN_LEASE_MS=<value>How long a run's executor lease lasts without renewal, in milliseconds. Every unfinished run and every running eval run holds one, renewed every quarter of this by the server executing it. When a server stops without a shutdown (killed, out of memory, a crash), their leases run out, and a server's sweep fails them: a run sending run.finished, an eval run ending failed, interrupted, with its finished cases kept. Default 300000 (5 minutes); at least 10000, or the server refuses to start. A shorter lease finds such runs sooner, at the cost of more renewals.
Values
- Read by: the server
- Required: no
- Default:
300000(5 minutes); at least10000
Example
KINDGI_RUN_LEASE_MS=300000See also
KINDGI_RUN_SWEEP_INTERVAL_MS
Section titled “KINDGI_RUN_SWEEP_INTERVAL_MS”Synopsis
KINDGI_RUN_SWEEP_INTERVAL_MS=<value>How often each server sweeps for runs and eval runs whose executor lease ran out, in milliseconds. A run or eval run whose server stopped without a shutdown is failed within about KINDGI_RUN_LEASE_MS plus this. Default 60000; at least 1000, and shorter than KINDGI_RUN_LEASE_MS, or the server refuses to start.
Values
- Read by: the server
- Required: no
- Default:
60000(1 minute); at least1000, shorter than the lease
Example
KINDGI_RUN_SWEEP_INTERVAL_MS=60000See also
KINDGI_RUN_ENDED_CHECK_MS
Section titled “KINDGI_RUN_ENDED_CHECK_MS”Synopsis
KINDGI_RUN_ENDED_CHECK_MS=<value>How often each server stops the runs it executes that were ended from outside (cancelled, on this server or another), in milliseconds. A run stops starting steps at its next write either way; this also stops a step that writes nothing for a while, such as a long model call, within this time of a cancel. Default 5000; at least 1000, or the server refuses to start.
Values
- Read by: the server
- Required: no
- Default:
5000(5 seconds); at least1000
Example
KINDGI_RUN_ENDED_CHECK_MS=5000See also
KINDGI_MEMORY_EMBEDDINGS
Section titled “KINDGI_MEMORY_EMBEDDINGS”Synopsis
KINDGI_MEMORY_EMBEDDINGS=<value>Turns on memory search by meaning, with the embedding provider: openai-compat, an embeddings endpoint that speaks OpenAI's POST /embeddings (OpenAI, Ollama, vLLM, Hugging Face TEI, LM Studio; set KINDGI_MEMORY_EMBEDDINGS_URL and KINDGI_MEMORY_EMBEDDINGS_MODEL), or local:<model>, a model run inside the server (bge-small-en-v1.5, nomic-embed-text-v1.5 or mxbai-embed-large-v1; only for a server run from source on macOS or glibc Linux: the runtime image can't load it, and the server refuses to start there). Facts are embedded when written, and a background job embeds the ones already there; agents' semantic and both retrieval and /v1/memory/retrieve then search by meaning. Unset (the default): keyword search only; a semantic intent fails its turn with semantic-unavailable, both runs its keyword half, and publishing such an agent warns. An endpoint that doesn't answer yet doesn't stop the server: it is retried in the background (its first answer gives the dimensions), search by meaning waits for it (semantic-unavailable meanwhile, writes kept without a vector until then), and /ready says memoryEmbeddings: unavailable (retrying).
Values
- Read by: the server
- Required: no
- Default: none: memory search by keyword only
Example
KINDGI_MEMORY_EMBEDDINGS=openai-compatSee also
KINDGI_MEMORY_EMBEDDINGS_URL
Section titled “KINDGI_MEMORY_EMBEDDINGS_URL”Synopsis
KINDGI_MEMORY_EMBEDDINGS_URL=<value>With KINDGI_MEMORY_EMBEDDINGS=openai-compat: the endpoint's base URL, with its /v1 (http://localhost:11434/v1 for Ollama, https://api.openai.com/v1). Required then.
Values
- Read by: the server
- Required: no
- Default: none: required when
KINDGI_MEMORY_EMBEDDINGS=openai-compat, not read otherwise
Example
KINDGI_MEMORY_EMBEDDINGS_URL=http://localhost:11434/v1See also
KINDGI_MEMORY_EMBEDDINGS_MODEL
Section titled “KINDGI_MEMORY_EMBEDDINGS_MODEL”Synopsis
KINDGI_MEMORY_EMBEDDINGS_MODEL=<value>With KINDGI_MEMORY_EMBEDDINGS=openai-compat: the embedding model the endpoint serves (nomic-embed-text, text-embedding-3-small). Required then. A different model means a new vector space: the background job re-embeds every fact in it.
Values
- Read by: the server
- Required: no
- Default: none: required when
KINDGI_MEMORY_EMBEDDINGS=openai-compat, not read otherwise
Example
KINDGI_MEMORY_EMBEDDINGS_MODEL=nomic-embed-textSee also
KINDGI_MEMORY_EMBEDDINGS_API_KEY
Section titled “KINDGI_MEMORY_EMBEDDINGS_API_KEY”Synopsis
KINDGI_MEMORY_EMBEDDINGS_API_KEY=<value>With KINDGI_MEMORY_EMBEDDINGS=openai-compat: the endpoint's key, mapped into the environment from your secret store; Kindgi never stores it. Optional: Ollama and a local TEI take none.
Values
- Read by: the server
- Required: no
- Default: none: requests carry no key
Example
KINDGI_MEMORY_EMBEDDINGS_API_KEY=<API key of the embeddings endpoint>See also
KINDGI_RETENTION_SWEEP_INTERVAL_MS
Section titled “KINDGI_RETENTION_SWEEP_INTERVAL_MS”Synopsis
KINDGI_RETENTION_SWEEP_INTERVAL_MS=<value>How often the server purges deleted rows on its own, in milliseconds: in every tenant it serves, it purges for good the tombstones past their retention policy's grace, as POST /v1/retention/sweep does, holds (graceSeconds: -1) kept, and logs what it purged. Memory facts and conversations purge only under a policy naming their domain (memory, conversation), never under a * policy. Unset (the default): nothing purges on its own; sweep with POST /v1/retention/sweep or the console. At least 60000, or the server refuses to start.
Values
- Read by: the server
- Required: no
- Default: none: no automatic purge; at least
60000when set
Example
KINDGI_RETENTION_SWEEP_INTERVAL_MS=3600000See also
KINDGI_ERASURE_SHARED_WAIT_MS
Section titled “KINDGI_ERASURE_SHARED_WAIT_MS”Synopsis
KINDGI_ERASURE_SHARED_WAIT_MS=<value>How long an erasure waits for a turn of the person's that sits in a flow serving other people (cancelling it now could end their work), in milliseconds. The erasure shows waiting-on-run, naming the run, until then; at the deadline it cancels the run and goes on, and a tenant admin can stop the wait sooner (kindgi memory erasures resume <id> --force). Default 604800000 (7 days).
Values
- Read by: the server
- Required: no
- Default:
604800000(7 days); at least3600000
Example
KINDGI_ERASURE_SHARED_WAIT_MS=604800000See also
KINDGI_ERASURE_LEDGER_KEY_PATH
Section titled “KINDGI_ERASURE_LEDGER_KEY_PATH”Synopsis
KINDGI_ERASURE_LEDGER_KEY_PATH=<value>Absolute path to the erasure ledger's 32-byte key file (mode 0600), the same on every replica, whatever the secrets backend. The ledger keeps a keyed hash of whom each erasure erased, so after a backup restore kindgi memory erasures replay finds them again. Unset (and no KINDGI_ERASURE_LEDGER_KEY): erasures still run, but can't be replayed after a restore. Losing the key means losing replay. This or KINDGI_ERASURE_LEDGER_KEY, not both.
Values
- Read by: the server
- Required: no
- Default: none (with
KINDGI_ERASURE_LEDGER_KEYunset): erasures run but cannot be replayed after a restore
Example
KINDGI_ERASURE_LEDGER_KEY_PATH=/etc/kindgi/erasure-ledger.keySee also
KINDGI_ERASURE_LEDGER_KEY
Section titled “KINDGI_ERASURE_LEDGER_KEY”Synopsis
KINDGI_ERASURE_LEDGER_KEY=<value>The erasure ledger's 32-byte key itself, base64: for platforms that give secrets as environment variables (Cloud Run with Secret Manager), where a key file's mode can't be 0600. See KINDGI_ERASURE_LEDGER_KEY_PATH; this or that, not both.
Values
- Read by: the server
- Required: no
- Default: none: same as
KINDGI_ERASURE_LEDGER_KEY_PATH
Example
# 32 random bytes, base64KINDGI_ERASURE_LEDGER_KEY="$(openssl rand -base64 32)"See also
KINDGI_ERASURE_LEDGER_EXPORT
Section titled “KINDGI_ERASURE_LEDGER_EXPORT”Synopsis
KINDGI_ERASURE_LEDGER_EXPORT=<value>Where the server keeps copies of the erasure ledger, off the database, so erasures can be replayed after a backup restore: local:<absolute dir> or gcs:<bucket>[/<prefix>] (Application Default Credentials; creating objects is all it needs). On an interval (KINDGI_ERASURE_LEDGER_EXPORT_INTERVAL_MS) it writes the ledger of every tenant it serves as one file (keyed hashes only, never whom an erasure names), as kindgi memory erasures export does for one tenant: a new file when the ledger changed, and at least one a day. It never overwrites or deletes one; keep them longer than your backups. Replay the newest after a restore with kindgi-runtime erasures replay. Unset (the default): the ledger stays in the database only.
Values
- Read by: the server
- Required: no
- Default: none: the ledger stays in the database only
Example
KINDGI_ERASURE_LEDGER_EXPORT=gcs:acme-erasure-ledger/runtimeSee also
KINDGI_ERASURE_LEDGER_EXPORT_INTERVAL_MS
Section titled “KINDGI_ERASURE_LEDGER_EXPORT_INTERVAL_MS”Synopsis
KINDGI_ERASURE_LEDGER_EXPORT_INTERVAL_MS=<value>How often the server writes the erasure ledger to KINDGI_ERASURE_LEDGER_EXPORT, in milliseconds. An erasure made after the last copy and after the restore point is in neither, so this bounds what a restore can miss. Default 3600000 (an hour). At least 60000, and needs KINDGI_ERASURE_LEDGER_EXPORT, or the server refuses to start.
Values
- Read by: the server
- Required: no
- Default:
3600000(an hour); at least60000
Example
KINDGI_ERASURE_LEDGER_EXPORT_INTERVAL_MS=900000See also
KINDGI_PASSIVE
Section titled “KINDGI_PASSIVE”Synopsis
KINDGI_PASSIVE=<value>on boots a server that does nothing on its own, for looking at a restored backup before anyone uses it: none of its background work starts (runs, schedules and event triggers, webhook deliveries, sending permission changes to OpenFGA, the sweeps, erasures and the erasure ledger export), and it sends no email. Requests are served as usual, and a run started through the API still runs (in the server that took the request), so keep a passive server where only you can reach it. The startup output and /ready say it's passive. Off by default.
Values
- Read by: the server
- Required: no
- Default:
off
Example
KINDGI_PASSIVE=onSee also
KINDGI_PAGINATION_KEY_PATH
Section titled “KINDGI_PAGINATION_KEY_PATH”Synopsis
KINDGI_PAGINATION_KEY_PATH=<value>Absolute path to the 32-byte key (mode 0600) every list's page cursors are sealed with, so a cursor never shows the row it points after; the same on every instance. Unset (and no KINDGI_PAGINATION_KEY): a key made at boot and kept nowhere, so a cursor handed out before a restart answers 400 after it, and more than one instance behind one address needs the key set. Rotate it yearly (each cursor is sealed with a random nonce): the new key here, the old one in KINDGI_PAGINATION_PREVIOUS_KEY_PATH for at least a day. Its own key: never the erasure ledger's or the secrets AAD key. This or KINDGI_PAGINATION_KEY, not both.
Values
- Read by: the server
- Required: no
- Default: none (with
KINDGI_PAGINATION_KEYunset): a random key made at start and kept nowhere
Example
KINDGI_PAGINATION_KEY_PATH=/etc/kindgi/pagination.keySee also
KINDGI_PAGINATION_KEY
Section titled “KINDGI_PAGINATION_KEY”Synopsis
KINDGI_PAGINATION_KEY=<value>The page-cursor key itself, base64: for platforms that give secrets as environment variables (Cloud Run with Secret Manager). See KINDGI_PAGINATION_KEY_PATH; this or that, not both.
Values
- Read by: the server
- Required: no
- Default: none: same as
KINDGI_PAGINATION_KEY_PATH
Example
# 32 random bytes, base64KINDGI_PAGINATION_KEY="$(openssl rand -base64 32)"See also
KINDGI_PAGINATION_PREVIOUS_KEY_PATH
Section titled “KINDGI_PAGINATION_PREVIOUS_KEY_PATH”Synopsis
KINDGI_PAGINATION_PREVIOUS_KEY_PATH=<value>While the page-cursor key rotates, the key before it (a 32-byte file, mode 0600): it still opens the cursors it sealed. Keep it at least a day (a cursor's life) after rotating, then remove it. Needs KINDGI_PAGINATION_KEY(_PATH), and must differ from it. This or KINDGI_PAGINATION_PREVIOUS_KEY, not both.
Values
- Read by: the server
- Required: no
- Default: none: no previous key
Example
KINDGI_PAGINATION_PREVIOUS_KEY_PATH=/etc/kindgi/pagination.previous.keySee also
KINDGI_PAGINATION_PREVIOUS_KEY
Section titled “KINDGI_PAGINATION_PREVIOUS_KEY”Synopsis
KINDGI_PAGINATION_PREVIOUS_KEY=<value>The previous page-cursor key itself, base64. See KINDGI_PAGINATION_PREVIOUS_KEY_PATH; this or that, not both.
Values
- Read by: the server
- Required: no
- Default: none: no previous key
Example
KINDGI_PAGINATION_PREVIOUS_KEY=<the KINDGI_PAGINATION_KEY value before the rotation>See also
KINDGI_COMPLIANCE_CLASSIFIER
Section titled “KINDGI_COMPLIANCE_CLASSIFIER”Synopsis
KINDGI_COMPLIANCE_CLASSIFIER=<value>Turns on the audit trail's compliance features: shipped uses the classifier the runtime ships; or give the absolute path of your own classifier JSON. When set, the server serves /v1/compliance/* (audit events as compliance evidence, and their signed export) and purges audit events by kind, as the classifier says. With shipped: authorization decisions after 90 days (denials after 365), run outcomes and guardrail violations after 730 days; secret changes and approval decisions are kept (legal hold), and so are kinds the classifier doesn't list. Unset (the default): no /v1/compliance/*, and no audit event is ever purged.
Values
- Read by: the server
- Required: no
- Default: none: no compliance routes, and no audit event is purged
Example
KINDGI_COMPLIANCE_CLASSIFIER=shippedSee also
KINDGI_ARTIFACTS
Section titled “KINDGI_ARTIFACTS”Synopsis
KINDGI_ARTIFACTS=<value>Where artifacts' files go, which turns on /v1/artifacts: local:<absolute dir> (a directory on this machine) or gcs:<bucket>[/<prefix>] (a Google Cloud Storage bucket, through Application Default Credentials: workload identity on GCP, no keys to store). Metadata is in Postgres; a deleted artifact is purged under the artifact retention policy. Unset (the default): no /v1/artifacts. kindgi dev sets it to the pack's .kindgi/dev/artifacts.
Values
- Read by: the server
- Required: no
- Default: none: artifacts are off (no
/v1/artifacts)
Example
KINDGI_ARTIFACTS=gcs:acme-artifacts/prodSee also
KINDGI_ARTIFACT_MAX_BYTES
Section titled “KINDGI_ARTIFACT_MAX_BYTES”Synopsis
KINDGI_ARTIFACT_MAX_BYTES=<value>The most bytes one artifact upload may carry, the whole request body; more is 413 artifact-too-large. Default 104857600 (100 MiB).
Values
- Read by: the server
- Required: no
- Default:
104857600(100 MiB)
Example
KINDGI_ARTIFACT_MAX_BYTES=104857600See also
KINDGI_TURN_MEMORY_MIB
Section titled “KINDGI_TURN_MEMORY_MIB”Synopsis
KINDGI_TURN_MEMORY_MIB=<value>Used from runtime 0.1.8; earlier runtimes ignore it. The most memory, in MiB, that every tenant's running agent turns may hold together. A turn is charged by size before each model call: (4 + the iterations it has done) × its conversation as sent, plus a resumed run's journal. Past the limit, the turn fails with 429 turn-memory-limit-reached (limit: server). Unset: no limit. Kindgi Cloud sets 384.
Values
- Read by: the server
- Required: no
- Default: none: no limit on every tenant's turns together
Example
KINDGI_TURN_MEMORY_MIB=384See also
KINDGI_TURN_MEMORY_PER_TENANT_MIB
Section titled “KINDGI_TURN_MEMORY_PER_TENANT_MIB”Synopsis
KINDGI_TURN_MEMORY_PER_TENANT_MIB=<value>Used from runtime 0.1.8; earlier runtimes ignore it. The most memory, in MiB, that one tenant's running agent turns may hold, charged as for KINDGI_TURN_MEMORY_MIB. Past it, the turn fails with 429 turn-memory-limit-reached (limit: tenant), and a resume whose journal alone is bigger fails at once. Unset: no limit per tenant. Kindgi Cloud sets 192.
Values
- Read by: the server
- Required: no
- Default: none: no limit per tenant
Example
KINDGI_TURN_MEMORY_PER_TENANT_MIB=192See also
Logging
Section titled “Logging”KINDGI_LOG_LEVEL
Section titled “KINDGI_LOG_LEVEL”Synopsis
KINDGI_LOG_LEVEL=error|warn|info|debug|traceThe lowest level written: error, warn, info (default), debug or trace. At info an idle runtime writes nothing after its boot record but background work that did something. An unknown level stops the server at boot, naming this variable (exit code 2).
Values
- Read by: the server
- Required: no
- Values:
error,warn,info,debug,trace - Default:
info
Example
KINDGI_LOG_LEVEL=infoSee also
KINDGI_LOG_LEVELS
Section titled “KINDGI_LOG_LEVELS”Synopsis
KINDGI_LOG_LEVELS=<value>Levels per subsystem, over KINDGI_LOG_LEVEL: a comma list of subsystem=level, such as kernel=debug,http=warn. A dotted subsystem takes its parent's level (kernel=debug covers kernel.sweeper). A malformed entry stops the server at boot (exit code 2); a subsystem nothing logs under is a warning at boot.
Values
- Read by: the server
- Required: no
- Default: none: no per-subsystem levels;
KINDGI_LOG_LEVELapplies everywhere
Example
KINDGI_LOG_LEVELS=kernel=debugSee also
KINDGI_LOG_FORMAT
Section titled “KINDGI_LOG_FORMAT”Synopsis
KINDGI_LOG_FORMAT=auto|json|prettyjson: one record per line (time, level, severity, subsystem, message, then the ids), for a log collector. pretty: for a person at a terminal. auto (default): pretty when stdout is a terminal or KINDGI_DEV=true, JSON otherwise. kindgi dev sets pretty.
Values
- Read by: the server
- Required: no
- Values:
auto,json,pretty - Default:
auto:prettywhen stdout is a terminal orKINDGI_DEVis on, elsejson
Example
KINDGI_LOG_FORMAT=jsonSee also
Secrets backend selection
Section titled “Secrets backend selection”KINDGI_SECRETS_BACKEND
Section titled “KINDGI_SECRETS_BACKEND”Synopsis
KINDGI_SECRETS_BACKEND=none|postgres|dotenv|secret-managerWhere secret bytes live. none (default; /v1/secrets/* unmounted) | postgres (envelope-encrypted, needs KMS) | dotenv (.env files in a directory; development only, needs KINDGI_DEV=true) | secret-manager (your own secret manager holds the bytes; pick it with KINDGI_SECRETS_MANAGER).
Values
- Read by: the server
- Required: no
- Values:
none,postgres,dotenv,secret-manager - Default:
none(the secrets routes are not served)
Example
KINDGI_SECRETS_BACKEND=postgresSee also
KINDGI_SECRETS_MANAGER
Section titled “KINDGI_SECRETS_MANAGER”Synopsis
KINDGI_SECRETS_MANAGER=azure|gcp|aws|vaultWhich secret manager the secret-manager backend keeps secrets in: azure (Azure Key Vault, see KINDGI_SECRETS_AZURE_VAULT_URL), gcp (Google Secret Manager, in the project KINDGI_SECRETS_GCP_PROJECT_ID names; the server's service account needs roles/secretmanager.admin there), vault (HashiCorp Vault or OpenBao, see KINDGI_SECRETS_VAULT_ADDR) or aws (AWS Secrets Manager, used from runtime 0.1.7: in the region KINDGI_SECRETS_AWS_REGION names, signed in as the server's AWS identity, KINDGI_AWS_IDENTITY; runtime 0.1.6 refuses it at startup). Kindgi reads and writes them with the server's own identity and keeps only their names and version numbers in its database.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager - Required: yes
- Values:
azure,gcp,aws,vault - Default: none (required)
Example
KINDGI_SECRETS_MANAGER=azureSee also
KINDGI_SECRETS_DOTENV_DIR
Section titled “KINDGI_SECRETS_DOTENV_DIR”Synopsis
KINDGI_SECRETS_DOTENV_DIR=<value>Absolute path of the directory whose .env files hold secrets (dotenv backend). Mount the project directory here; secrets written through the API land in its files.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=dotenv - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_DOTENV_DIR=/packSee also
KINDGI_SECRETS_DOTENV_FILES
Section titled “KINDGI_SECRETS_DOTENV_FILES”Synopsis
KINDGI_SECRETS_DOTENV_FILES=<value>Comma-separated .env files read for secrets (dotenv backend), relative to KINDGI_SECRETS_DOTENV_DIR, lowest precedence first. Default .env,.env.local.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=dotenv - Required: no
- Default:
.env,.env.local
Example
KINDGI_SECRETS_DOTENV_FILES=.env,.env.localSee also
KINDGI_SECRETS_BACKEND_KMS
Section titled “KINDGI_SECRETS_BACKEND_KMS”Synopsis
KINDGI_SECRETS_BACKEND_KMS=gcp|azure|aws|libsodiumWhich KMS wraps DEKs (postgres backend only): gcp (Google Cloud KMS), azure (an Azure Key Vault key, see KINDGI_SECRETS_AZURE_KEY_ID), or libsodium, a key this runtime holds (see KINDGI_SECRETS_LOCAL_KEY_PATH). Reserved: aws.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres - Required: yes
- Values:
gcp,azure,aws,libsodium - Default: none (required)
Example
KINDGI_SECRETS_BACKEND_KMS=gcpSee also
KINDGI_SECRETS_AAD_KEY_PATH
Section titled “KINDGI_SECRETS_AAD_KEY_PATH”Synopsis
KINDGI_SECRETS_AAD_KEY_PATH=<value>Absolute path to a 32-byte AAD/HMAC key file (mode 0600). Same key across every replica; protects AEAD associated data over every secret row. The postgres backend needs this or KINDGI_SECRETS_AAD_KEY, not both.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres - Required: no
- Default: none (with
KINDGI_SECRETS_AAD_KEYunset): no key; the postgres backend refuses to start without one of the two
Example
KINDGI_SECRETS_AAD_KEY_PATH=/etc/kindgi/secrets-aad.keySee also
KINDGI_SECRETS_AAD_KEY
Section titled “KINDGI_SECRETS_AAD_KEY”Synopsis
KINDGI_SECRETS_AAD_KEY=<value>The 32-byte AAD/HMAC key itself, base64: for platforms that give secrets as environment variables (Cloud Run with Secret Manager, Container Apps with Key Vault), where a key file's mode can't be 0600. Reference one fixed version of it, never the latest: a new version would make every stored secret unreadable. The postgres backend needs this or KINDGI_SECRETS_AAD_KEY_PATH, not both.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres - Required: no
- Default: none: same as
KINDGI_SECRETS_AAD_KEY_PATH
Example
# 32 random bytes, base64KINDGI_SECRETS_AAD_KEY="$(openssl rand -base64 32)"See also
GCP vendor config (postgres + gcp KMS; secret-manager + gcp)
Section titled “GCP vendor config (postgres + gcp KMS; secret-manager + gcp)”KINDGI_SECRETS_GCP_PROJECT_ID
Section titled “KINDGI_SECRETS_GCP_PROJECT_ID”Synopsis
KINDGI_SECRETS_GCP_PROJECT_ID=<value>GCP project id owning the KMS keyring + key (postgres backend, KMS gcp), or holding the secrets in its Secret Manager (secret-manager backend, manager gcp; the server's service account needs to create, add versions to and disable them, e.g. Secret Manager Admin, in a project used for Kindgi's secrets alone).
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgresorsecret-manager - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_GCP_PROJECT_ID=my-projSee also
KINDGI_SECRETS_GCP_LOCATION_ID
Section titled “KINDGI_SECRETS_GCP_LOCATION_ID”Synopsis
KINDGI_SECRETS_GCP_LOCATION_ID=<value>KMS location, e.g. us-central1, europe-west1, global.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres,KINDGI_SECRETS_BACKEND_KMS=gcp - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_GCP_LOCATION_ID=us-central1See also
KINDGI_SECRETS_GCP_KEY_RING_ID
Section titled “KINDGI_SECRETS_GCP_KEY_RING_ID”Synopsis
KINDGI_SECRETS_GCP_KEY_RING_ID=<value>KMS keyring id within the location.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres,KINDGI_SECRETS_BACKEND_KMS=gcp - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_GCP_KEY_RING_ID=kindgiSee also
KINDGI_SECRETS_GCP_KEY_ID
Section titled “KINDGI_SECRETS_GCP_KEY_ID”Synopsis
KINDGI_SECRETS_GCP_KEY_ID=<value>CryptoKey id within the keyring (symmetric GOOGLE_SYMMETRIC_ENCRYPTION).
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres,KINDGI_SECRETS_BACKEND_KMS=gcp - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_GCP_KEY_ID=secrets-kekSee also
AWS vendor config (the server's AWS identity; secret-manager + aws)
Section titled “AWS vendor config (the server's AWS identity; secret-manager + aws)”KINDGI_AWS_IDENTITY
Section titled “KINDGI_AWS_IDENTITY”Synopsis
KINDGI_AWS_IDENTITY=container|instance|web-identity|profileUsed from runtime 0.1.7; runtime 0.1.6 ignores it. Where the server's AWS credentials come from, for the settings that sign in as it (such as the Bedrock adapter's auth: aws-identity). container: the task's or pod's role from the container credentials endpoint (ECS and Fargate, and EKS Pod Identity). instance: the EC2 instance profile, IMDSv2 only (in a container on EC2, raise the IMDS hop limit to 2, or use container). web-identity: EKS IRSA, from the projected token file and AWS_ROLE_ARN, which the platform sets. profile: development only (KINDGI_DEV=true), a named profile from ~/.aws as aws login or SSO makes it (KINDGI_AWS_PROFILE). Unset: the server has no AWS identity, and a registration that needs one is refused. Under KINDGI_TENANT_HOST_ACCESS=isolated, model providers can't sign in as it either. Never the AWS SDK's default chain or keys in the environment; Kindgi keeps no key.
Values
- Read by: the server
- Required: no
- Values:
container,instance,web-identity,profile - Default: none: the server has no AWS identity; a registration that needs one is refused
Example
KINDGI_AWS_IDENTITY=containerSee also
KINDGI_AWS_PROFILE
Section titled “KINDGI_AWS_PROFILE”Synopsis
KINDGI_AWS_PROFILE=<value>Used from runtime 0.1.7; runtime 0.1.6 ignores it. With KINDGI_AWS_IDENTITY=profile (development only): the profile in ~/.aws/config the server signs in as. Default: default.
Values
- Read by: the server
- Required: no
- Default:
default
Example
KINDGI_AWS_PROFILE=kindgi-devSee also
KINDGI_AWS_ROLE_ARN
Section titled “KINDGI_AWS_ROLE_ARN”Synopsis
KINDGI_AWS_ROLE_ARN=<value>Used from runtime 0.1.7; runtime 0.1.6 ignores it. An IAM role the server assumes on top of its AWS identity (STS, 1-hour sessions renewed before they expire): least privilege, or a role in another account. An IAM role's ARN, arn:aws:iam::<account>:role/<name>. Unset: the identity's own permissions.
Values
- Read by: the server
- Required: no
- Default: none: no role is assumed on top of the server's AWS identity
Example
KINDGI_AWS_ROLE_ARN=arn:aws:iam::123456789012:role/kindgi-bedrockSee also
KINDGI_AWS_ROLE_SESSION_NAME
Section titled “KINDGI_AWS_ROLE_SESSION_NAME”Synopsis
KINDGI_AWS_ROLE_SESSION_NAME=<value>Used from runtime 0.1.7; runtime 0.1.6 ignores it. With KINDGI_AWS_ROLE_ARN: the role session's name, as CloudTrail shows it. Default: kindgi-runtime.
Values
- Read by: the server
- Required: no
- Default:
kindgi-runtime
Example
KINDGI_AWS_ROLE_SESSION_NAME=kindgi-runtimeSee also
KINDGI_AWS_STS_REGION
Section titled “KINDGI_AWS_STS_REGION”Synopsis
KINDGI_AWS_STS_REGION=<value>Used from runtime 0.1.7; runtime 0.1.6 ignores it. With KINDGI_AWS_ROLE_ARN or KINDGI_AWS_IDENTITY=web-identity: the region whose STS endpoint is used (regional STS, never the global endpoint). Default: AWS_REGION. Neither: the server refuses to start.
Values
- Read by: the server
- Required: no
- Default: the value of
AWS_REGION; the server refuses to start when a role or web identity is used and neither is set
Example
KINDGI_AWS_STS_REGION=us-east-2See also
KINDGI_SECRETS_AWS_REGION
Section titled “KINDGI_SECRETS_AWS_REGION”Synopsis
KINDGI_SECRETS_AWS_REGION=<value>Used from runtime 0.1.7 (0.1.6 refuses KINDGI_SECRETS_MANAGER=aws at startup). The AWS region whose Secrets Manager holds the secrets set through Kindgi's API (secret-manager backend, manager aws). The server signs in as its AWS identity (KINDGI_AWS_IDENTITY), never with AWS_* keys or the SDK's default chain. That identity needs, on arn:aws:secretsmanager:<region>:<account>:secret:kindgi/* only: secretsmanager:CreateSecret, TagResource, PutSecretValue, GetSecretValue, DescribeSecret and DeleteSecret. Secrets are named kindgi/<hash>, with the scope in their tags.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=aws - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_AWS_REGION=ca-central-1See also
KINDGI_SECRETS_AWS_KMS_KEY_ID
Section titled “KINDGI_SECRETS_AWS_KMS_KEY_ID”Synopsis
KINDGI_SECRETS_AWS_KMS_KEY_ID=<value>Used from runtime 0.1.7 (0.1.6 refuses KINDGI_SECRETS_MANAGER=aws at startup). The KMS key AWS Secrets Manager encrypts Kindgi's secrets with (secret-manager backend, manager aws): a key ARN, key id or alias/…. The server's AWS identity then needs kms:GenerateDataKey and kms:Decrypt on it. Unset: AWS's own aws/secretsmanager key.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=aws - Required: no
- Default: none: AWS's own
aws/secretsmanagerkey
Example
KINDGI_SECRETS_AWS_KMS_KEY_ID=alias/kindgi-secretsSee also
Azure vendor config (the server's managed identity; postgres + azure KMS; secret-manager + azure)
Section titled “Azure vendor config (the server's managed identity; postgres + azure KMS; secret-manager + azure)”KINDGI_AZURE_CLIENT_ID
Section titled “KINDGI_AZURE_CLIENT_ID”Synopsis
KINDGI_AZURE_CLIENT_ID=<value>Client id of the user-assigned managed identity the server signs in to Azure with, for its Azure settings (KINDGI_SECRETS_BACKEND_KMS=azure, KINDGI_SECRETS_MANAGER=azure, KINDGI_IMAGE_REGISTRY_AUTH=azure). Unset: the service's system-assigned identity. With KINDGI_DEV=true (a laptop), the Azure CLI's sign-in (az login) first, then the managed identity. Kindgi keeps no key or secret for it.
Values
- Read by: the server
- Required: no
- Default: none: the service's system-assigned managed identity
Example
KINDGI_AZURE_CLIENT_ID=11111111-2222-3333-4444-555555555555See also
KINDGI_SECRETS_AZURE_KEY_ID
Section titled “KINDGI_SECRETS_AZURE_KEY_ID”Synopsis
KINDGI_SECRETS_AZURE_KEY_ID=<value>The Azure Key Vault key that wraps DEKs (postgres backend, KMS azure): its URL without a version, https://<vault>.vault.azure.net/keys/<name>. New secrets are wrapped with the key's current version and remember it, so rotating the key needs no rewrite. A URL with a version is refused. The server's identity needs wrap and unwrap on the key (the Key Vault Crypto Service Encryption User role).
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres,KINDGI_SECRETS_BACKEND_KMS=azure - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_AZURE_KEY_ID=https://my-vault.vault.azure.net/keys/kindgi-secretsSee also
KINDGI_SECRETS_AZURE_VAULT_URL
Section titled “KINDGI_SECRETS_AZURE_VAULT_URL”Synopsis
KINDGI_SECRETS_AZURE_VAULT_URL=<value>The Azure Key Vault that holds the secrets set through Kindgi's API (secret-manager backend, manager azure): its URL, https://<vault>.vault.azure.net. Use a vault for these alone, not the one your deployment's own secrets are in: the server's identity needs the Key Vault Secrets Officer role on it, to create, version, disable and recover secrets.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=azure - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_AZURE_VAULT_URL=https://my-kindgi-secrets.vault.azure.netSee also
HashiCorp Vault / OpenBao (secret-manager + vault)
Section titled “HashiCorp Vault / OpenBao (secret-manager + vault)”KINDGI_SECRETS_VAULT_ADDR
Section titled “KINDGI_SECRETS_VAULT_ADDR”Synopsis
KINDGI_SECRETS_VAULT_ADDR=<value>The Vault (or OpenBao) that holds the secrets set through Kindgi's API (secret-manager backend, manager vault): its address. https://, or plain http:// only to a Vault Agent on the same machine (http://127.0.0.1:8100) or in development. The server's token needs, on its kv version 2 mount (KINDGI_SECRETS_VAULT_MOUNT): create, read, update on <mount>/data/*; read, delete, list on <mount>/metadata/*; update on <mount>/delete/* and <mount>/destroy/*. A custom CA: NODE_EXTRA_CA_CERTS.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=vault - Required: yes
- Default: none (required)
Example
KINDGI_SECRETS_VAULT_ADDR=https://vault.example.com:8200See also
KINDGI_SECRETS_VAULT_MOUNT
Section titled “KINDGI_SECRETS_VAULT_MOUNT”Synopsis
KINDGI_SECRETS_VAULT_MOUNT=<value>The kv version 2 mount Kindgi keeps its secrets in. Use one for these alone. Default secret.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=vault - Required: no
- Default:
secret
Example
KINDGI_SECRETS_VAULT_MOUNT=kindgiSee also
KINDGI_SECRETS_VAULT_NAMESPACE
Section titled “KINDGI_SECRETS_VAULT_NAMESPACE”Synopsis
KINDGI_SECRETS_VAULT_NAMESPACE=<value>The Vault Enterprise or HCP Vault namespace (admin, admin/team). Unset: none.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=vault - Required: no
- Default: none: no namespace
Example
KINDGI_SECRETS_VAULT_NAMESPACE=adminSee also
KINDGI_SECRETS_VAULT_TOKEN_FILE
Section titled “KINDGI_SECRETS_VAULT_TOKEN_FILE”Synopsis
KINDGI_SECRETS_VAULT_TOKEN_FILE=<value>A file holding the server's Vault token, kept fresh by the platform: Vault Agent's sink, or a mounted secret. Read again every minute, and when Vault refuses the token. Set this or KINDGI_SECRETS_VAULT_K8S_ROLE. Kindgi never reads VAULT_TOKEN or ~/.vault-token.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=vault - Required: no
- Default: none: the server signs in with
KINDGI_SECRETS_VAULT_K8S_ROLEinstead; one of the two is required
Example
KINDGI_SECRETS_VAULT_TOKEN_FILE=/vault/secrets/tokenSee also
KINDGI_SECRETS_VAULT_K8S_ROLE
Section titled “KINDGI_SECRETS_VAULT_K8S_ROLE”Synopsis
KINDGI_SECRETS_VAULT_K8S_ROLE=<value>The role of Vault's Kubernetes auth method the server logs in with, using its pod's service account token. Its token is renewed by logging in again before its lease ends. Set this or KINDGI_SECRETS_VAULT_TOKEN_FILE.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=vault - Required: no
- Default: none: the server signs in with
KINDGI_SECRETS_VAULT_TOKEN_FILEinstead; one of the two is required
Example
KINDGI_SECRETS_VAULT_K8S_ROLE=kindgi-runtimeSee also
KINDGI_SECRETS_VAULT_K8S_MOUNT
Section titled “KINDGI_SECRETS_VAULT_K8S_MOUNT”Synopsis
KINDGI_SECRETS_VAULT_K8S_MOUNT=<value>Where Vault's Kubernetes auth method is mounted, with KINDGI_SECRETS_VAULT_K8S_ROLE. Default kubernetes.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=vault - Required: no
- Default:
kubernetes
Example
KINDGI_SECRETS_VAULT_K8S_MOUNT=kubernetes-prodSee also
KINDGI_SECRETS_VAULT_K8S_TOKEN_FILE
Section titled “KINDGI_SECRETS_VAULT_K8S_TOKEN_FILE”Synopsis
KINDGI_SECRETS_VAULT_K8S_TOKEN_FILE=<value>The service account token the Kubernetes login sends, with KINDGI_SECRETS_VAULT_K8S_ROLE. Default /var/run/secrets/kubernetes.io/serviceaccount/token; set it for a projected token with its own audience.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=secret-manager,KINDGI_SECRETS_MANAGER=vault - Required: no
- Default:
/var/run/secrets/kubernetes.io/serviceaccount/token
Example
KINDGI_SECRETS_VAULT_K8S_TOKEN_FILE=/var/run/secrets/vault/tokenSee also
Local key (postgres + libsodium: a key this runtime holds, single-node)
Section titled “Local key (postgres + libsodium: a key this runtime holds, single-node)”KINDGI_SECRETS_LOCAL_KEY_PATH
Section titled “KINDGI_SECRETS_LOCAL_KEY_PATH”Synopsis
KINDGI_SECRETS_LOCAL_KEY_PATH=<value>Absolute path to the local key: a file of 32 random bytes (openssl rand 32, mode 0600), for KINDGI_SECRETS_BACKEND_KMS=libsodium. It wraps every secret's data key, and it's held on this host, next to the database: back it up apart from the database, since a lost key loses every secret. Replicas mount the same file. Starting with a different key than the secrets were stored under is refused. This or KINDGI_SECRETS_LOCAL_KEY, not both.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres,KINDGI_SECRETS_BACKEND_KMS=libsodium - Required: no
- Default: none (with
KINDGI_SECRETS_LOCAL_KEYunset): no key; the libsodium KMS refuses to start without one of the two
Example
KINDGI_SECRETS_LOCAL_KEY_PATH=/etc/kindgi/secrets-local.keySee also
KINDGI_SECRETS_LOCAL_KEY
Section titled “KINDGI_SECRETS_LOCAL_KEY”Synopsis
KINDGI_SECRETS_LOCAL_KEY=<value>The local key itself, base64 (32 bytes; openssl rand -base64 32): for platforms that give secrets as environment variables. This or KINDGI_SECRETS_LOCAL_KEY_PATH, not both.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres,KINDGI_SECRETS_BACKEND_KMS=libsodium - Required: no
- Default: none: same as
KINDGI_SECRETS_LOCAL_KEY_PATH
Example
# 32 random bytes, base64KINDGI_SECRETS_LOCAL_KEY="$(openssl rand -base64 32)"See also
KINDGI_SECRETS_LOCAL_KEY_ACK
Section titled “KINDGI_SECRETS_LOCAL_KEY_ACK”Synopsis
KINDGI_SECRETS_LOCAL_KEY_ACK=single-nodeExactly single-node: the operator's acknowledgement that the secrets' key is held on this host, next to the database, not in a cloud KMS. Not FIPS 140-3; for regulated workloads, use a cloud KMS. Required with KINDGI_SECRETS_BACKEND_KMS=libsodium.
Values
- Read by: the server, with
KINDGI_SECRETS_BACKEND=postgres,KINDGI_SECRETS_BACKEND_KMS=libsodium - Required: yes
- Values:
single-node - Default: none (required)
Example
KINDGI_SECRETS_LOCAL_KEY_ACK=single-nodeSee also
Pack service (runs the pack code: tools and guardrail checks)
Section titled “Pack service (runs the pack code: tools and guardrail checks)”KINDGI_PACK_SERVICE_URL
Section titled “KINDGI_PACK_SERVICE_URL”Synopsis
KINDGI_PACK_SERVICE_URL=<value>Base URL of the pack service, the separate process that runs the pack code (its tools and guardrail checks), e.g. http://pack-service:8080 or its internal Cloud Run URL. Set: the server calls it over HTTP for every pack tool and check, and needs KINDGI_PACK_SERVICE_TOKEN. Unset: no pack code runs, and a pack tool fails saying no pack service is wired. kindgi dev runs its own.
Values
- Read by: the server
- Required: no
- Default: none: no pack service; a pack tool fails saying none is wired
Example
KINDGI_PACK_SERVICE_URL=http://pack-service:8080See also
KINDGI_PACK_CALL_TIMEOUT_MS
Section titled “KINDGI_PACK_CALL_TIMEOUT_MS”Synopsis
KINDGI_PACK_CALL_TIMEOUT_MS=<value>How long one pack call (a tool or a guardrail check) may take, in milliseconds. Default 120000. The deadline travels with the call, and the pack service aborts the handler when it passes.
Values
- Read by: the server, when it calls a pack service (
KINDGI_PACK_SERVICE_URLset) - Required: no
- Default:
120000(2 minutes)
Example
KINDGI_PACK_CALL_TIMEOUT_MS=120000See also
KINDGI_PACK_SERVICE_AUTH
Section titled “KINDGI_PACK_SERVICE_AUTH”Synopsis
KINDGI_PACK_SERVICE_AUTH=token|google-id-tokenHow the server proves itself to the pack service besides the pack token. token (default): the pack token alone. google-id-token: also a Google ID token for the pack service URL, from the server's own identity, for a pack service on Cloud Run behind IAM (--no-allow-unauthenticated); the URL must be https. The identity is a service account: on Cloud Run the server's own; elsewhere, impersonate one (a person's own credentials can't mint an ID token for a service).
Values
- Read by: the server, when it calls a pack service (
KINDGI_PACK_SERVICE_URLset) - Required: no
- Values:
token,google-id-token - Default:
token
Example
KINDGI_PACK_SERVICE_AUTH=tokenSee also
KINDGI_PACK_SERVICE_TOKEN
Section titled “KINDGI_PACK_SERVICE_TOKEN”Synopsis
KINDGI_PACK_SERVICE_TOKEN=<value>Shared secret between the server and the pack service. The pack service refuses any call without it, and the server sends it with every call. Required by the pack service, and by the server when KINDGI_PACK_SERVICE_URL is set. Use a long random value (openssl rand -base64 32). Both sides drop surrounding whitespace (such as the trailing newline of a stored secret), and refuse whitespace or control characters inside: the token travels in an HTTP header. The pack service removes it from its environment before it loads the pack code.
Values
- Read by: the server, when it calls a pack service (
KINDGI_PACK_SERVICE_URLset); the pack service - Required: yes
- Default: none (required)
Example
# long random value, printable ASCII without spacesKINDGI_PACK_SERVICE_TOKEN="$(openssl rand -hex 32)"See also
KINDGI_PACK_INDEX
Section titled “KINDGI_PACK_INDEX”Synopsis
KINDGI_PACK_INDEX=<value>Path of the pack's index.json in the pack service's image. Default /app/index.json, where kindgi build puts it; the --index flag overrides it.
Values
- Read by: the pack service
- Required: no
- Default:
/app/index.json(the--indexflag wins)
Example
KINDGI_PACK_INDEX=/app/index.jsonSee also
KINDGI_PACK_SERVICE_MAX_CONCURRENCY
Section titled “KINDGI_PACK_SERVICE_MAX_CONCURRENCY”Synopsis
KINDGI_PACK_SERVICE_MAX_CONCURRENCY=<value>How many calls the pack service runs at once. Past it, calls get 503 (overloaded), which the server retries. Default 32. On Cloud Run, set the service's concurrency to the same number.
Values
- Read by: the pack service
- Required: no
- Default:
32
Example
KINDGI_PACK_SERVICE_MAX_CONCURRENCY=32See also
KINDGI_PACK_ENV_CHECK
Section titled “KINDGI_PACK_ENV_CHECK”Synopsis
KINDGI_PACK_ENV_CHECK=strict|warnWhat the pack service does when a name the pack's env.required declares is unset or empty in its environment. strict (default): it isn't ready, and /readyz and every call answer 503 naming the missing names. warn: it serves, and names them in its log and /v1/info. kindgi dev uses warn.
Values
- Read by: the pack service
- Required: no
- Values:
strict,warn - Default:
strict
Example
KINDGI_PACK_ENV_CHECK=strictSee also
KINDGI_PACK_ENV_FILTER
Section titled “KINDGI_PACK_ENV_FILTER”Synopsis
KINDGI_PACK_ENV_FILTER=on|offWhether the pack service keeps only the names its pack declares (env.required, env.optional). on (default): before the pack's code loads, it drops every other variable from its environment but KINDGI_* and the platform's own (the process's basics, the language runtime's settings, PORT, proxies and certificates, and Cloud Run's, AWS's and Azure's workload identity and metadata), and logs the dropped names, never their values (WARN env-dropped). off: every variable reaches the pack's code. kindgi dev uses off.
Values
- Read by: the pack service
- Required: no
- Values:
on,off - Default:
on
Example
KINDGI_PACK_ENV_FILTER=onSee also
KINDGI_PACK_ENV_DECLARED
Section titled “KINDGI_PACK_ENV_DECLARED”Synopsis
KINDGI_PACK_ENV_DECLARED=<value>A Java or Scala pack service's declared names, comma-separated: the ones its launcher (kindgi-pack-java) keeps when KINDGI_PACK_ENV_FILTER is on, since a JVM can't drop a variable from its own environment. kindgi build sets it in the image from the pack's index; the service won't start when it differs from the index's env. Without it, the launcher drops nothing, and the service won't start while a name the pack doesn't declare reaches it.
Values
- Read by: the pack service
- Required: no
- Default: none: the launcher drops nothing (an image built by
kindgi buildsets it)
Example
KINDGI_PACK_ENV_DECLARED=DATABASE_URL,CACHE_DIRSee also
KINDGI_PACK_TENANT_ID
Section titled “KINDGI_PACK_TENANT_ID”Synopsis
KINDGI_PACK_TENANT_ID=<value>The one tenant this pack service serves: the tenant's id, a UUID, checked at startup. It needs a runtime that sends the kindgi-tenant-id header on its pack calls, 0.1.8 or later: with an earlier runtime, every call is refused. Set: the service refuses, with 421 (pack-tenant-mismatch), a call to /v1/invoke or /v1/info whose kindgi-tenant-id header is missing or names another tenant, and a tool call whose context names another tenant, before any pack code runs. The health probes stay open. The server sends the header on every call, from the deployment it routed the call to. An orchestrator that runs a pack service per tenant sets it. Unset: no check. It's a backstop for a misrouted call to an honest pack, not a boundary: the server's routing is.
Values
- Read by: the pack service
- Required: no
- Default: none: no check, the pack service answers any tenant's calls
Example
KINDGI_PACK_TENANT_ID=<UUID of the tenant this pack service serves>See also
KINDGI_PACK_ROUTING
Section titled “KINDGI_PACK_ROUTING”Synopsis
KINDGI_PACK_ROUTING=single|per-deploymentUsed from runtime 0.1.8; earlier runtimes ignore it. How the server finds the pack service for a call. single (default): one pack service, KINDGI_PACK_SERVICE_URL, for every call. per-deployment needs KINDGI_TENANCY=multi: the endpoints are recorded through the system API, which a runtime serving one tenant does not have, so the server refuses to start with it there; multi starts only with it. Each call then goes to the newest deployment that shipped the tool or check, at the endpoint recorded for it by whatever runs the services (an orchestrator, or a script) with a system:deployments key. Each endpoint carries its own token and auth, so KINDGI_PACK_SERVICE_URL, KINDGI_PACK_SERVICE_TOKEN and KINDGI_PACK_SERVICE_AUTH are refused; KINDGI_PACK_CALL_TIMEOUT_MS still applies. A call whose deployment has no endpoint yet fails (pack-endpoint-pending): it never falls back to an older deployment or another service. Deployments registered before it was turned on have no routes; deploy them again.
Values
- Read by: the server
- Required: no
- Values:
single,per-deployment - Default:
single: one pack service,KINDGI_PACK_SERVICE_URL, for every call
Example
KINDGI_PACK_ROUTING=singleSee also
KINDGI_PACK_ENDPOINT_HOSTS
Section titled “KINDGI_PACK_ENDPOINT_HOSTS”Synopsis
KINDGI_PACK_ENDPOINT_HOSTS=<value>Used from runtime 0.1.8; earlier runtimes ignore it. With KINDGI_PACK_ROUTING=per-deployment: the hosts a deployment's pack endpoint may name, comma-separated. Each is a host name; *. and a domain, which matches one more label in front of it; or *-, a tail and a domain, which matches one more label ending with - and the tail. On Cloud Run, name each pack project with *-<project number>.<region>.run.app: Cloud Run URLs are <service>-<project number>.<region>.run.app for every project, so *., or a *- tail that isn't a project number, with run.app or a domain under it would admit anyone's service, and the server refuses to start with one. Lowercase, with no scheme, port or path. Without it, the server refuses to start: per-deployment routing needs KINDGI_TENANCY=multi, which starts only with the hosts named. An endpoint's host must also begin with its deployment's own service name (kp- and 20 characters, then - or .), so an endpoint can't point one tenant's deployment at another's service.
Values
- Read by: the server
- Required: no
- Default: none: with
KINDGI_PACK_ROUTING=per-deployment, the server refuses to start
Example
KINDGI_PACK_ENDPOINT_HOSTS=*-123456789012.us-central1.run.appSee also
Image registry (where deployments' images are read from)
Section titled “Image registry (where deployments' images are read from)”KINDGI_IMAGE_REGISTRY_HOST
Section titled “KINDGI_IMAGE_REGISTRY_HOST”Synopsis
KINDGI_IMAGE_REGISTRY_HOST=<value>The registry host the credentials below are for, with its port when it has one (e.g. registry.example, ghcr.io). Other registries are read anonymously.
Values
- Read by: the server
- Required: no
- Default: none: every registry is read anonymously
Example
KINDGI_IMAGE_REGISTRY_HOST=registry.exampleSee also
KINDGI_IMAGE_REGISTRY_USERNAME
Section titled “KINDGI_IMAGE_REGISTRY_USERNAME”Synopsis
KINDGI_IMAGE_REGISTRY_USERNAME=<value>Username for KINDGI_IMAGE_REGISTRY_HOST. Used for the registry's token flow, or as basic auth.
Values
- Read by: the server
- Required: no
- Default: none: no credentials (anonymous reads)
Example
KINDGI_IMAGE_REGISTRY_USERNAME=kindgi-readerSee also
KINDGI_IMAGE_REGISTRY_PASSWORD
Section titled “KINDGI_IMAGE_REGISTRY_PASSWORD”Synopsis
KINDGI_IMAGE_REGISTRY_PASSWORD=<value>Password or access token for KINDGI_IMAGE_REGISTRY_HOST. Read-only (pull) access is enough.
Values
- Read by: the server
- Required: no
- Default: none: no credentials (anonymous reads)
Example
KINDGI_IMAGE_REGISTRY_PASSWORD=<registry password or read-only access token>See also
KINDGI_IMAGE_REGISTRY_INSECURE_HOSTS
Section titled “KINDGI_IMAGE_REGISTRY_INSECURE_HOSTS”Synopsis
KINDGI_IMAGE_REGISTRY_INSECURE_HOSTS=<value>Comma-separated registry hosts reached over plain HTTP instead of HTTPS, e.g. a local registry:2. Loopback hosts (localhost, 127.0.0.1) always are.
Values
- Read by: the server
- Required: no
- Default: none: loopback hosts always use plain HTTP
Example
KINDGI_IMAGE_REGISTRY_INSECURE_HOSTS=registry.internal:5000See also
KINDGI_IMAGE_REGISTRY_AUTH
Section titled “KINDGI_IMAGE_REGISTRY_AUTH”Synopsis
KINDGI_IMAGE_REGISTRY_AUTH=static|google|azureHow the server signs in to KINDGI_IMAGE_REGISTRY_HOST. static (default): KINDGI_IMAGE_REGISTRY_USERNAME and _PASSWORD. google: the server's own Google identity (Application Default Credentials: the service's identity on Cloud Run), for Artifact Registry; no username or password is set, and Kindgi keeps no key file. azure: the server's own managed identity (see KINDGI_AZURE_CLIENT_ID), for Azure Container Registry, where it needs the AcrPull role; no username or password is set either.
Values
- Read by: the server
- Required: no
- Values:
static,google,azure - Default:
static
Example
KINDGI_IMAGE_REGISTRY_AUTH=staticSee also
Development (kindgi dev; each needs KINDGI_DEV=true)
Section titled “Development (kindgi dev; each needs KINDGI_DEV=true)”KINDGI_PACK_DIR
Section titled “KINDGI_PACK_DIR”Synopsis
KINDGI_PACK_DIR=<value>Development only: the pack directory kindgi dev runs. The server reads the pack's tools, guardrails, agents and flows from the index kindgi dev writes there (.kindgi/dev/index.json), on every change, instead of from Postgres; signed deployments are off. Mount the directory, not the file: the index is replaced by rename.
Values
- Read by: the server
- Required: no
- Default: none: packs come from signed deployments in Postgres
Example
KINDGI_PACK_DIR=/packSee also
KINDGI_DEV_CONSOLE_LOGIN
Section titled “KINDGI_DEV_CONSOLE_LOGIN”Synopsis
KINDGI_DEV_CONSOLE_LOGIN=true|false|1|0Development only: true lets the console log in by itself. GET /__dev/bearer hands it the API token, answering only requests addressed to a loopback host (localhost, 127.0.0.1, [::1]). Needs the console.
Values
- Read by: the server
- Required: no
- Values:
true,false,1,0 - Default:
false
Example
KINDGI_DEV_CONSOLE_LOGIN=trueSee also
KINDGI_DEV_HOST_ALIAS
Section titled “KINDGI_DEV_HOST_ALIAS”Synopsis
KINDGI_DEV_HOST_ALIAS=<value>Development only: where the server's outbound calls to a loopback address (localhost, 127.0.0.1, [::1]) connect instead. This covers webhooks to the app, HTTP MCP endpoints, model providers and the pack service. Inside a container, loopback is the container itself; kindgi dev sets host.docker.internal on Docker Desktop. The URL, the Host header and the TLS server name stay as written; only the connection goes to the alias.
Values
- Read by: the server
- Required: no
- Default: none: calls to loopback addresses connect as written
Example
KINDGI_DEV_HOST_ALIAS=host.docker.internalSee also