Skip to content

Installing Sibyl ​

Sibyl has two supported install shapes:

  • Default single-user install: local username/password auth is enabled, the first setup signup creates the owner/admin user, and later account creation is invite-only unless public signups are explicitly enabled.
  • Enterprise SSO install: Kubernetes deployment behind a corporate identity provider, with OIDC configured explicitly and local password login disabled only after an OIDC owner can sign in.

Just want Sibyl for yourself? This guide covers team and enterprise installs on Kubernetes.

For a personal single-user instance, Run Sibyl for Yourself (one command with sibyl up) or the single-host Ansible deploy for an always-on VM are the simpler paths. :::

SurrealDB is the active data plane in both shapes. Valkey or Redis is only needed for coordination when running multiple backend or worker replicas. Enterprise installs add an ingress or Gateway API controller for TLS and routing.

Prerequisites ​

  • Kubernetes cluster with a block-storage CSI driver.
  • A persistent claim shared by API and worker for completed validation receipts (ReadWriteMany access for multi-node replicas).
  • Helm 3.
  • A Gateway API-compatible controller or classic Ingress controller.
  • A secrets injector such as External Secrets Operator, Sealed Secrets, or your cloud KMS-backed secret manager.
  • SurrealDB 3.x, either through charts/surrealdb or a separately managed endpoint.
  • Valkey or Redis when backend or worker replicas are greater than one.
  • For enterprise SSO only: corporate OIDC app registration with MFA enforced at the provider.

Install The Charts ​

Render both charts before installing:

bash
helm lint charts/sibyl charts/surrealdb
helm template sibyl charts/sibyl -n sibyl -f values-enterprise.yaml
helm template sibyl-surrealdb charts/surrealdb -n sibyl -f values-surrealdb.yaml

Install SurrealDB first when using the wrapper chart:

bash
helm upgrade --install sibyl-surrealdb charts/surrealdb \
  -n sibyl \
  --create-namespace \
  -f values-surrealdb.yaml

Then install Sibyl:

bash
helm upgrade --install sibyl charts/sibyl \
  -n sibyl \
  -f values-enterprise.yaml

Minimal Enterprise Values ​

yaml
coordinationBackend: redis

auth:
  localAuthEnabled: false
  publicSignupsEnabled: false

oidc:
  providers:
    - name: entra
      issuer: "https://login.microsoftonline.com/<tenant-id>/v2.0"
      client_id: "<app-client-id>"
      client_secret_env: "SIBYL_OIDC_ENTRA_CLIENT_SECRET"
      organization_slug: "acme"
      scopes: ["openid", "profile", "email"]
  role_claim: "roles"
  session_minutes: 60
  silent_refresh_enabled: false
  extra_providers_enabled: false

backend:
  existingSecret: sibyl-secrets
  validationReceipts:
    existingClaim: sibyl-validation-receipts
    # Or keep receipts in S3 and leave existingClaim empty:
    # url: "s3://sibyl-receipts/prod?region=us-west-2"
  env:
    SIBYL_ENVIRONMENT: "production"
    SIBYL_PUBLIC_URL: "https://sibyl.example.com"
  surreal:
    url: "ws://sibyl-surrealdb:8000/rpc"
    existingSecret: sibyl-surreal
  redis:
    host: valkey.sibyl.svc.cluster.local
    existingSecret: sibyl-redis

ingress:
  gatewayApi:
    enabled: true
    parentRefs:
      - name: shared-gateway
        namespace: gateway-system
  hosts:
    - host: sibyl.example.com
      paths:
        - path: /api
          pathType: Prefix
          service: backend
        - path: /mcp
          pathType: Prefix
          service: backend
        - path: /
          pathType: Prefix
          service: frontend

networkPolicy:
  enabled: true

podSecurity:
  enforceRestricted: true

organization_slug is required for every OIDC provider and must exactly match a bootstrapped non-personal Sibyl organization. A verified role claim creates or updates membership only in that bound organization.

Keep cloud-specific annotations, certificate issuers, secret references, object storage mounts, and SIEM wiring in a deployment overlay.

The chart default keeps local username/password login enabled for simple self-hosted installs while leaving public signup, OIDC providers, silent refresh, extra OAuth providers, and break-glass access off. Enterprise SSO values should set auth.localAuthEnabled=false only after the corporate OIDC provider is configured and an owner has successfully signed in through it.

OIDC Provider Setup ​

Use one corporate provider in production. Non-corporate providers such as Google or GitHub require oidc.extra_providers_enabled=true; leave it false for enterprise installs.

ProviderAdmin setup
Microsoft Entra IDCreate App Roles named Sibyl.Member, Sibyl.Admin, and Sibyl.Owner; assign users or groups; require MFA with Conditional Access.
OktaMap groups or app assignments into the configured role claim, often groups; include any required scope in oidc.providers[].scopes.
Auth0Use an Action to copy RBAC roles into a namespaced custom claim such as urn:sibyl:roles.
KeycloakConfigure a mapper or set oidc.role_claim to a dotted path such as resource_access.sibyl.roles.

The redirect URI must match the provider name:

text
https://sibyl.example.com/api/auth/oidc/<provider>/callback

For silent refresh, also allow:

text
https://sibyl.example.com/api/auth/oidc/<provider>/refresh

Secrets ​

At minimum, the backend secret should provide:

text
SIBYL_JWT_SECRET
SIBYL_SETTINGS_KEY
SIBYL_OIDC_ENTRA_CLIENT_SECRET

Add the API key for each model provider the server routes to, such as SIBYL_ANTHROPIC_API_KEY and SIBYL_OPENAI_API_KEY. On AWS, Amazon Bedrock serves Claude and Cohere embeddings through the service account's IAM role and needs no provider key. An admin can also enter keys in the web app, which stores them encrypted with SIBYL_SETTINGS_KEY.

Use a generated 32-byte or stronger SIBYL_JWT_SECRET. Keep SIBYL_SETTINGS_KEY stable so encrypted settings can be read after a restart. With Redis coordination, every API replica and worker must carry the same SIBYL_SETTINGS_KEY (or mount one shared key file), and sibyld refuses to start without one rather than encrypt with a key no other process holds. The first process to start records a fingerprint of its key, and any process whose key differs refuses to start. To rotate the key on purpose, delete the internal.settings_key_fingerprint setting (DELETE /api/settings/internal.settings_key_fingerprint), restart every process with the new key, and enter the encrypted settings again.

Transactional Email ​

Password reset and invitation emails need a delivery provider. Configure either Resend or SMTP, plus a from address:

text
# Option A: Resend
SIBYL_RESEND_API_KEY
SIBYL_EMAIL_FROM

# Option B: SMTP
SIBYL_SMTP_HOST
SIBYL_SMTP_PORT
SIBYL_SMTP_USERNAME
SIBYL_SMTP_PASSWORD
SIBYL_EMAIL_FROM

Without one of these configured, Sibyl logs those emails to its JSONL outbox and skips live delivery, so invited users and password-reset requests never receive a link. When setting SMTP passwords in a Compose .env file, escape literal $ characters as $$.

Database Schema ​

The backend applies the auth and content schemas to SurrealDB automatically at startup, records applied migrations in schema_version, and refuses to start if bootstrap fails outside development mode, so a fresh store needs no manual step. To apply or repair the schemas by hand (an empty store, a restore, a bootstrap failure named in the logs), run:

bash
sibyld db init

The command is non-destructive and safe to run repeatedly: it never drops tables, skips migrations already recorded, and verifies schema invariants after applying. If requests fail with table ... does not exist, see the troubleshooting entry.

First Owner ​

The default Sibyl install is local-first. The first setup signup creates the owner/admin user. After setup completes, account creation is invite-based unless SIBYL_PUBLIC_SIGNUPS_ENABLED=true or auth.publicSignupsEnabled=true is set.

Enterprise SSO installs can opt into OIDC and then disable local password login after the corporate provider is working. Do not disable local auth on a fresh install before completing either local setup or a verified OIDC owner login, or the instance has no normal owner path.

Break-glass remains an explicit emergency path:

yaml
breakGlass:
  enabled: true
  allowedIPs:
    - 203.0.113.0/24
  expiresAt: "<UTC timestamp no more than four hours out>"
  existingSecret: sibyl-break-glass

After the OIDC owner signs in successfully, enterprise values may set auth.localAuthEnabled=false unless you are actively running the break-glass path. Set expiresAt no more than four hours out for an emergency window and keep allowedIPs scoped to the operator network. When break-glass is enabled, Sibyl denies login if either field is missing, if the expiry has passed, or if the expiry is more than four hours out.

Connect Machines ​

Once the owner can sign in, each person connects their machine with one line. The web app shows it on the Connect card, in the setup wizard's last step, and in each user's onboarding, with your server's URL filled in:

bash
# macOS
brew install hyperb1iss/tap/sibyl && sibyl setup https://sibyl.example.com

# Linux, or anywhere with uv
uv tool install --upgrade sibyl-dev && sibyl setup https://sibyl.example.com

sibyl setup signs the user in through the browser (with your OIDC provider when SSO is on), installs the Sibyl skill, and adds the Claude Code SessionStart hook. People can also hand the job to an agent with the sentence on the Connect card, such as Set up Sibyl on this machine by following https://sibyl.example.com/agent. The web app serves /agent; the API serves the same document at /api/setup/agent.md. When the web app and API have separate origins (SIBYL_FRONTEND_URL differs from the server URL), the card points agents at the API form. The /agent page and the /api/setup/connect and /api/setup/agent.md routes carry only facts anyone who reaches the server can already see: the public URL, the minimum CLI version, and the sign-in methods.

Users never enter model provider keys. When every provider the server uses is ready (each language model surface plus both embedding planes), onboarding skips the API keys step for everyone; when any one is not, only an instance admin sees it.

Released under the Apache-2.0 License.