Skip to content

Reference

Configuration reference

You can look up every setting of the three images, with its default.

Before you start

  • You run the images forgeopslabs/flux-gate-backend, forgeopslabs/flux-gate-edge and forgeopslabs/flux-gate-ui, for example with the demo docker-compose.demo.yml.
  • You have the demo config.demo.toml, or your own config.toml, mounted into the backend.

What you will do

The backend reads a config.toml file and a few environment variables. The edge server and the UI take their settings from environment variables. The sections below list each setting, what it does, and its default. Secrets such as FLUXGATE_ENCRYPTION_KEY are environment variables so that they stay out of the file.

A check mark (✓) after a default means the value was checked in a running v1.2.0 container: from its default file, its startup log, or its behavior. The other defaults are the v1.2.0 defaults from the product's configuration. They were not exercised.

Backend

config.toml

Mount your file at /app/config/config.toml. When the container starts, its entrypoint copies that file to /app/config.toml, and the backend reads the copy. If you mount nothing, the entrypoint copies a built-in default file instead.

docker-compose.demo.yml (backend)
volumes:
  - ./config.demo.toml:/app/config/config.toml:ro

The first three keys are required. Every other key is optional and falls back to its default. Put the keys of a table such as [auth] under that table heading.

KeyDefaultDescription
allowed_originhttp://localhost:3000 in config.demo.toml ✓; http://localhost:8090 in the built-in default fileThe exact origin of the UI. The backend accepts browser requests from this origin only. Single sign-on callbacks redirect to it.
http_addr0.0.0.0:8080 ✓Address and port of the REST server and of Swagger UI at /docs/.
grpc_addr0.0.0.0:50051 ✓Address and port of the gRPC server. Edge servers connect here.
public_base_urlunsetThe public address of the backend as browsers and identity providers reach it, for example https://fluxgate.example.com. The backend builds single sign-on callback addresses from it. A trailing slash is removed. When unset, the backend derives the address from each request, and logs a warning at startup. Set it in production.
grpc_tls_cert_fileunsetPEM certificate chain for the gRPC server. Set it with grpc_tls_key_file, or set neither. When both are set, the gRPC port serves TLS only, and edge servers must use an https:// EDGE_BACKEND_GRPC.
grpc_tls_key_fileunsetPEM private key for the gRPC server. An unreadable or invalid file stops the backend at startup.
[auth] access_token_ttl_minutes30 ✓Lifetime of an access token in minutes. Values below 1 become 1.
[auth] refresh_token_ttl_days7 ✓Lifetime of a refresh token in days. Values below 1 become 1.
[jira] allow_insecure_httpfalseAllow http:// Jira base URLs for write-back. Keep it false unless you test against a local Jira.
[jira] ui_base_urlunset, so allowed_origin is usedThe UI address that FluxGate puts in the remote links it creates on Jira tickets.
[jira] inbound_per_minute120Sustained number of inbound Jira events per minute for one integration. Excess events get 429. A value of 0 becomes the default.
[jira] inbound_burst60Number of inbound Jira events that one integration can send at once. A value of 0 becomes the default.
[typesafe] base_urlhttps://api.typesafe.ai ✓Address of the TypeSafe API that serves the Jev AI features.
[typesafe] modeljev-1.13.0 ✓The Jev model version. It is pinned on purpose: moving aliases such as jev-latest can change answers.
[typesafe] timeout_ms3000 ✓Timeout of each HTTP attempt to the TypeSafe API, in milliseconds. A value of 0 becomes the default.
[typesafe] max_in_flight16 ✓Number of TypeSafe requests that can run at the same time. A value of 0 becomes the default.

The demo config.demo.toml sets only the first three keys. It has public_base_url too, but commented out. These are its settings, with the comments removed:

config.demo.toml
allowed_origin = "http://localhost:3000"
http_addr = "0.0.0.0:8080"
grpc_addr = "0.0.0.0:50051"
#public_base_url = "https://fluxgate.example.com"

To change token lifetimes and the Jev model, add tables to the same file:

config.toml
[auth]
access_token_ttl_minutes = 15
refresh_token_ttl_days = 14

[typesafe]
model = "jev-1.13.0"
timeout_ms = 5000

Environment variables

Environment variables carry the database address and the secrets. The backend does not read other config.toml keys from the environment, so no variable overrides a key in the file.

VariableDefaultDescription
DATABASE_URLnone, requiredPostgreSQL connection string, postgres://<user>:<password>@<host>:5432/<database>. URL-encode special characters in the password. The backend runs its migrations against this database at every start.
FLUXGATE_ENCRYPTION_KEYnoneThe key that encrypts the secrets FluxGate stores: Jira write-back tokens and single sign-on client secrets. It must be the standard base64 of exactly 32 bytes. The demo compose file refuses to start without it.
FLUXGATE_SSO_<SLUG>_CLIENT_SECRETunsetOptional client secret for one single sign-on provider. It wins over the stored secret and needs no encryption key. Uppercase the provider slug and replace every character that is not a letter or digit with _: the slug my-idp gives FLUXGATE_SSO_MY_IDP_CLIENT_SECRET.
TYPESAFE_API_KEYunsetYour TypeSafe API key. When it is set, the Jev AI features turn on. Without it, all AI controls stay hidden. The key is never read from config.toml.
FEATURE_TOGGLE_CONFIGunsetPath of a configuration file to load instead of /app/config.toml. You rarely need it, because the entrypoint already copies your mounted file.
RUST_LOGinfo in the demo compose fileNot read. The images set the log level in a bundled logging file.

Without a valid FLUXGATE_ENCRYPTION_KEY, saving a Jira token or a single sign-on secret fails. Set the key from the first boot.

Edge server

The edge server reads its settings from environment variables. The image has no config.toml, so you must set the first four variables yourself. You can also mount a config.toml and point EDGE_CONFIG_FILE at it. Environment variables override values in that file.

VariableDefaultDescription
EDGE_BACKEND_GRPCnone, requiredAddress of the backend gRPC server, for example http://backend:50051.
EDGE_HTTP_ADDRnone, requiredAddress and port the edge listens on, for example 0.0.0.0:8081.
EDGE_CLIENT_IDnone, requiredThe ID (a UUID) of the client the edge authenticates as. It is not the SDK key.
EDGE_CLIENT_SECRETnone, requiredThe API key of that client.
EDGE_NODE_IDthe host nameA stable name for this edge. A relay needs a stable value, because you register the relay by it.
EDGE_CONFIG_FILEconfig.tomlPath of an optional configuration file. If the file does not exist, the edge uses environment variables only.

The demo compose file starts the edge with empty EDGE_CLIENT_ID and EDGE_CLIENT_SECRET. The edge then cannot authenticate to the backend until you set both.

Tuning settings

Every other edge setting has a default, and you rarely change them. Set one with an EDGE_ variable. A double underscore __ separates the section from the key: EDGE_CACHE__CLIENT_TTL_SECS=60 sets client_ttl_secs in the cache section. A single underscore, as in EDGE_CACHE_CLIENT_TTL_SECS, is ignored. In a config.toml, the same settings sit in the matching table, for example [cache].

VariableDefaultDescription
EDGE_CACHE__MAX_CAPACITY10000 ✓Number of flags the edge keeps in its cache. The oldest unused flags leave first when the cache is full.
EDGE_CACHE__CLIENT_TTL_SECS300 ✓Seconds the edge caches a successful client authentication. A disabled client or a rotated API key can keep working for this long. The edge caches a rejected key for a fixed 30 seconds.
EDGE_CACHE__CLIENT_MAX_CAPACITY1000 ✓Number of client credentials whose authentication the edge caches.
EDGE_GRPC__CONNECT_TIMEOUT_SECS5Timeout for connecting to the backend.
EDGE_GRPC__TIMEOUT_SECS10Timeout of each gRPC request.
EDGE_GRPC__TCP_KEEPALIVE_SECS30TCP keepalive interval.
EDGE_GRPC__HTTP2_KEEPALIVE_SECS20HTTP/2 keepalive interval.
EDGE_GRPC__KEEP_ALIVE_WHILE_IDLEtrueKeep the connection alive when no request runs.
EDGE_GRPC__CONCURRENCY_LIMIT256Maximum number of concurrent gRPC requests.
EDGE_GRPC__TCP_NODELAYtrueTurn on TCP_NODELAY for the connection.
EDGE_GRPC__COMPRESSIONnoneCompression of gRPC requests: none or gzip. The older name EDGE_GRPC_COMPRESSION still works, but it is deprecated.
EDGE_FLUSH__ASSIGNMENT_FLUSH_SECS10 ✓Seconds between sends of user assignments to the backend.
EDGE_FLUSH__EVALUATION_FLUSH_SECS30Seconds between sends of evaluation events to the backend.
EDGE_FLUSH__EVALUATION_EVENT_QUEUE_CAPACITY10000Size of the queue of evaluation events that wait to be sent.
EDGE_FLUSH__ASSIGNMENT_FLUSH_BATCH_SIZE1000Maximum number of user assignments in one send.
EDGE_FLUSH__EVALUATION_FLUSH_BATCH_SIZE500Maximum number of evaluation events in one request.
EDGE_RETRY__BASE_DELAY_MS500Base delay of the exponential backoff between retries, in milliseconds.
EDGE_RETRY__MAX_ATTEMPTS3Maximum number of attempts for a direct gRPC call.
EDGE_RETRY__STREAM_INITIAL_DELAY_SECS1First delay before the edge reconnects the flag stream.
EDGE_RETRY__STREAM_MAX_DELAY_SECS30Longest delay between reconnect attempts.
EDGE_GRPC__TLS_CA_FILEemptyPEM file with the CA that signed the backend gRPC certificate. Used only when EDGE_BACKEND_GRPC starts with https://. Empty trusts the built-in public roots.

Resilience settings

These settings keep an edge serving when the backend is unreachable. See Edge resilience for how they fit together.

VariableDefaultDescription
EDGE_RESILIENCE__CLIENT_STALE_IF_ERROR_SECS86400Seconds after its last successful check that the edge still accepts an SDK key while the backend is unavailable. 0 turns it off.
EDGE_RESILIENCE__READY_MAX_AGE_SECS0Config age in seconds above which /health and /health/ready return 503. 0 turns the limit off.
EDGE_SNAPSHOT__DIRemptyFolder for the local snapshot file. The edge reads it at startup. Empty turns the local snapshot off.
EDGE_SNAPSHOT__WRITE_INTERVAL_SECS30Longest wait between two writes of the file after stream updates.
EDGE_SNAPSHOT__BOOTSTRAPemptyWhere the edge reads a signed bootstrap snapshot: a file path or an https:// URL. Empty turns it off. Needs EDGE_SNAPSHOT__TRUSTED_KEYS. Enterprise: the backend needs a signing key.
EDGE_SNAPSHOT__TRUSTED_KEYSemptyPublic keys that may sign a bootstrap snapshot, as one comma-separated string of <key ID>:<public key>. In config.toml, use a list.
EDGE_SNAPSHOT__STARTUP_WAIT_SECS5Seconds the stream gets to deliver flags before the edge reads the bootstrap snapshot.
EDGE_SNAPSHOT__MAX_AGE_SECS0Oldest bootstrap snapshot the edge accepts, in seconds since the backend generated it. 0 means no limit.

Relay settings

A relay is an edge that serves other edges. Registering a relay needs the edge_resilience entitlement (Enterprise).

VariableDefaultDescription
EDGE_RELAY__ENABLEDfalseRun this edge as a relay.
EDGE_RELAY__GRPC_ADDR0.0.0.0:50061Address of the relay gRPC listener.
EDGE_RELAY__SERVE_HTTPtruefalse makes a pure relay that serves only the health, detail, and metrics paths.
EDGE_RELAY__TLS_CERT_FILEemptyPEM certificate chain of the relay listener. Set it with the key file, or set neither.
EDGE_RELAY__TLS_KEY_FILEemptyPEM private key of the relay listener.
EDGE_RELAY__ALLOW_INSECUREfalseServe children over plaintext gRPC when no TLS files are set. Without TLS files and this setting, the edge stops at startup.

The images set the log level in a bundled logging file. RUST_LOG is not read.

Admin UI

The UI container reads four variables when it starts. It writes them into a small file that the browser loads. The UI has no proxy: your browser calls the backend directly, at <BACKEND_PROTOCOL>://<BACKEND_HOST>:<BACKEND_PORT>/api/v1. Set these variables to the address that your browser uses to reach the backend, not to the compose service name backend.

VariableDemo valueDescription
BACKEND_HOSTlocalhostHost name of the backend as the browser reaches it.
BACKEND_PORT8080Port of the backend as the browser reaches it. The port is always part of the address, so use 443 for HTTPS on the default port.
BACKEND_PROTOCOLhttphttp or https. Use https when the UI page is served over HTTPS.
WS_PROTOCOLwsws or wss, for the live-update connection. Use wss with https.

The variables have no built-in defaults. If you leave one out, the UI builds an invalid backend address. Set all four.

Ports

PortServiceProtocolNotes
3000Admin UIHTTPPublished by the demo compose file. The container listens on port 80 inside.
8080BackendHTTPREST API at /api/v1, and Swagger UI at /docs/. Configured by http_addr.
50051BackendgRPCEdge servers connect here. Configured by grpc_addr. The demo compose file does not publish it. Never publish it in production.
8081Edge serverHTTPFlag evaluation for your apps. Configured by EDGE_HTTP_ADDR.
5433PostgreSQLTCPHost port in the demo compose file. The container listens on 5432 inside. Remove this mapping in production.

To move a service to another host port, change the left side of its ports entry in the compose file, for example "3100:80". Then update the settings that point at it: allowed_origin for the UI, and BACKEND_PORT for the backend.

Secrets

ValueWhereHow to create itWhat breaks when it changes
FLUXGATE_ENCRYPTION_KEYBackend environmentopenssl rand -base64 32Stored Jira tokens and single sign-on client secrets stop decrypting. Enter each one again in the UI. Do not change the key while the database exists. Back it up.
EDGE_CLIENT_SECRETEdge environmentThe API key of a client. Create the client in the UI.If you regenerate the API key of the client, the edge cannot authenticate until you set the new value. Requests already authenticated in the cache keep working for up to EDGE_CACHE__CLIENT_TTL_SECS.
EDGE_CLIENT_IDEdge environmentThe ID of the same client.The edge cannot authenticate when the ID and the secret belong to different clients.
TYPESAFE_API_KEYBackend environmentCreate it in your TypeSafe account.Removing it turns the Jev AI features off.
FLUXGATE_SSO_<SLUG>_CLIENT_SECRETBackend environmentCopy it from your identity provider.Set the new value and recreate the backend.
Database password in DATABASE_URLBackend environment, and PostgreSQLSet it when you create the database user.The backend cannot connect and does not start.
JWT signing secretsThe database, managed in the UIFluxGate creates the first one at first start. Rotate or deactivate secrets in the UI.After Generate New Secret, the old secret keeps verifying for a grace period equal to the access-token lifetime (30 minutes by default). Deactivate All JWT Secrets signs every user out.

Keep these values in a secret store, not in the compose file. Never commit the .env file. The demo password local123 in the compose file is for local use only.

Good to know

  • A change in config.toml needs a backend restart. The entrypoint copies the file at container start.
  • Run one backend instance. Scale the edge server for more evaluation traffic.
  • Docker Hub publishes the images with the tags v2.0.1 and latest. Pin v2.0.1 in production.

Troubleshooting

Browser requests fail with a CORS error

allowed_origin does not match the address in the browser address bar. Set it to the exact origin of the UI, with scheme and port and no trailing path. Restart the backend.

The backend ignores my config.toml

The file must be mounted at /app/config/config.toml, not at /app/config.toml. The entrypoint prints Using mounted config.toml when it finds the file. If it prints No mounted config found, check the volume path.

Changing RUST_LOG does not change the logs

The images set the log level in a bundled logging file; RUST_LOG is not read.

An EDGE_ setting has no effect

Check the separator. A section setting needs a double underscore: EDGE_GRPC__TIMEOUT_SECS, not EDGE_GRPC_TIMEOUT_SECS.

Next

To call the edge server over HTTP, see the Edge server API. To plan for backend outages, see Edge resilience.