OAuth 2.0 / OIDC

PicFast supports third-party authentication via OAuth 2.0 and OpenID Connect (OIDC). Once configured, a "Sign in with ..." button appears on the login page, and users can link or unlink providers from their account settings.

Supported providers

ProviderTypeNotes
GitHub github Pure OAuth 2.0. Uses /user and /user/emails APIs. No OIDC discovery.
Keycloak oidc Full OIDC with automatic discovery via .well-known/openid-configuration. PKCE enforced.
Any OIDC provider oidc Use type: oidc with any OIDC-compliant provider (Google, Microsoft, Authelia, etc.).

Configuration

OAuth providers are configured under the oauth.providers key in config.yaml. The recommended way is to mount a config file via Docker Compose volume.

Docker Compose volume

Add a volume mount to your docker-compose.yml:

services:
  app:
    volumes:
      - ./config.yaml:/etc/picfast/config.yaml:ro
File permissions. The container runs as 10001:10001. Make sure your config.yaml is readable by that user: chown 10001:10001 config.yaml && chmod 0644 config.yaml.

GitHub

  1. Create an OAuth App at GitHub Settings → Developer settings → OAuth Apps.
  2. Set Authorization callback URL to https://your-domain/api/v1/auth/oauth/github/callback.
  3. Copy the Client ID and generate a Client Secret.
oauth:
  providers:
    - id: github
      display_name: GitHub
      type: github
      client_id: "Iv1.xxxxxxxxxxxx"
      client_secret: "ghs_xxxxxxxxxxxxxxxxxxxx"
      enabled: true

app:
  web_base_url: "https://picfast.example.com"

Keycloak (or any OIDC provider)

  1. In your Keycloak realm, create a new client with:
    • Client type: OpenID Connect
    • Access type: confidential
    • Valid redirect URIs: https://your-domain/api/v1/auth/oauth/keycloak/callback
  2. Copy the Client ID and Client Secret from the Credentials tab.
oauth:
  providers:
    - id: keycloak
      display_name: "Keycloak SSO"
      type: oidc
      client_id: "picfast"
      client_secret: "your-keycloak-secret"
      issuer: "https://auth.example.com/realms/myrealm"
      enabled: true
      scopes:
        - openid
        - profile
        - email

app:
  web_base_url: "https://picfast.example.com"

Other OIDC providers (without discovery)

If your OIDC provider doesn't support Discovery (.well-known/openid-configuration), keep issuer set (it's required for ID token iss validation) and additionally provide auth_url, token_url, and jwks_url. userinfo_url is optional.

oauth:
  providers:
    - id: custom-oidc
      display_name: "Custom OIDC"
      type: oidc
      client_id: "your-client-id"
      client_secret: "your-secret"
      issuer: "https://idp.example.com"
      auth_url: "https://idp.example.com/authorize"
      token_url: "https://idp.example.com/token"
      userinfo_url: "https://idp.example.com/userinfo"
      jwks_url: "https://idp.example.com/certs"
      enabled: true

Multiple providers

oauth:
  providers:
    - id: keycloak
      display_name: "Keycloak SSO"
      type: oidc
      client_id: "picfast"
      client_secret: "..."
      issuer: "https://auth.example.com/realms/myrealm"
      enabled: true
    - id: github
      display_name: GitHub
      type: github
      client_id: "Iv1.xxx"
      client_secret: "ghs_xxx"
      enabled: true

Required settings

KeyDescription
app.web_base_url Required when OAuth is enabled. The frontend URL users land on after login. Must match the domain users access your site from.
server.base_url Required when OAuth is enabled. The backend URL used to construct the OAuth redirect URIs.
server.trusted_proxies CIDR list of reverse proxy IPs. Required behind nginx/traefik for secure cookie and client IP handling.

User experience

  • Login page: Provider buttons appear below the email form with a separator.
  • Account linking: Already logged-in users can connect or disconnect providers from the Settings page.
  • Auto-link: If an IdP-verified email matches an existing account, PicFast links them automatically on first login.
  • Lockout prevention: You cannot unlink your last login method unless your account has a password.

Security notes

  • PKCE is enforced for OIDC providers via S256 code challenge.
  • State cookies use HMAC with a key derived from the JWT secret to prevent CSRF.
  • Trusted proxies are required for correct X-Forwarded-Proto and X-Forwarded-For handling.
  • Auto-link only happens when the IdP declares the email as verified (email_verified: true).