Files
paste.es/docs/social-login.md
Malin bc9f96cbd4 feat: rebrand Hemmelig to paste.es for cloudhost.es
- Set Spanish as default language with ephemeral/encrypted privacy focus
- Translate all user-facing strings and legal pages to Spanish
- Replace Norwegian flag with Spanish flag in footer
- Remove Hemmelig/terces.cloud links, add cloudhost.es sponsorship
- Rewrite PrivacyPage: zero data collection, ephemeral design emphasis
- Rewrite TermsPage: Spanish law, RGPD, paste.es/CloudHost.es references
- Update PWA manifest, HTML meta tags, package.json branding
- Rename webhook headers to X-Paste-Event / X-Paste-Signature
- Update API docs title and contact to paste.es / cloudhost.es

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 09:30:19 +01:00

18 KiB

Social Login Configuration

Hemmelig supports multiple social login providers. Users can configure any combination of providers via environment variables. Only providers with valid credentials will be shown on the login and registration pages.

Required Configuration

Before setting up any social provider, you must set your base URL:

HEMMELIG_BASE_URL=https://your-domain.com

This is used to generate the correct OAuth callback URLs.

Supported Providers

Standard Providers

Provider Environment Variables
GitHub HEMMELIG_AUTH_GITHUB_ID, HEMMELIG_AUTH_GITHUB_SECRET
Google HEMMELIG_AUTH_GOOGLE_ID, HEMMELIG_AUTH_GOOGLE_SECRET
Microsoft HEMMELIG_AUTH_MICROSOFT_ID, HEMMELIG_AUTH_MICROSOFT_SECRET, HEMMELIG_AUTH_MICROSOFT_TENANT_ID (optional)
Discord HEMMELIG_AUTH_DISCORD_ID, HEMMELIG_AUTH_DISCORD_SECRET
GitLab HEMMELIG_AUTH_GITLAB_ID, HEMMELIG_AUTH_GITLAB_SECRET, HEMMELIG_AUTH_GITLAB_ISSUER (optional)
Apple HEMMELIG_AUTH_APPLE_ID, HEMMELIG_AUTH_APPLE_SECRET
Twitter/X HEMMELIG_AUTH_TWITTER_ID, HEMMELIG_AUTH_TWITTER_SECRET

Generic OAuth Providers

Hemmelig now supports any OAuth 2.0 / OpenID Connect provider through the generic OAuth configuration. This allows you to integrate with identity providers like:

  • Authentik
  • Authelia
  • Keycloak
  • Zitadel
  • Ory Hydra
  • Auth0 (if not using the built-in provider)
  • Okta
  • Any other OAuth 2.0 / OpenID Connect compatible provider

Use the HEMMELIG_AUTH_GENERIC_OAUTH environment variable with a JSON array of provider configurations.

Environment Variable: HEMMELIG_AUTH_GENERIC_OAUTH

Generic OAuth Configuration Format

Each provider in the array must include:

Field Required Description
providerId Yes Unique identifier for the provider (used in callback URLs)
clientId Yes OAuth client ID from your identity provider
clientSecret Yes OAuth client secret from your identity provider
discoveryUrl No* OpenID Connect discovery URL (e.g., /.well-known/openid-configuration)
authorizationUrl No* OAuth authorization endpoint (required if no discoveryUrl)
tokenUrl No* OAuth token endpoint (required if no discoveryUrl)
userInfoUrl No* OAuth user info endpoint (required if no discoveryUrl)
scopes No Array of OAuth scopes (default: ["openid", "profile", "email"])
pkce No Enable PKCE (Proof Key for Code Exchange) - recommended for public clients

*You must provide either discoveryUrl OR all three of (authorizationUrl, tokenUrl, userInfoUrl).

Example: Authentik

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"authentik","discoveryUrl":"https://auth.example.com/application/o/hemmelig/.well-known/openid-configuration","clientId":"your-client-id","clientSecret":"your-client-secret","scopes":["openid","profile","email"]}]

Example: Authelia

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"authelia","discoveryUrl":"https://auth.example.com/.well-known/openid-configuration","clientId":"hemmelig","clientSecret":"your-client-secret","scopes":["openid","profile","email","groups"]}]

Example: Keycloak

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"keycloak","discoveryUrl":"https://keycloak.example.com/realms/myrealm/.well-known/openid-configuration","clientId":"hemmelig","clientSecret":"your-client-secret","scopes":["openid","profile","email"]}]

Example: Multiple Generic Providers

You can configure multiple generic OAuth providers in the same JSON array:

HEMMELIG_AUTH_GENERIC_OAUTH=[
  {
    "providerId": "authentik",
    "discoveryUrl": "https://auth.example.com/application/o/hemmelig/.well-known/openid-configuration",
    "clientId": "client-id-1",
    "clientSecret": "secret-1",
    "scopes": ["openid", "profile", "email"]
  },
  {
    "providerId": "keycloak",
    "discoveryUrl": "https://keycloak.example.com/realms/myrealm/.well-known/openid-configuration",
    "clientId": "client-id-2",
    "clientSecret": "secret-2"
  }
]

Example: Manual URLs (without discovery)

If your provider doesn't support OpenID Connect discovery:

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"custom","authorizationUrl":"https://oauth.example.com/authorize","tokenUrl":"https://oauth.example.com/token","userInfoUrl":"https://oauth.example.com/userinfo","clientId":"your-client-id","clientSecret":"your-client-secret","scopes":["openid","profile","email"]}]

Callback URLs

When configuring your OAuth applications, use these callback URLs:

Standard Providers

Provider Callback URL
GitHub https://your-domain.com/api/auth/callback/github
Google https://your-domain.com/api/auth/callback/google
Microsoft https://your-domain.com/api/auth/callback/microsoft
Discord https://your-domain.com/api/auth/callback/discord
GitLab https://your-domain.com/api/auth/callback/gitlab
Apple https://your-domain.com/api/auth/callback/apple
Twitter/X https://your-domain.com/api/auth/callback/twitter

Generic OAuth Providers

For generic OAuth providers, the callback URL format is:

https://your-domain.com/api/auth/oauth2/callback/{providerId}

Where {providerId} is the value you specified in the providerId field.

Examples:

  • Authentik: https://your-domain.com/api/auth/oauth2/callback/authentik
  • Authelia: https://your-domain.com/api/auth/oauth2/callback/authelia
  • Keycloak: https://your-domain.com/api/auth/oauth2/callback/keycloak

Configuration

Add the environment variables for the providers you want to enable. Both _ID and _SECRET must be set for a standard provider to be enabled.

Example: Docker Compose

services:
    hemmelig:
        image: hemmelig/hemmelig:latest
        environment:
            # Required: Base URL for OAuth callbacks
            - HEMMELIG_BASE_URL=https://your-domain.com

            # Standard providers (GitHub example)
            - HEMMELIG_AUTH_GITHUB_ID=your-github-client-id
            - HEMMELIG_AUTH_GITHUB_SECRET=your-github-client-secret

            # Generic OAuth provider (Authentik example)
            - HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"authentik","discoveryUrl":"https://auth.example.com/application/o/hemmelig/.well-known/openid-configuration","clientId":"your-client-id","clientSecret":"your-client-secret","scopes":["openid","profile","email"]}]

Example: Environment File (.env)

# Required: Base URL for OAuth callbacks
HEMMELIG_BASE_URL=https://your-domain.com

# GitHub OAuth
HEMMELIG_AUTH_GITHUB_ID=your-github-client-id
HEMMELIG_AUTH_GITHUB_SECRET=your-github-client-secret

# Google OAuth
HEMMELIG_AUTH_GOOGLE_ID=your-google-client-id
HEMMELIG_AUTH_GOOGLE_SECRET=your-google-client-secret

# Microsoft OAuth (Azure AD)
HEMMELIG_AUTH_MICROSOFT_ID=your-microsoft-client-id
HEMMELIG_AUTH_MICROSOFT_SECRET=your-microsoft-client-secret
HEMMELIG_AUTH_MICROSOFT_TENANT_ID=your-tenant-id  # Optional, defaults to "common"

# Discord OAuth
HEMMELIG_AUTH_DISCORD_ID=your-discord-client-id
HEMMELIG_AUTH_DISCORD_SECRET=your-discord-client-secret

# GitLab OAuth
HEMMELIG_AUTH_GITLAB_ID=your-gitlab-client-id
HEMMELIG_AUTH_GITLAB_SECRET=your-gitlab-client-secret
HEMMELIG_AUTH_GITLAB_ISSUER=https://gitlab.example.com  # Optional, for self-hosted GitLab

# Apple OAuth
HEMMELIG_AUTH_APPLE_ID=your-apple-client-id
HEMMELIG_AUTH_APPLE_SECRET=your-apple-client-secret

# Twitter/X OAuth
HEMMELIG_AUTH_TWITTER_ID=your-twitter-client-id
HEMMELIG_AUTH_TWITTER_SECRET=your-twitter-client-secret

# Generic OAuth (supports Authentik, Authelia, Keycloak, etc.)
HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"authentik","discoveryUrl":"https://auth.example.com/application/o/hemmelig/.well-known/openid-configuration","clientId":"your-client-id","clientSecret":"your-client-secret","scopes":["openid","profile","email"]}]

Setting Up OAuth Applications

Standard Providers

GitHub

  1. Go to GitHub Developer Settings
  2. Click "New OAuth App"
  3. Set the callback URL to: https://your-domain.com/api/auth/callback/github
  4. Copy the Client ID and Client Secret

Google

  1. Go to Google Cloud Console
  2. Create a new OAuth 2.0 Client ID
  3. Set the authorized redirect URI to: https://your-domain.com/api/auth/callback/google
  4. Copy the Client ID and Client Secret

Microsoft (Azure AD)

  1. Go to Azure Portal
  2. Register a new application
  3. Add a redirect URI: https://your-domain.com/api/auth/callback/microsoft
  4. Create a client secret under "Certificates & secrets"
  5. Copy the Application (client) ID and the client secret value
  6. Optionally set the Tenant ID for single-tenant apps

Discord

  1. Go to Discord Developer Portal
  2. Create a new application
  3. Go to OAuth2 settings
  4. Add redirect URL: https://your-domain.com/api/auth/callback/discord
  5. Copy the Client ID and Client Secret

GitLab

  1. Go to GitLab User Settings > Applications
  2. Create a new application
  3. Set the redirect URI to: https://your-domain.com/api/auth/callback/gitlab
  4. Select the read_user scope
  5. Copy the Application ID and Secret

Self-hosted GitLab: If you're using a self-hosted GitLab instance, set the HEMMELIG_AUTH_GITLAB_ISSUER environment variable to your GitLab instance URL (e.g., https://gitlab.example.com). Without this, GitLab.com is used by default.

Apple

  1. Go to Apple Developer Portal
  2. Create a Services ID
  3. Configure Sign in with Apple, add your domain and return URL: https://your-domain.com/api/auth/callback/apple
  4. Create a key for Sign in with Apple
  5. Use the Services ID as Client ID and generate the client secret from the key

Twitter/X

  1. Go to Twitter Developer Portal
  2. Create a new project and app
  3. Enable OAuth 2.0
  4. Set the callback URL to: https://your-domain.com/api/auth/callback/twitter
  5. Copy the Client ID and Client Secret

Generic OAuth Providers

Authentik

  1. Log into your Authentik instance as an admin
  2. Go to Applications > Providers > Create
  3. Select OAuth2/OpenID Provider
  4. Configure the provider:
    • Name: Hemmelig
    • Authorization flow: Select your flow (e.g., default-authentication-flow)
    • Redirect URIs: https://your-domain.com/api/auth/oauth2/callback/authentik
    • Client type: Confidential
    • Scopes: openid, profile, email
  5. Save and copy the Client ID and Client Secret
  6. Create an application and bind it to this provider
  7. Find your discovery URL (usually https://auth.example.com/application/o/hemmelig/.well-known/openid-configuration)

Example environment variable:

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"authentik","discoveryUrl":"https://auth.example.com/application/o/hemmelig/.well-known/openid-configuration","clientId":"<client-id>","clientSecret":"<client-secret>","scopes":["openid","profile","email"]}]

Authelia

  1. Edit your Authelia configuration file (configuration.yml)
  2. Add Hemmelig as a client under identity_providers.oidc.clients:
    clients:
        - id: hemmelig
          description: Hemmelig Secret Sharing
          secret: <generate-a-secure-secret>
          redirect_uris:
              - https://your-domain.com/api/auth/oauth2/callback/authelia
          scopes:
              - openid
              - profile
              - email
              - groups
    
  3. Restart Authelia
  4. Your discovery URL will be: https://auth.example.com/.well-known/openid-configuration

Example environment variable:

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"authelia","discoveryUrl":"https://auth.example.com/.well-known/openid-configuration","clientId":"hemmelig","clientSecret":"<client-secret>","scopes":["openid","profile","email"]}]

Keycloak

  1. Log into your Keycloak admin console
  2. Select your realm (or create a new one)
  3. Go to Clients > Create client
  4. Configure the client:
    • Client type: OpenID Connect
    • Client ID: hemmelig
  5. On the next screen:
    • Client authentication: ON
    • Valid redirect URIs: https://your-domain.com/api/auth/oauth2/callback/keycloak
    • Web origins: https://your-domain.com
  6. Go to the Credentials tab and copy the Client Secret
  7. Your discovery URL will be: https://keycloak.example.com/realms/{realm-name}/.well-known/openid-configuration

Example environment variable:

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"keycloak","discoveryUrl":"https://keycloak.example.com/realms/myrealm/.well-known/openid-configuration","clientId":"hemmelig","clientSecret":"<client-secret>"}]

Zitadel

  1. Log into your Zitadel instance
  2. Go to your project (or create a new one)
  3. Create a new application:
    • Type: Web
    • Authentication method: PKCE or Code
  4. Configure:
    • Redirect URIs: https://your-domain.com/api/auth/oauth2/callback/zitadel
    • Post logout redirect URIs: https://your-domain.com
  5. Copy the Client ID and Client Secret (if using Code flow)
  6. Your discovery URL: https://<instance>.zitadel.cloud/.well-known/openid-configuration

Example environment variable:

HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"zitadel","discoveryUrl":"https://instance.zitadel.cloud/.well-known/openid-configuration","clientId":"<client-id>","clientSecret":"<client-secret>","scopes":["openid","profile","email"],"pkce":true}]

How It Works

  1. On server startup, the application reads all HEMMELIG_AUTH_* environment variables
  2. Only providers with both _ID and _SECRET set are enabled
  3. The frontend fetches the list of enabled providers from /api/config/social-providers
  4. Login and registration pages dynamically show buttons only for enabled providers
  5. Each provider button uses the correct branded icon and colors
  6. The callback URL is built using HEMMELIG_BASE_URL + /api/auth/callback/{provider}

All Environment Variables

# Required for OAuth
HEMMELIG_BASE_URL=https://your-domain.com

# GitHub
HEMMELIG_AUTH_GITHUB_ID=
HEMMELIG_AUTH_GITHUB_SECRET=

# Google
HEMMELIG_AUTH_GOOGLE_ID=
HEMMELIG_AUTH_GOOGLE_SECRET=

# Microsoft (Azure AD)
HEMMELIG_AUTH_MICROSOFT_ID=
HEMMELIG_AUTH_MICROSOFT_SECRET=
HEMMELIG_AUTH_MICROSOFT_TENANT_ID=  # Optional

# Discord
HEMMELIG_AUTH_DISCORD_ID=
HEMMELIG_AUTH_DISCORD_SECRET=

# GitLab
HEMMELIG_AUTH_GITLAB_ID=
HEMMELIG_AUTH_GITLAB_SECRET=
HEMMELIG_AUTH_GITLAB_ISSUER=  # Optional, for self-hosted GitLab (e.g., https://gitlab.example.com)

# Apple
HEMMELIG_AUTH_APPLE_ID=
HEMMELIG_AUTH_APPLE_SECRET=

# Twitter/X
HEMMELIG_AUTH_TWITTER_ID=
HEMMELIG_AUTH_TWITTER_SECRET=

# Generic OAuth (JSON array - supports any OAuth 2.0 / OIDC provider)
HEMMELIG_AUTH_GENERIC_OAUTH=[{"providerId":"authentik","discoveryUrl":"https://auth.example.com/.well-known/openid-configuration","clientId":"client-id","clientSecret":"client-secret","scopes":["openid","profile","email"]}]

Troubleshooting

Provider not showing up

Standard providers:

  • Ensure both _ID and _SECRET environment variables are set
  • Restart the server after adding environment variables
  • Check server logs for any configuration errors

Generic OAuth providers:

  • Verify the JSON in HEMMELIG_AUTH_GENERIC_OAUTH is valid
  • Check that each provider has providerId, clientId, and clientSecret
  • Verify you have either discoveryUrl OR all three URLs (authorizationUrl, tokenUrl, userInfoUrl)
  • Check server logs for parsing errors

OAuth callback errors

Standard providers:

  • Verify the callback URL in your OAuth app settings matches exactly
  • Format: https://your-domain.com/api/auth/callback/{provider}

Generic OAuth providers:

  • Callback URL format: https://your-domain.com/api/auth/oauth2/callback/{providerId}
  • Ensure the providerId in your config matches the one in your identity provider settings

Common issues:

  • Ensure HEMMELIG_BASE_URL is set correctly (no trailing slash)
  • Ensure your domain is using HTTPS in production
  • Check that the client ID and secret are correct (no extra spaces)

"Access Denied" errors

  • Verify the OAuth app has the correct permissions/scopes
  • For Microsoft, ensure the app is configured for the correct account types
  • For Apple, ensure the Services ID is correctly configured
  • For generic OAuth: Check that the requested scopes are allowed by your provider

Discovery URL errors (Generic OAuth)

  • Verify the discovery URL is accessible: curl https://your-auth-provider/.well-known/openid-configuration
  • Ensure your Hemmelig instance can reach the discovery URL (check firewall rules)
  • Try using manual URLs (authorizationUrl, tokenUrl, userInfoUrl) instead if discovery is not supported