Skip to content

Runtime Bootstrap and Access

See also: Configuration Reference, Identity and Access, Service Accounts, Oceans LLM Gateway, Deploy, Deploy and Operations, Admin Runbooks

This page explains what the gateway does when it starts and what access exists right after boot.

Source of Truth

Startup Actions

The normal startup path is gateway serve.

At startup, the gateway can do three separate things:

  • run migrations
  • seed config-backed objects such as providers, models, teams, users, and budgets
  • ensure a bootstrap admin exists

Those actions are controlled by:

  • GATEWAY_RUN_MIGRATIONS
  • GATEWAY_SEED_CONFIG
  • GATEWAY_BOOTSTRAP_ADMIN

The same behavior is also exposed through explicit commands:

  • gateway migrate
  • gateway seed-config
  • gateway bootstrap-admin

Startup Shapes

Runtime shapeConfigRequired env for first accessDatabaseAdmin login sourceData-plane access source
Local developmentgateway.yamlnone for checked-in defaultslibsql or SQLiteadmin@local / admin from checked-in confignone by default; local demo reset seeds sample keys
Production-shaped localgateway.prod.yamlPOSTGRES_URL if not supplied by the mise taskPostgreSQLadmin@local / admin, with forced password rotationservice account created after admin access
GHCR compose deploydeploy/config/gateway.yamlGATEWAY_BOOTSTRAP_ADMIN_PASSWORD, provider secrets, Postgres envPostgreSQLadmin@local with env-backed bootstrap passwordservice account created after admin access
Kubernetes Helm deployrendered gateway.config valuesPOSTGRES_URL or CloudNativePG connection secret, GATEWAY_IDENTITY_TOKEN_SECRET, provider secretsPostgreSQLopt-in bootstrap-admin Jobservice account created after admin access

Bootstrap admin access and service-account data-plane access are separate paths. One can exist without the other.

Local development

  • config: ../gateway.yaml
  • database: libsql or SQLite
  • usual entry point: mise run dev-stack
  • bootstrap admin: enabled
  • forced password change: off
  • seeded teams, users, and budgets: driven by config

What exists after boot:

  • a gateway on http://localhost:8080
  • an admin UI at http://localhost:8080/admin
  • a bootstrap admin at admin@local with password admin
  • config-seeded local users are invited team members, not checked-in control-plane admins
  • when ./gateway.db is absent and you start with mise run dev-stack, the local demo dataset is seeded automatically:
    • 2 teams
    • 5 users across those teams
    • owner-aware demo credentials for local data-plane testing
    • $1000/month budgets for each team and a $50/day user budget
    • request-log and spend history sample rows for the admin observability pages

Production-shaped local run

  • config: ../gateway.prod.yaml
  • database: PostgreSQL
  • usual entry point: mise run prod-stack
  • bootstrap admin: enabled
  • forced password change: on
  • data-plane service accounts: created after admin access

What exists after boot:

  • the same admin email and password as the local-dev config
  • a forced password rotation on first sign-in
  • a runtime shape closer to deploy and release behavior

GHCR compose deploy

What exists after boot:

  • a bootstrap admin at admin@local
  • config-seeded teams, invited users, and any listed active budgets
  • admin access once GATEWAY_BOOTSTRAP_ADMIN_PASSWORD is set in the deploy environment
  • data-plane access after an allowed admin creates a service account and credential

Kubernetes Helm deploy

  • chart source: ../../deploy/helm/oceans-llm
  • mounted config: rendered from gateway.config values
  • database: external PostgreSQL by default, optional CloudNativePG Cluster
  • migrations: Helm hook Job enabled by default
  • bootstrap admin: disabled until bootstrapAdminJob.enabled=true
  • seeded config: disabled until seedConfigJob.enabled=true

What exists after boot depends on the enabled Jobs:

  • migrations run before normal external-Postgres installs and after CloudNativePG resource creation for CloudNativePG installs
  • gateway pods do not run migrations, bootstrap admin creation, or config seeding on startup
  • admin access only exists if bootstrap-admin is enabled or an admin already exists in the database
  • data-plane access exists after an allowed admin creates a service account and credential

Bootstrap Admin

Bootstrap admin creation is for control-plane access.

  • It is separate from service-account data-plane credentials.
  • It is checked at startup when bootstrap behavior is enabled.
  • It can also be created with gateway bootstrap-admin.

Checked-in defaults:

  • local config keeps the bootstrap admin on and does not force password rotation
  • production-shaped local config keeps the bootstrap admin on and forces password rotation

For the lifecycle and ownership rules after that first sign-in, see identity-and-access.md.

Service-Account Data-Plane Access

Service accounts are for non-human data-plane access.

  • They belong to a team.
  • They are managed by platform admins or by owners and admins of the owning team.
  • They authenticate through issued credentials.
  • They do not replace admin login.
  • Direct team-owned runtime API keys and system-legacy seeded keys are not supported.

Seeded users and teams are also config-backed, but password and OIDC onboarding links are still generated through the admin UI after boot.

Access Matrix

ObjectCan sign in to /admin?Can call /v1/*?Notes
Bootstrap adminYesNo, unless a separate user credential is createdFirst control-plane access path.
Config-seeded invited userNo, until onboarding completesNo, unless a credential is created for that userStarts as invited.
Config-seeded platform admin userNo, until onboarding completesNo, unless a credential is created for that userRole is seeded, but auth proof still requires onboarding.
Gateway service accountNoYes, through an issued credentialTeam-owned non-human principal.
Service-account credentialNoYesData-plane access only.
Direct team-owned API keyNoNoRemoved compatibility path.

First Access Checklist

The right first-access path depends on the runtime shape.

Local development

  • open /admin
  • sign in with admin@local / admin
  • inspect live admin-backed pages

Production-shaped local run

  • open /admin
  • sign in with admin@local / admin
  • rotate the password when prompted
  • confirm provider secrets and Postgres connectivity

Compose deploy

  • confirm the stack is healthy
  • sign in with admin@local and the configured bootstrap password
  • inspect seeded teams, invited users, and budgets in /admin
  • create a team service account and credential for automation that needs /v1/*

Kubernetes Helm deploy

  • render the intended values with mise run helm-template or helm template
  • confirm required secrets exist before install or are produced by ExternalSecret
  • confirm the migration Job succeeds
  • confirm gateway and admin UI pods become ready
  • call /healthz and /readyz through the gateway service or ingress
  • sign in to /admin only after bootstrap-admin is intentionally enabled or a pre-existing admin exists

Startup Paths That Are Easy To Confuse

These behaviors are easy to blur together:

  • seed-config creates config-backed runtime objects
  • bootstrap-admin creates control-plane access
  • serve can do both, but only when the related switches are on
  • service-account credentials create non-human data-plane access

That means one environment can have:

  • valid API access but no admin login
  • valid admin login but no service-account credential
  • both
  • neither, if the startup toggles are disabled and the database is empty

Authentication Notes

OIDC/OAuth providers and password users are seeded by config when present in the active gateway config. Local SSO testing uses ../development/authentication-testing.md; production-shaped first access still depends on the active deploy config and supplied secrets.

What This Page Does Not Own