Skip to content

Self-Hosting

This guide is for anyone running the logi server themselves. If you only want to integrate OAuth, the managed IdP (https://1pass.dev) path in the Quickstart is much faster.

When you need self-hosting

  • Contributor: you modify or contribute to the logi server code.
  • Enterprise: you need to run an IdP in isolation, serving only your internal users.
  • Compliance: user data must not leave your own infrastructure (for example, a domestic data center or on-prem).
  • Local integration testing: reproducible scenarios that the managed IdP's sandbox alone can't cover (for example, time manipulation or direct DB inspection).

For most RP integrations, the sandbox tier of the managed IdP is enough.

Requirements

ComponentVersion
Ruby3.3+
Rails8.0+
PostgreSQL16+
Redis7+ (for the SolidQueue / rate-limit backend)
Node.js20+ (for building JS assets)

Required environment variables:

bash
SECRET_KEY_BASE=<output of rails secret>
DATABASE_URL=postgres://localhost/logi_development
RAILS_ENV=development

# OAuth provider (Sign in with Apple / Google) — optional; without it, email login only
APPLE_TEAM_ID=...
APPLE_KEY_ID=...
APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
APPLE_DEFAULT_CLIENT_ID=com.example.app

GOOGLE_OAUTH_CLIENT_ID=...
GOOGLE_OAUTH_CLIENT_SECRET=...

# APNs (mobile push approval — optional)
APNS_KEY_ID=...
APNS_TEAM_ID=...
APNS_KEY_PATH=/path/to/AuthKey_XXXXX.p8
APNS_TOPIC=com.example.app
APNS_TOPIC_MACOS=com.example.app.mac      # if the macOS app is a separate bundle
APNS_ENV=development

# OIDC discovery (the self-hosted issuer URL in production)
OIDC_ISSUER=https://idp.example.com
APP_HOST=idp.example.com                  # :host for Rails default_url_options
LOGI_API_HOST=api.example.com             # when splitting hosts — the quickstart/registering-apps host gate
LOGI_ADMIN_API_HOST=admin.example.com     # admin route gate (optional)

# WebAuthn (Passkey)
WEBAUTHN_ORIGIN=https://idp.example.com
WEBAUTHN_RP_ID=example.com

# Android App Links (assetlinks.json) — when running a mobile app
ANDROID_APP_CERT_SHA256=AB:CD:...

# Operational toggles (recommended in production)
ENFORCE_CANONICAL_RESOLUTION=true         # enforce canonical_sub after a merge (see the account-merge guide for details)
SOLID_QUEUE_IN_PUMA=true                  # run SolidQueue inside puma without a separate worker process
JOB_CONCURRENCY=1                         # SolidQueue concurrency
LOGI_BETA_AUTO_APPROVE=false              # public-client beta auto-approval (beta period only)

# External SaaS — optional, depending on the features you use
RESEND_API_KEY=re_...                     # email delivery
TELEGRAM_ADMIN_BOT_TOKEN=...              # production-promotion alerts
TELEGRAM_ADMIN_CHAT_ID=...
FCM_PROJECT_ID=...                        # Android push
FCM_SERVICE_ACCOUNT_JSON_PATH=/path/to/sa.json

Production host separation

The managed IdP (https://1pass.dev) splits the OAuth/OIDC endpoints onto api.1pass.dev and the console / developer portal onto start.1pass.dev. If you want the same host separation in your self-hosted production, set up LOGI_API_HOST plus the console host environment variables separately; if you'd rather run everything on a single host, point them all at the same domain and the host_constraint simply passes through (in development/test environments, it automatically runs on a single host).

Setup

Source access is provided during onboarding/partnership — contact support@1pass.dev. Replace <your-logi-repo> below with the repository URL you receive.

bash
git clone <your-logi-repo>
cd logi
bundle install
bin/rails db:setup
bin/rails server

The server runs at http://localhost:3000. A separate worker process isn't needed in development, since SolidQueue runs inside puma.

Registering your first OAuth app (local)

In a self-hosted environment, every quickstart command works against $LOGI=http://localhost:3000.

1) Create a developer account and sign in

bash
export LOGI="http://localhost:3000"

curl -s -c /tmp/cookies.txt -X POST "$LOGI/developer/signup" \
  -H 'Content-Type: application/json' \
  -d '{"user": {"email_address": "dev@example.com", "password": "correctHorseBatteryStaple"}}'

2) Issue a Personal API Key

/api/v1/applications uses PAK (Personal API Key) Bearer authentication. Issue a PAK once using the session cookie:

bash
curl -s -b /tmp/cookies.txt -X POST "$LOGI/api/v1/me/api_keys" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Quickstart CLI",
    "scopes": ["apps:manage", "apps:read"]
  }' | tee /tmp/pak.json

PAK=$(python3 -c 'import json; print(json.load(open("/tmp/pak.json"))["plaintext"])')

3) Register the OAuth app

bash
curl -s -X POST "$LOGI/api/v1/applications" \
  -H "Authorization: Bearer $PAK" \
  -H 'Content-Type: application/json' \
  -d '{
    "application": {
      "name": "My Local App",
      "redirect_uris": ["http://localhost:4000/auth/callback"],
      "allowed_scopes": ["profile", "email"]
    }
  }' | tee /tmp/app.json

CLIENT_ID=$(python3 -c 'import json; print(json.load(open("/tmp/app.json"))["client_id"])')
CLIENT_SECRET=$(python3 -c 'import json; print(json.load(open("/tmp/app.json"))["client_secret"])')

You can also create it with a form on the web portal (http://localhost:3000/developer/applications/new).

4) Sign up a test end user

bash
curl -s -c /tmp/user-cookies.txt -X POST "$LOGI/signup" \
  -H 'Content-Type: application/json' \
  -d '{"user": {"email_address": "user@example.com", "password": "correctHorseBatteryStaple", "device_uuid": "demo-device-1"}}'

From here, follow steps 4–7 of the Quickstart (PKCE → authorize → token → userinfo) as-is, but adjust the environment variables to your self-hosted values:

bash
export LOGI="http://localhost:3000"
export CLIENT_ID="logi_..."        # the value from step 3) above
export CLIENT_SECRET="..."         # the value from step 3) above
export REDIRECT="http://localhost:4000/auth/callback"

Operational considerations

Additional items to review when you self-operate:

When you need help

For installation issues, use GitHub Issues; for operational discussions, please contact us through the admin contact channel (FAB).

Identity가 제품의 신뢰를 만듭니다.