Skip to content

Security Model

This page explains the security design decisions in Oore CI and how they protect your instance.

Authentication: Remote OIDC or Trusted Proxy + Loopback Local Login (Local Only)

For any non-loopback access (runtime_mode=remote), Oore CI requires one of:

  • OpenID Connect (OIDC)
  • Trusted Proxy mode (for example Warpgate / IAP)

There are no local passwords, no password storage, and no password reset flows.

The daemon also supports loopback-only local login (POST /v1/auth/local/login) for local-first onboarding and local operator access. When setup is incomplete, local login is only available in Local Only mode; in Remote mode it is only available after setup is complete. In Local Only mode, the first successful local login may auto-complete setup and create the initial owner record.

Why: Eliminates an entire class of vulnerabilities (credential storage, brute force attacks, password reuse). Users authenticate with identity systems already used by the organization. Disabling a user in the upstream identity system revokes their ability to start new sessions.

Trusted Proxy mode (Warpgate / IAP)

In Trusted Proxy mode, Oore CI trusts identity headers from an upstream proxy and creates normal Oore sessions per user.

  • Default identity header: x-warpgate-username (expected to be an email)
  • Trust boundary: headers are accepted only when the immediate peer is trusted (loopback by default, optional CIDR allowlist for remote proxy peers)
  • Authorization stays in Oore RBAC (owner/admin/developer/qa_viewer) via Oore users and roles

This mode does not introduce local passwords; it shifts authentication to the upstream access proxy while preserving Oore sessioning, RBAC, and audit attribution.

PKCE and CSRF protection (OIDC mode)

All OIDC flows use PKCE (S256 method) and CSRF state tokens:

  • PKCE: Prevents authorization code interception attacks
  • State token: Random value verified on callback to prevent CSRF
  • Nonce: Included in the ID token to prevent replay attacks
  • Pending auth entries expire after 10 minutes

Session management

  • Session tokens are 32-byte random values generated with OsRng
  • Only the SHA-256 hash is stored in the database
  • User sessions have a 24-hour TTL
  • Setup sessions have a 30-minute sliding window TTL
  • Sessions are invalidated on logout or user disablement

Authorization: RBAC

Four roles with fixed permission sets: owner, admin, developer, qa_viewer. Permissions are enforced at the API level — every request is checked before processing.

See RBAC Reference for the full permission matrix.

Encryption at rest

Sensitive data (OIDC client secrets, signing credentials) is encrypted with AES-256-GCM before storage:

  • The encryption key is stored in a file on disk at <data-root>/encryption.key
  • Each encrypted value includes a unique nonce (IV)

Bootstrap token security

The first-run bootstrap token (required for Remote-mode setup flows) has multiple protections:

ProtectionDetail
Randomness32 bytes (256 bits) from OsRng
StorageOnly SHA-256 hash stored; plaintext shown once
TTLConfigurable, default 15 minutes
Single-useConsumed on first successful verification
Rate limitingLocked after 5 failed attempts

Token and secret handling

DataStorageProtection
Bootstrap tokenSHA-256 hash in SQLitePlaintext never stored
Setup session tokenSHA-256 hash in SQLite30-minute sliding TTL
User session tokenSHA-256 hash in SQLite24-hour TTL
OIDC client secretAES-256-GCM encrypted in SQLiteFile-stored encryption key
Trusted proxy shared secret (optional)AES-256-GCM encrypted in SQLiteFile-stored encryption key
Signing certificatesAES-256-GCM encrypted in SQLiteSame encryption key
Keystore passwordsAES-256-GCM encrypted in SQLiteSame encryption key

CORS policy

The API restricts cross-origin requests:

  • Default origins: http://localhost:3000, http://127.0.0.1:3000, http://localhost:4173, http://127.0.0.1:4173
  • Configuration: Stored in SQLite (Preferences UI); env fallback via OORE_CORS_ORIGINS / OORE_CORS_ORIGIN
  • Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
  • Headers: Content-Type, Authorization

Network model

Oore CI is designed for local-network deployment:

  • The daemon listens on 127.0.0.1:8787 by default (localhost only)
  • For remote access, place the daemon behind a reverse proxy with TLS
  • Runner-to-daemon communication happens over your local network
  • The hosted UI at ci.oore.build connects directly to your daemon — no data proxied through a third party

Audit logging

User management operations are logged:

  • user_invited, role_changed, user_disabled, user_enabled, user_activated, owner_created

These events are stored in the SQLite database and available through the admin interface.

Self-hosted mobile CI, built for Flutter.