Environment variables
You configure self-hosted Stategraph only with environment variables on the Stategraph container:
- The database connection and
STATEGRAPH_UI_BASE are always required.
- Some variables are required only with a feature, such as OAuth or Orchestration.
- All others have a default.
Leave optional variables unset, not empty: several Orchestration variables treat an empty string differently from an unset one.
Core
| Variable |
Default |
Description |
STATEGRAPH_UI_BASE |
required |
Public URL that users open, for example https://stategraph.example.com, for links, cookie security, and sign-in callbacks. migrate needs it too: it loads the configuration first |
STATEGRAPH_LICENSE_KEY |
unset |
License key of the Enterprise build. Needed to complete the first-time setup. You can also enter it on the setup screen, or later under Settings > License |
STATEGRAPH_DEFAULT_TENANT_NAME |
Default |
Tenant that new users join at sign-in. With an empty string, new users have no tenant until someone adds them to one |
STATEGRAPH_INVITATION_TTL_HOURS |
168 |
Tenant invitation link validity, in hours (7 days) |
STATEGRAPH_AEGIS_API_BASE / STATEGRAPH_AEGIS_SERVICE_TOKEN |
unset |
Aegis control plane, used only for invitation emails. Both unset: invitations are links only |
STATEGRAPH_ENABLE_CORS |
false |
Send CORS headers. Development only, with the console on another origin |
STATEGRAPH_CORS_DEFAULT_ORIGIN |
http://localhost:3000 |
Origin that CORS allows |
HTTP
| Variable |
Default |
Description |
STATEGRAPH_ACCESS_LOG |
off |
Access log, used as it is: a path or off, no on. /dev/stdout writes each request to the container log |
STATEGRAPH_CLIENT_MAX_BODY_SIZE |
512m |
Maximum request body, which limits the state file size |
DISABLE_IPV6 |
0 |
1 turns off IPv6 on port 8080 |
Database
| Variable |
Default |
Description |
DB_HOST |
required |
PostgreSQL host |
DB_PORT |
5432 |
PostgreSQL port |
DB_USER |
required |
Database user |
DB_PASS |
required |
Database password |
DB_NAME |
required |
Stategraph database name, stategraph in every guide |
DB_CONNECT_TIMEOUT |
120 |
Connection timeout in seconds. Orchestration reads it too, same default |
DB_MAX_POOL_SIZE |
100 |
Maximum connections in the pool. Orchestration reads it too |
DB_IDLE_TX_TIMEOUT |
180s |
Idle-in-transaction timeout. Orchestration reads it too |
DB_LOCK_TIMEOUT |
120s |
Lock timeout. Only Orchestration reads it |
STATEGRAPH_DB_STATEMENT_TIMEOUT |
30s |
Statement timeout for the Stategraph server |
DWF_IDLE_TX_TIMEOUT |
600s |
Idle-in-transaction timeout for workflow connections. No STATEGRAPH_ prefix |
Orchestration reads the same DB_* names for its database. See Orchestration for how they map.
Authentication
Local email and password sign-in needs no variable. For the sign-in modes, see Access control.
| Variable |
Default |
Description |
STATEGRAPH_OAUTH_TYPE |
unset |
google or oidc. Unset: single sign-on is off |
STATEGRAPH_OAUTH_CLIENT_ID |
|
OAuth client ID. Required with STATEGRAPH_OAUTH_TYPE |
STATEGRAPH_OAUTH_CLIENT_SECRET |
|
OAuth client secret. Required with STATEGRAPH_OAUTH_TYPE |
STATEGRAPH_OAUTH_REDIRECT_BASE |
http://localhost:<port> |
Base URL of the /oauth2/{provider}/callback callbacks. Set it to the public URL, as in STATEGRAPH_UI_BASE |
STATEGRAPH_OAUTH_EMAIL_DOMAIN |
* |
Email domain that can sign in. With *, any identity that the provider authenticates signs in, and the first to sign in while no instance admin exists becomes one. Restrict it to your domain on any public deployment |
STATEGRAPH_OAUTH_DISPLAY_NAME |
Google or SSO |
Provider name on the sign-in button |
STATEGRAPH_OAUTH_COOKIE_SECRET |
random per process |
Signs session and CSRF cookies: 16, 24, or 32 characters. Set it on each replica of a multi-replica deployment, or replicas do not share sessions |
STATEGRAPH_OAUTH_OIDC_ISSUER_URL |
|
OIDC issuer URL, required with STATEGRAPH_OAUTH_TYPE=oidc. The provider must support discovery at {issuer}/.well-known/openid-configuration |
STATEGRAPH_OAUTH_OIDC_USE_AUTH0_LOGOUT |
false |
Use the Auth0 logout endpoint for OIDC sign-out |
STATEGRAPH_OAUTH_GOOGLE_GROUP |
unset |
Google Group whose members can sign in. Needs the two variables below |
STATEGRAPH_OAUTH_GOOGLE_ADMIN_EMAIL |
unset |
Google Workspace super admin email, for Google Groups API access |
STATEGRAPH_OAUTH_GOOGLE_SERVICE_ACCOUNT_JSON |
unset |
Google Admin API service account key, as inline JSON or a file path |
STATEGRAPH_OAUTH2_PROXY_PATH |
/usr/local/bin/oauth2-proxy |
Path of the oauth2-proxy binary that Stategraph runs |
A missing or invalid sign-in variable stops the server at start, with the reason in the server log. If the sign-in provider does not start, the server runs without OAuth sign-in, with the reason in /tmp/oauth2-proxy.log in the container.
Server tuning
| Variable |
Default |
Description |
STATEGRAPH_DWF_CONCURRENCY |
40 |
Workflow concurrency |
STATEGRAPH_PREVIEW_EXEC_TIMEOUT_MINUTES |
60 |
Wall-clock limit for a plan preview |
STATEGRAPH_PREVIEW_IDLE_TIMEOUT_MINUTES |
60 |
Idle limit for a plan preview |
STATEGRAPH_COMMIT_EXEC_TIMEOUT_MINUTES |
60 |
Wall-clock limit for a commit |
STATEGRAPH_COMMIT_IDLE_TIMEOUT_MINUTES |
60 |
Idle limit for a commit |
STATEGRAPH_FOCUS_SYNC_PARALLELISM |
|
Parallelism of focus synchronization |
STATEGRAPH_INTERP_MEMO |
on |
Memoization in the HCL interpreter. false, 0, or off turns it off |
STATEGRAPH_INTERP_MEMO_VERIFY |
off |
true, 1, or on compares memoized results with a fresh evaluation |
STATEGRAPH_HCL_TYPE_COERCION_STRICT |
|
Strict type coercion in the HCL interpreter |
Orchestration
Enable Orchestration explains the database, the roles, and the GitHub and GitLab setup.
| Variable |
Default |
Description |
STATEGRAPH_ORCHESTRATION_ENABLED |
off |
true or 1 turns on Orchestration, and rebuilds the FDW bridge at each start |
TERRAT_API_BASE |
required with Orchestration |
Public URL plus /api. The runner base URL comes from it |
TERRAT_UI_BASE |
required with Orchestration |
Public URL of the Terrateam console host, and run link base of a .terrateam/config repository. If it names the STATEGRAPH_UI_BASE host or localhost, that host keeps the Stategraph console |
TERRAT_WEB_BASE_URL |
required with Orchestration |
Public URL. Run link base in comments and commit checks for a repository whose brand has no base of its own. https://app.terrateam.io when unset or empty |
TERRAT_DB_HOST / TERRAT_DB_PORT / TERRAT_DB_USER / TERRAT_DB_PASS |
the DB_* values |
Orchestration database connection. Each unset one takes the matching DB_* value |
TERRAT_DB_NAME |
terrateam |
Orchestration database. It never takes DB_NAME |
TERRAT_SESSION_COOKIE_NAME |
terrat_session, set in the container |
Orchestration session cookie. It must differ from the console session cookie on the shared origin, or a VCS OAuth callback signs the console user out. Set it container-wide: Stategraph expires it at sign-out |
TERRAT_BRAND |
unset |
Brand of comments and commit-check names when the repository configuration names none. .stategraph/config or a stategraph centralized repository gives stategraph, and .terrateam/config or a terrateam one gives terrateam. Others get this value, or stategraph when unset. Any value except stategraph or terrateam is a configuration error: Orchestration does not start |
TERRAT_TELEMETRY_LEVEL |
anonymous |
anonymous or disabled. Other values stop Orchestration at start |
TERRAT_TELEMETRY_URI |
https://telemetry.terrateam.io |
Where anonymous telemetry goes |
TERRAT_ADMIN_TOKEN |
unset |
Bearer token for the Orchestration admin endpoints |
TERRAT_DEFAULT_TIER |
unlimited |
Default tier of a new installation |
TERRAT_EVENT_EVALUATOR_SLOTS |
20 |
Concurrent event evaluations |
TERRAT_STATEMENT_TIMEOUT |
5s |
Statement timeout for the Orchestration database |
TERRAT_GC_MIN_SPACE_OVERHEAD / TERRAT_GC_MAX_SPACE_OVERHEAD / TERRAT_GC_HEAP_SPACE_OVERHEAD_START_MB / TERRAT_GC_HEAP_SPACE_OVERHEAD_REALLY_MB |
unset |
Garbage collector tuning. Set all four together |
GITHUB_ACTION_DYNAMIC_TITLE |
unset |
Comma-separated fields for the dynamic title of Orchestration GitHub Actions runs: pr_title, pr_number, run_kind, run_type |
GITHUB_WORKFLOW_PATH_OVERRIDE |
unset |
Path of the GitHub Actions workflow file that Orchestration dispatches, in place of the default |
TERRATUNNEL_API_ENDPOINT |
unset |
Development only: TERRAT_API_BASE comes from a tunnel |
INFRACOST_PRICING_API_ENDPOINT / SELF_HOSTED_INFRACOST_API_KEY |
empty |
Infracost pricing API endpoint and key, for cost estimation in pull requests. See Cost estimation in pull requests |
FDW bridge
| Variable |
Default |
Description |
STATEGRAPH_FDW_HOST |
localhost |
Host of the terrateam database, as seen from the PostgreSQL server |
STATEGRAPH_FDW_PORT |
5432 |
Port of that connection |
STATEGRAPH_FDW_DBNAME |
terrateam |
Orchestration database |
STATEGRAPH_FDW_USER |
stategraph_mql |
Read role that the bridge authenticates as |
STATEGRAPH_FDW_PASSWORD |
required with Orchestration |
Password of the read role. Without it, the configuration does not load |
STATEGRAPH_FDW_PROVISIONER_USER |
stategraph_provisioner |
Write role for GitLab provisioning from the console |
STATEGRAPH_FDW_PROVISIONER_PASSWORD |
unset |
Password of the write role. Unset: provisioning is off, the endpoint answers 503, and the console cannot connect a GitLab group |
GitHub
| Variable |
Default |
Description |
GITHUB_APP_ID |
unset |
GitHub App ID. Setting it turns on GitHub support |
GITHUB_APP_PEM |
|
Private key of the App. Literal \n sequences become newlines |
GITHUB_APP_CLIENT_ID / GITHUB_APP_CLIENT_SECRET |
|
OAuth client of the App, for Orchestration and Stategraph. For tenant self-claim, Stategraph reads both or neither |
GITHUB_WEBHOOK_SECRET |
|
Webhook secret of the App. Required with GITHUB_APP_ID: unset or empty, Orchestration does not start |
GITHUB_APP_URL |
unset |
App install URL, behind the console Install on GitHub button. Unset, the console says to install the App from the GitHub organization settings. Leave it unset, not empty |
GITHUB_API_BASE_URL |
https://api.github.com |
GitHub Enterprise Server API base |
GITHUB_WEB_BASE_URL |
https://github.com |
GitHub Enterprise Server web base |
GitLab
| Variable |
Default |
Description |
GITLAB_APP_ID |
unset |
Application ID of a GitLab OAuth application. A non-empty value turns on GitLab in Orchestration |
GITLAB_APP_SECRET |
unset |
Application secret. Required with GITLAB_APP_ID, or Orchestration does not start |
GITLAB_ACCESS_TOKEN |
unset |
Access token with the api scope. Required with GITLAB_APP_ID, or Orchestration does not start |
GITLAB_API_BASE_URL |
https://gitlab.com |
Root URL of a self-managed instance, for example https://gitlab.example.com, without /api/v4. Only Orchestration reads it |
GITLAB_WEB_BASE_URL |
https://gitlab.com |
Web URL of a self-managed instance, for example https://gitlab.example.com. Only Orchestration reads it |
Cost estimation
See Enable cost estimation.
| Variable |
Default |
Description |
STATEGRAPH_COST_ENABLED |
off |
true or 1 turns on cost estimation |
STATEGRAPH_PRICING_SERVICE_URL |
http://localhost:8090 |
Pricing endpoint. Set it only for an external pricing service |
STATEGRAPH_PRICING_DEFAULT_REGION |
us-east-1 |
Region for a resource that does not specify one |
STATEGRAPH_COST_SCHEDULE_HOURS |
24 |
Interval of the scheduled per-state cost recompute |
STATEGRAPH_COST_EVENT_DEBOUNCE_HOURS |
6 |
Minimum gap before an apply triggers a recompute |
STATEGRAPH_COST_PRICING_CALL_TIMEOUT_SECONDS |
30 |
Timeout of one pricing call |
PRICING_DB_HOST / PRICING_DB_PORT / PRICING_DB_USER / PRICING_DB_PASSWORD / PRICING_DB_NAME |
db / 5432 / stategraph / stategraph / cloud_pricing |
Price-book database. It does not take DB_*, but the load-pricing-data loader does, for host, port, user, and password |
PRICING_DB_SSLMODE |
disable |
Set it for a remote pricing database |
PRICING_REFRESH_HOURS |
168 |
Price-book refresh interval. 0 turns off the refresh |
LISTEN_ADDR |
:8090 |
Pricing endpoint listen address. It has no authentication: do not publish the port |
Security scanning
See Enable security scanning.
| Variable |
Default |
Description |
STATEGRAPH_SECURITY |
0, set in the container |
0 and false turn off scanning. Any other value, including an empty string, turns it on |
STATEGRAPH_SECURITY_SCHEDULE_HOURS |
24 |
Scheduled rescan interval per state |
STATEGRAPH_SECURITY_EVENT_DEBOUNCE_HOURS |
1 |
Minimum gap before an apply triggers another scan |
Read by the CLI, not the server
The stategraph CLI reads these when it runs, by hand or on a runner. The server ignores them.
| Variable |
Description |
TF_CMD |
Terraform or tofu binary that the CLI runs. It must exist when set |
STATEGRAPH_ACTUATOR_CHUNK_SIZE |
Size of the chunks that the CLI uploads |
STATEGRAPH_FETCH_RESULT_PARALLELISM |
Parallelism of the CLI result fetches |
Not supported
Stategraph ignores CUSTOM_CA_CERT: the container installs no certificates at start. To trust a custom CA, build a derived image. See Self-signed certificates.
If a configuration change has no effect, check the server metrics first: see Observability. Otherwise, contact support with your server logs and deployment version.
Next steps