Console
Sign in
Docs for Console and CLI user
On this page
  1. Build and run
  2. Set up Access
  3. Credentials it holds
  4. Probes and logs
  5. Replicas and limits
  6. Rotating secrets

Operations

How to build, deploy and run the console in production: Access setup, the credentials it holds, probes and logs, replicas, and secret rotation. It is for operators and secops; variables are in configuration.md and behavior rules in the specification.

Read byPlatform operatorSecurity engineer

Build and run#

bash
bun run --cwd packages/console build   # dist/: browser files and the server
bun run --cwd packages/console start   # src/main.ts serves the build

The release publishes the image of the console like the three services: ghcr.io/ggpwnkthx/console:<version>. The image builds from packages/console/Dockerfile. Its build stage runs vite build and reads the docs/ tree into the server build. The final image contains only the build and the process, with no development modules and no secrets: it runs as the non-root bun user, exposes port 8083, writes only to stdout (the file system can be read-only), and checks GET /healthz every 15 seconds.

The digest of the image is in the file digests.json of the release, and a deployment pins the digest rather than the tag.

The standalone stack is deploy/compose/console.compose.yaml; the full platform stack includes the console too.

Set up Access#

Do this once per tenant whose people use the console.

  1. Register {CONSOLE_PUBLIC_URL}/auth/callback in the tenant's clientRedirectUris.
  2. Grant console.status, console.admin or console.platform on the console's route, with the tenant slug as the workspace:
bash
   curl -sS -X PUT "$ACCESS/v1/admin/grants" \
     -H "authorization: Bearer $ACCESS_ADMIN_TOKEN" -H "content-type: application/json" \
     -d '{"tenant":"acme","userId":"…","permission":"console.admin","workspaceId":"acme","routeId":"console"}'
  1. Configure, in Access, the access context credential (ACCESS_CONTEXT_TOKENS) and the administration credentials (ACCESS_ADMIN_TOKENS) that the console holds, then give the same values to the console's variables.

The mapping from each Access setting to its console variable is in configuration.md.

Credentials it holds#

CredentialUsed forAllows
CONSOLE_CLIENT_SECRETExchanging a login code at AccessSigning a caller in as the tenant's client
CONSOLE_ACCESS_CONTEXT_TOKENReading an operator's scope through the access context contractReading a principal's keys (read-only)
CONSOLE_TENANT_ADMIN_TOKENSTenant administration, for that tenant's operatorsChanging the tenant's users, groups and rights
CONSOLE_ADMIN_TOKENPlatform administration, for operators holding console.platformChanging every tenant
CONSOLE_SESSION_SECRETSigning console cookiesNothing outside the console
Callers' access tokensData calls through the gatewayWhatever Data's policies allow that caller, for five minutes

It never holds:

  • the gateway's identity-signing private key: every data request carries the caller's token, and the key would let the console act as the gateway toward every upstream;
  • a database connection: it reaches no platform store;
  • a decision: every refusal it shows comes from a service, which refuses even what the console fails to hide.

Sessions, login and cookie rules: spec §3. Request origin and content security policy: spec §2. Operator scope and revocation: spec §4.

Probes and logs#

EndpointResponse
GET /healthz200 {"status":"ok","service":"console","version":"…"} while the process is alive.
GET /readyz200 {"status":"ready"} when Access serves its discovery document, else 503 {"status":"not-ready"}.

Logs go to stdout as one JSON object per line, one line per request, including the request ID (x-request-id). Probe requests are not logged. Set the level with CONSOLE_LOG_LEVEL.

Replicas and limits#

  • Sessions and pending logins live in process memory. Run one replica, or pin each browser to one.
  • A restart signs everyone out; callers still signed in at the tenant's provider are signed back in without a prompt.
  • The workspace list comes from the caller's grants, read with the tenant's credential. A right covering every workspace of a tenant names none, so the caller opens such a workspace by ID.

Rotating secrets#

SecretHow to rotate
CONSOLE_SESSION_SECRETReplace it; everyone is signed out.
CONSOLE_CLIENT_SECRETAccess accepts a client's old secret alongside the new one for a day: update the tenant, then the console.
Administration and access context credentialsAdd the new credential to Access, update the console, then remove the old one.

Access's side of a client secret rotation is in the Access spec: rotating a secret.