Skip to content

SSO Authentication Setup Guide

DocShare supports multiple SSO providers including OAuth2/OIDC (Google, GitHub, Keycloak, Authentik), SAML (Okta, Azure AD), and LDAP/Active Directory.

Table of Contents

  1. Quick Start
  2. OAuth2/OIDC Providers
  3. Google
  4. GitHub
  5. OIDC (Keycloak, Authentik)
  6. SAML
  7. LDAP/Active Directory
  8. Environment Variables
  9. API Endpoints

Quick Start

Docker Compose

Enable SSO by adding an override file:

# Google OAuth2
docker-compose -f docker-compose.yml -f examples/docker-compose/sso/google/docker-compose.yml up -d

# GitHub OAuth2  
docker-compose -f docker-compose.yml -f examples/docker-compose/sso/github/docker-compose.yml up -d

# Keycloak OIDC
docker-compose -f docker-compose.yml -f examples/docker-compose/sso/keycloak/docker-compose.yml up -d

# LDAP
docker-compose -f docker-compose.yml -f examples/docker-compose/sso/ldap/docker-compose.yml up -d

Helm

helm install docshare oci://ghcr.io/hayward-solutions/charts/docshare \
  --namespace docshare \
  -f examples/helm/sso.yaml \
  --set sso.oidc.clientSecret=$OIDC_CLIENT_SECRET

The Helm chart exposes every provider under sso.*. For OIDC, the only required field is sso.oidc.issuerUrl; DocShare discovers the authorization, token, userinfo, and JWKS endpoints automatically.

sso:
  oidc:
    enabled: true
    clientId: docshare
    clientSecret: ""          # prefer --set or sso.existingSecret
    issuerUrl: https://keycloak.example.com/realms/docshare
    scopes: "openid,profile,email"

Secrets can also be supplied via an existing Kubernetes Secret:

sso:
  existingSecret: docshare-sso   # keys: OAUTH_OIDC_CLIENT_SECRET, OAUTH_GOOGLE_CLIENT_SECRET, ...
  oidc:
    enabled: true
    clientId: docshare
    issuerUrl: https://keycloak.example.com/realms/docshare

OAuth2/OIDC Providers

Google OAuth2

  1. Go to Google Cloud Console
  2. Create a new project
  3. Navigate to APIs & Services > Credentials
  4. Create OAuth 2.0 Client ID (Web application)
  5. Add authorized redirect URI:
    http://localhost:8080/api/auth/sso/oauth/google/callback
    
  6. Add authorized JavaScript origins:
    http://localhost:8080
    
  7. Copy Client ID and Client Secret

Docker Compose:

export GOOGLE_CLIENT_ID="your-client-id"
export GOOGLE_CLIENT_SECRET="your-client-secret"
docker-compose -f docker-compose.yml -f examples/docker-compose/sso/google/docker-compose.yml up -d

Environment Variables:

OAUTH_GOOGLE_ENABLED=true
OAUTH_GOOGLE_CLIENT_ID=your-client-id
OAUTH_GOOGLE_CLIENT_SECRET=your-client-secret
OAUTH_GOOGLE_REDIRECT_URL=http://localhost:8080/api/auth/sso/oauth/google/callback
OAUTH_GOOGLE_SCOPES=openid,email,profile

GitHub OAuth2

  1. Go to GitHub Developer Settings
  2. Create a new OAuth App
  3. Homepage URL: http://localhost:3001
  4. Authorization callback URL:
    http://localhost:8080/api/auth/sso/oauth/github/callback
    
  5. Copy Client ID and generate Client Secret

Docker Compose:

export GITHUB_CLIENT_ID="your-client-id"
export GITHUB_CLIENT_SECRET="your-client-secret"
docker-compose -f docker-compose.yml -f examples/docker-compose/sso/github/docker-compose.yml up -d

Environment Variables:

OAUTH_GITHUB_ENABLED=true
OAUTH_GITHUB_CLIENT_ID=your-client-id
OAUTH_GITHUB_CLIENT_SECRET=your-client-secret
OAUTH_GITHUB_REDIRECT_URL=http://localhost:8080/api/auth/sso/oauth/github/callback
OAUTH_GITHUB_SCOPES=read:user,user:email

OIDC (Keycloak, Authentik, Auth0, Okta, Azure AD, …)

DocShare speaks standard OpenID Connect. Endpoints are resolved from the IdP's discovery document at {issuerUrl}/.well-known/openid-configuration, and every login verifies the id_token signature, issuer, audience, expiration, and nonce against the IdP's JWKS. You only need to supply the issuer URL, client ID, and client secret — DocShare figures out the rest.

Callback URL to register with your IdP:

{API_URL}/auth/sso/oauth/oidc/callback
(e.g. http://localhost:8080/api/auth/sso/oauth/oidc/callback for local dev.)

Common Environment Variables:

OAUTH_OIDC_ENABLED=true
OAUTH_OIDC_CLIENT_ID=docshare
OAUTH_OIDC_CLIENT_SECRET=your-client-secret
OAUTH_OIDC_ISSUER_URL=https://your-idp.example.com/realms/docshare
OAUTH_OIDC_REDIRECT_URL=http://localhost:8080/api/auth/sso/oauth/oidc/callback
OAUTH_OIDC_SCOPES=openid,profile,email
# OAUTH_OIDC_SKIP_ISSUER_VERIFICATION=true  # only if your IdP returns a mismatched `iss`

Keycloak

  1. Start Keycloak:

    docker-compose -f docker-compose.yml -f examples/docker-compose/sso/keycloak/docker-compose.yml up -d
    

  2. Access the Keycloak admin console at http://localhost:8180 (admin / admin).

  3. Create a realm named docshare.

  4. Create a Client:

  5. Client ID: docshare
  6. Client Protocol: openid-connect
  7. Access Type: confidential
  8. Valid Redirect URIs: http://localhost:8080/api/auth/sso/oauth/oidc/callback
  9. Web Origins: http://localhost:8080

  10. Copy the client secret from the Credentials tab.

  11. Issuer URL: http://localhost:8180/realms/docshare

Authentik

  1. Create an OAuth2/OpenID Provider:
  2. Client type: Confidential
  3. Redirect URIs: {API_URL}/auth/sso/oauth/oidc/callback
  4. Signing key: any RSA key
  5. Attach it to an Application.
  6. Issuer URL: https://authentik.example.com/application/o/<app-slug>/ (note the trailing slash — Authentik includes it in the iss claim).

Auth0

  1. Create a Regular Web Application.
  2. Allowed Callback URLs: {API_URL}/auth/sso/oauth/oidc/callback
  3. Issuer URL: https://YOUR_TENANT.auth0.com/ (trailing slash required).

Okta

  1. Create a new OIDC Web App.
  2. Sign-in redirect URI: {API_URL}/auth/sso/oauth/oidc/callback
  3. Issuer URL: https://YOUR_ORG.okta.com/oauth2/default (or the custom authorization server issuer you use).

Azure AD (Microsoft Entra ID)

  1. App registrations → New registration.
  2. Redirect URI (Web): {API_URL}/auth/sso/oauth/oidc/callback
  3. Certificates & secrets → New client secret.
  4. Issuer URL: https://login.microsoftonline.com/{tenant-id}/v2.0

SAML

Okta SAML Setup

  1. Create a new SAML Application in Okta Admin Console

  2. Configure SAML Settings:

  3. Single sign-on URL: http://localhost:8080/api/auth/sso/saml/acs
  4. Audience URI (SP Entity ID): http://localhost:8080
  5. Name ID format: EmailAddress
  6. Attribute Statements:

    • email → user.email
    • firstName → user.firstName
    • lastName → user.lastName
  7. Copy the IdP Metadata URL

Environment Variables:

SAML_ENABLED=true
SAML_IDP_METADATA_URL=https://your-org.okta.com/app/abc123/sso/saml
SAML_SP_ENTITY_ID=http://localhost:8080
SAML_SP_ACS_URL=http://localhost:8080/api/auth/sso/saml/acs

Azure AD SAML Setup

  1. Register DocShare as an Enterprise Application in Azure AD

  2. Configure Single Sign-On with SAML:

  3. Identifier (Entity ID): http://localhost:8080
  4. Reply URL: http://localhost:8080/api/auth/sso/saml/acs
  5. User attributes:

    • user.email
    • user.givenName
    • user.surname
  6. Download Federation Metadata XML

Environment Variables:

SAML_ENABLED=true
SAML_IDP_METADATA_URL=https://login.microsoftonline.com/{tenant}/federationmetadata/2007-06/federationmetadata.xml
SAML_SP_ENTITY_ID=http://localhost:8080
SAML_SP_ACS_URL=http://localhost:8080/api/auth/sso/saml/acs


LDAP/Active Directory

OpenLDAP

Start with the LDAP compose file:

docker-compose -f docker-compose.yml -f examples/docker-compose/sso/ldap/docker-compose.yml up -d

Access phpLDAPadmin at http://localhost:8081

Environment Variables:

LDAP_ENABLED=true
LDAP_URL=ldap://ldap:389
LDAP_BIND_DN=cn=admin,dc=docshare,dc=local
LDAP_BIND_PASSWORD=admin
LDAP_SEARCH_BASE=dc=docshare,dc=local
LDAP_USER_FILTER=(uid=%s)
LDAP_EMAIL_FIELD=mail
LDAP_NAME_FIELDS=cn

Active Directory

LDAP_ENABLED=true
LDAP_URL=ldap://your-ad-server:389
LDAP_BIND_DN=cn=docshare,cn=Users,dc=example,dc=com
LDAP_BIND_PASSWORD=your-password
LDAP_SEARCH_BASE=dc=example,dc=com
LDAP_USER_FILTER=(sAMAccountName=%s)
LDAP_EMAIL_FIELD=userPrincipalName
LDAP_NAME_FIELDS=givenName,sn

Environment Variables

Variable Description Example
General
SSO_AUTO_REGISTER Auto-create user on first SSO login true
SSO_DEFAULT_ROLE Default role for new SSO users user
Google
OAUTH_GOOGLE_ENABLED Enable Google OAuth true
OAUTH_GOOGLE_CLIENT_ID Google Client ID xxx.apps.googleusercontent.com
OAUTH_GOOGLE_CLIENT_SECRET Google Client Secret xxx
OAUTH_GOOGLE_REDIRECT_URL Callback URL http://localhost:8080/api/auth/sso/oauth/google/callback
GitHub
OAUTH_GITHUB_ENABLED Enable GitHub OAuth true
OAUTH_GITHUB_CLIENT_ID GitHub Client ID xxx
OAUTH_GITHUB_CLIENT_SECRET GitHub Client Secret xxx
OIDC
OAUTH_OIDC_ENABLED Enable OIDC true
OAUTH_OIDC_CLIENT_ID OIDC Client ID docshare
OAUTH_OIDC_CLIENT_SECRET OIDC Client Secret xxx
OAUTH_OIDC_ISSUER_URL OIDC Issuer URL (endpoints auto-discovered) https://keycloak.example.com/realms/docshare
OAUTH_OIDC_REDIRECT_URL Callback URL (auto-derived from API_URL) https://docshare.example.com/api/auth/sso/oauth/oidc/callback
OAUTH_OIDC_SCOPES Scopes to request openid,profile,email
OAUTH_OIDC_SKIP_ISSUER_VERIFICATION Skip iss claim verification (for non-compliant IdPs) false
SAML
SAML_ENABLED Enable SAML true
SAML_IDP_METADATA_URL IdP Metadata URL https://idp.example.com/metadata
SAML_SP_ENTITY_ID SP Entity ID http://localhost:8080
SAML_SP_ACS_URL SP ACS URL http://localhost:8080/api/auth/sso/saml/acs
LDAP
LDAP_ENABLED Enable LDAP true
LDAP_URL LDAP Server URL ldap://localhost:389
LDAP_BIND_DN Bind DN cn=admin,dc=example,dc=com
LDAP_BIND_PASSWORD Bind Password xxx
LDAP_SEARCH_BASE Search Base dc=example,dc=com
LDAP_USER_FILTER User Search Filter (uid=%s) or (sAMAccountName=%s)
LDAP_EMAIL_FIELD Email Attribute mail or userPrincipalName
LDAP_NAME_FIELDS Name Attributes givenName,sn

API Endpoints

List Available Providers

GET /api/auth/sso/providers

Response:

[
  {"name": "google", "displayName": "Google", "type": "oauth"},
  {"name": "github", "displayName": "GitHub", "type": "oauth"},
  {"name": "oidc", "displayName": "OpenID Connect", "type": "oidc"},
  {"name": "saml", "displayName": "Enterprise SSO (SAML)", "type": "saml"},
  {"name": "ldap", "displayName": "Corporate Directory (LDAP)", "type": "ldap"}
]

OAuth2/OIDC Login

GET /api/auth/sso/oauth/{provider}

Redirects to provider authorization page.

OAuth2/OIDC Callback

GET /api/auth/sso/oauth/{provider}/callback?code=xxx&state=xxx

Returns JWT token and user:

{
  "success": true,
  "data": {
    "token": "eyJ...",
    "user": {...}
  }
}

SAML Metadata

GET /api/auth/sso/saml/metadata

Returns SP metadata XML for IdP configuration.

SAML ACS

POST /api/auth/sso/saml/acs

LDAP Login

POST /api/auth/sso/ldap/login

Request:

{
  "username": "john",
  "password": "xxx"
}

Response:

{
  "success": true,
  "data": {
    "token": "eyJ...",
    "user": {...}
  }
}

Linked Accounts

GET /api/auth/linked-accounts
DELETE /api/auth/linked-accounts/:id
POST /api/auth/linked-accounts/link

Security Considerations

  1. Use HTTPS in production - Never use HTTP for SSO
  2. Rotate secrets regularly - Update client secrets periodically
  3. Validate redirect URLs - Only allow pre-registered redirect URLs
  4. Enable audit logging - Monitor SSO authentication events
  5. Configure session timeout - Balance security with user experience