Server Authentication (rescile-ee)
rescile-ee serve protects all served routes with browser- and machine-facing
authentication. Authentication is enabled by passing a TOML configuration file:
rescile-ee serve --auth-file auth.toml
# or via environment variable
RESCILE_AUTH_FILE=auth.toml rescile-ee serve
Without --auth-file, no authentication is enforced. All routes — GraphQL,
REST, MCP, the Web UI, and binary mounts — are open. Always pass --auth-file
on servers reachable outside a trusted network.
Load failures matter: if the file cannot be read or fails TOML parsing, the
server logs a warning and starts without authentication. If any provider
fails to initialize (for example an OIDC issuer_url that cannot be reached
at startup), the entire file is skipped silently — there is no warning,
the only indication is the missing Loaded authentication from auth.toml
log line. Treat that line as the confirmation that protection is active, and
monitor for it.
File format
# Top-level keys must appear before any [table] header.
login_redirect = "/apps/my-app/"
session_secret = "${env.SESSION_SECRET}"
[users]
admin = "correct-horse-battery-staple"
ci = "${env.CI_USER_PASSWORD}"
[api_keys]
ci-pipeline = "k-8f3b..."
runner-alpha = "k-91d2..."
[providers.google]
type = "oidc"
issuer_url = "https://accounts.google.com"
client_id = "..."
client_secret = "${env.GOOGLE_CLIENT_SECRET}"
scopes = ["openid", "email", "profile"]
[providers.github]
type = "oauth2"
auth_url = "https://github.com/login/oauth/authorize"
token_url = "https://github.com/login/oauth/access_token"
api_url = "https://api.github.com/user"
client_id = "..."
client_secret = "${env.GITHUB_CLIENT_SECRET}"
Environment variable expansion
Before parsing, ${env.NAME} occurrences are replaced with the value of the
environment variable NAME. Missing variables expand to an empty string.
Use this to keep credentials out of the file itself — the file may be
committed or live in a world-readable config directory.
[users] — browser login and Basic auth
Maps usernames to passwords. Used by:
- the
/loginpage (form-based, sets an HTTP-only session cookie), and - HTTP
Authorization: Basic ...headers — the standard challenge for CLI tools such ascurl -u admin,wget --user, and most CI fetch helpers.
[api_keys] — machine authentication
Maps key names to secret tokens. Accepted as:
Authorization: Bearer <token>, orX-API-Key: <token>.
API keys are interchangeable with user credentials at the HTTP layer; use them for runners, CI pipelines, and other non-interactive clients.
Key names are significant for runners: standalone agent runners may only
authenticate with a key whose name starts with runner- (for example
runner-alpha = "k-..."). Ordinary keys cannot register a runner. The
in-process runner (--runner) needs no entry — it generates an ephemeral
internal-runner key per boot. See
Agent Runners.
login_redirect
Optional path the browser is sent to after a successful form login (default
/). A path starting with /apps/ that is missing its trailing slash is
corrected automatically.
session_secret
Optional secret used to encrypt OIDC session cookies (rescile_session).
Without it an insecure development default is used — always set this in
production when OIDC providers are configured. It should be a long random
value (64+ bytes is safe; shorter values are padded).
[providers.<name>] — OIDC and OAuth2
Each named entry enables a browser single sign-on button on the login page.
type = "oidc": standard OpenID Connect.issuer_urlis required; the provider metadata (authorization and token endpoints) is discovered from the issuer at startup. Note that a provider that fails discovery causes the whole file to be skipped (see the load-failure behavior above).type = "oauth2": plain OAuth2 with explicitauth_urlandtoken_url(required);api_urlis used to fetch user identity from the token.
The provider name appears in the SSO flow URLs: /auth/login/<name> and
/auth/callback/<name>.
How requests are authenticated
The middleware accepts any of the following, in this order:
Authorization: Basic— checked against[users].Authorization: Bearer <token>— checked against[api_keys].X-API-Key: <token>— checked against[api_keys].- OIDC session cookie (
rescile_session, HTTP-only, expires after 24 hours). - Form-login cookie (
rescile_auth, HTTP-only, set by/login).
When authentication is enabled, unauthenticated requests behave by route class:
/api/*,/graphql,/mcp,/binaries/*,/__portal— HTTP401with aWWW-Authenticate: Basicchallenge, so command-line tools retry with credentials automatically.- all other paths — redirect to
/login(browsers land on the login page, preserving the query string).
/login, /auth/*, /favicon.ico, and /vault* are always reachable without
authentication.
In-process runner
When --runner is used, the embedded runner authenticates to the gRPC port
with a per-boot random API key; the [api_keys] map does not need an entry for
it.