Skip to main content

Overview

FOKS server configuration is written in Jsonnet, a superset of JSON with variables, functions, and imports. All services share a single config file: conf/foks.jsonnet. The file is structured as:
conf/foks.jsonnet          # main config (from source tree, do not edit)
conf/local.pre.libsonnet   # local overrides applied before the main config
conf/local.post.libsonnet  # local overrides applied after
config.bash generates the local.*.libsonnet files from your deployment parameters. To see the fully-resolved configuration:
jsonnet conf/foks.jsonnet

Core settings

These live in local.pre.libsonnet and are set by config.bash.

Networking

FieldDescription
external_addrThe DNS hostname clients connect to (set from --base-hostname). All services advertise this hostname at different ports.
bind_addr_extIP address to bind externally-facing services (default 0.0.0.0 in Docker, 127.0.0.1 otherwise)
bind_addr_intIP address to bind internal services
base_ext_portBase port for external services. probe listens here; beacon, reg, user, kv_store, merkle_query follow on +1 through +5.

Ports

All external services share external_addr and differ only by port:
ServicePort offset
probebase_ext_port + 0
beaconbase_ext_port + 1
regbase_ext_port + 2
userbase_ext_port + 3
kv_storebase_ext_port + 4
merkle_querybase_ext_port + 5
Clients discover the exact ports from the probe service — no client-side port configuration is required.

Database

FieldDescription
db.hostPostgreSQL hostname
db.portPostgreSQL port
db.userDatabase user
db.passwordDatabase password
db.no-tlsDisable TLS for the DB connection (set true for local Docker)
FOKS uses multiple databases (one per functional area). Each is named in the db block of foks.jsonnet:
DatabasePurpose
foks_usersUser accounts, devices, team memberships
foks_queue_serviceInternal key-exchange message queue
foks_merkle_treeMerkle tree
foks_merkle_raftMerkle coordination
foks_server_configHost configuration, SSO config, plans
foks_beaconBeacon service (HostID → DNS mapping)
foks_kv_store_NKey-value store shards (one or more)

Keys and certificates

FieldDescription
keys_dirDirectory containing server private keys
certs_dirDirectory containing TLS certificates and CAs
caPath to the host’s root CA certificate
probe_caPath to the probe CA certificate

Viewership mode

Controls whether users on the same host can see each other:
ModeBehavior
openAll users on the host are visible to each other. Admins can add users to teams by name.
closedUsers must explicitly allow others to view them. Invites are required for team operations.
Viewership is set when the host is initialized and can be changed later via the web admin panel.

Other flags

FieldDefaultDescription
standalonetrueSet false for a hosting platform that supports virtual hosts
localhost_testfalseEnables test mode: overrides DNS to localhost, uses local CAs

Applying config changes

After editing local.pre.libsonnet or local.post.libsonnet, restart the affected services:
systemctl restart foks-*     # systemd
# or
docker compose restart       # Docker Compose

SSO / OAuth2 configuration

SSO is configured at runtime via the web admin panel, not in the Jsonnet config. This means SSO can be enabled, changed, or disabled without restarting any services.
SSO is configured per virtual host (or per standalone server). It is set up through the web admin UI at foks admin web.

Setting up OAuth2 SSO

  1. In your identity provider (Okta, Entra ID, Auth0, etc.), create an OAuth2 application with:
    • Grant type: Authorization Code + PKCE
    • Redirect URI: https://<your-foks-host>/oauth2/callback
    • Scopes: openid, profile, email, offline_access
  2. Note the OpenID configuration URL. For Okta this looks like:
    https://your-org.okta.com/application/o/appname/.well-known/openid-configuration
    
  3. Open the FOKS web admin panel:
    foks admin web
    
  4. Navigate to your virtual host’s settings → SSO and enter:
    FieldDescription
    OpenID Config URLYour IDP’s .well-known/openid-configuration URL
    Client IDOAuth2 application client ID
    Client SecretOAuth2 client secret (optional if using pure PKCE)

How SSO authorization works

Once SSO is configured, every authenticated FOKS request checks with the IDP:
  1. On login, the user is redirected to the IDP and completes the OAuth2 flow. FOKS stores the resulting access and refresh tokens.
  2. On every subsequent authenticated connection, FOKS checks whether the stored access token is still valid.
  3. If the token is near expiry, FOKS proactively exchanges the refresh token with the IDP for a fresh access token.
  4. If the IDP rejects the refresh — because the user was deprovisioned, suspended, or removed from the application — FOKS immediately marks the session as invalid. The user loses access within the access token’s remaining TTL (usually minutes, depending on IDP settings).
This means removing a user from your IDP automatically revokes their FOKS access without any manual intervention.
For immediate revocation, set a short access token TTL in your IDP (e.g., 10 minutes). FOKS will attempt a refresh within that window and fail as soon as the IDP rejects the user.

SSO and usernames

When SSO is enabled, FOKS usernames are derived from the IDP’s preferred_username or email claim. This keeps FOKS identities in sync with your organization’s naming scheme — when you look up alice@your-foks-host, you know exactly which IDP account that maps to.

Disabling SSO

SSO can be disabled from the web admin panel at any time. Existing users will retain their accounts; they will no longer require IDP re-validation on each connection.