OAuth/OIDC Setup
GeoLens supports SSO via OAuth 2.0 / OpenID Connect with three provider types: Google, Microsoft Entra ID, and generic OIDC (Auth0, Okta, Keycloak, Authentik, and any other OIDC-compliant IdP). All flows use PKCE (Proof Key for Code Exchange, S256) automatically. Client secrets are encrypted at rest with Fernet derived from JWT_SECRET_KEY.
Replace https://geolens.example.com with your GeoLens instance’s URL in every example below.
How OAuth works in GeoLens
Section titled “How OAuth works in GeoLens”End users do not call these endpoints directly — they sign in through the GeoLens web UI, which performs the authorization-code flow on their behalf. Once the UI has a JWT, machine clients reuse it like any other Bearer token (see API authentication).
PKCE & client-secret encryption
Section titled “PKCE & client-secret encryption”PKCE (Proof Key for Code Exchange) is enforced for every OAuth flow regardless of provider type — GeoLens generates a random code_verifier, sends the SHA-256 code_challenge on the authorize redirect, and verifies the verifier on the token exchange. This protects against authorization-code interception even on browsers without HTTPS-only contexts.
Client secrets stored in the database are encrypted at rest with Fernet (AES-128-CBC + HMAC-SHA256). The encryption key is derived from JWT_SECRET_KEY — rotating that secret invalidates every stored client secret, so coordinate rotation with re-entering each provider’s secret in the admin UI.
Configure providers via the admin UI
Section titled “Configure providers via the admin UI”The simplest way to configure OAuth is through the admin settings panel:
- Navigate to Admin → Settings → Authentication.
- Scroll to the OAuth Providers section.
- Click Add Provider.
- Select the provider type, fill in the required fields, and click Create.
Providers can be enabled, disabled, edited, or deleted from the same panel. The login screen reflects changes immediately — no restart required.
Provider configuration reference
Section titled “Provider configuration reference”Whether you use the admin UI or the API, every provider has the same configurable fields:
| Field | Required | Description |
|---|---|---|
slug | Yes | URL-safe identifier used in callback URLs (e.g. google, azure-ad) |
display_name | Yes | Label shown on the login page button |
provider_type | Yes | One of: google, microsoft, oidc |
client_id | Yes | OAuth client ID from the IdP |
client_secret | Yes | OAuth client secret |
discovery_url | No | OIDC discovery URL (.well-known/openid-configuration). Auto-populates for Google and Microsoft |
authorize_url | No | Authorization endpoint (only needed if discovery_url is not set) |
token_url | No | Token endpoint (only needed if discovery_url is not set) |
userinfo_url | No | Userinfo endpoint (only needed if discovery_url is not set) |
scopes | No | Space-separated scopes. Default: openid profile email |
default_role | No | Role assigned to new users: viewer, editor, or admin. Default: viewer |
group_claim | No | JWT claim containing group memberships (e.g. groups) |
group_role_mapping | No | JSON object mapping IdP group names to GeoLens roles |
enabled | No | Whether the provider appears on the login page. Default: true |
Provider step-by-steps
Section titled “Provider step-by-steps”- Go to the Google Cloud Console.
- Create a new OAuth 2.0 Client ID (application type: Web application).
- Add the authorized redirect URI:
https://geolens.example.com/api/auth/oauth/google/callback
- Copy the Client ID and Client Secret.
- In GeoLens, create the provider via the admin UI (Admin → Settings → Authentication → Add Provider → Google), or via the API:
curl -X POST https://geolens.example.com/api/settings/oauth-providers/ \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "google", "display_name": "Google", "provider_type": "google", "client_id": "123456789.apps.googleusercontent.com", "client_secret": "GOCSPX-xxxxxxxxxxxx", "discovery_url": "https://accounts.google.com/.well-known/openid-configuration", "scopes": "openid profile email", "default_role": "viewer", "enabled": true }'The “Sign in with Google” button appears on the login page immediately after creation.
- In the Azure Portal, navigate to Microsoft Entra ID → App registrations → New registration.
- Set the redirect URI to:
https://geolens.example.com/api/auth/oauth/microsoft/callback
- Under Certificates & secrets, create a new client secret. Save the secret value (not the secret ID) immediately — Azure shows it only once.
- Note your Application (client) ID, Directory (tenant) ID, and the secret value.
- Create the provider in GeoLens:
curl -X POST https://geolens.example.com/api/settings/oauth-providers/ \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "microsoft", "display_name": "Microsoft", "provider_type": "microsoft", "client_id": "YOUR_APPLICATION_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET_VALUE", "discovery_url": "https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0/.well-known/openid-configuration", "scopes": "openid profile email", "default_role": "viewer", "enabled": true }'The tenant-specific discovery URL embeds your Directory (tenant) ID — single-tenant installations should use this form; multi-tenant deployments can use common in place of the tenant ID with appropriate consent settings.
For any OIDC-compliant provider (Auth0, Okta, Keycloak, Authentik, etc.):
- Register a new application in your IdP. Application type: Web application with authorization-code flow.
- Set the redirect URI to:
Replacehttps://geolens.example.com/api/auth/oauth/{slug}/callback
{slug}with whatever slug you plan to use (e.g.keycloak,okta,auth0). - If the IdP publishes a discovery document, use
discovery_url. Otherwise, provideauthorize_url,token_url, anduserinfo_urlexplicitly.
curl -X POST https://geolens.example.com/api/settings/oauth-providers/ \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "keycloak", "display_name": "Keycloak", "provider_type": "oidc", "client_id": "geolens", "client_secret": "your-keycloak-secret", "discovery_url": "https://keycloak.example.com/realms/main/.well-known/openid-configuration", "scopes": "openid profile email", "default_role": "editor", "enabled": true }'For providers that don’t publish discovery (rare in 2026), supply the three endpoints manually:
{ "authorize_url": "https://idp.example.com/oauth2/authorize", "token_url": "https://idp.example.com/oauth2/token", "userinfo_url": "https://idp.example.com/oauth2/userinfo"}Group-to-role mapping
Section titled “Group-to-role mapping”If your IdP includes group memberships in the ID token or userinfo response, you can map those groups to GeoLens roles automatically. This is provider-agnostic — it works the same way for Google, Microsoft, and generic OIDC, as long as the provider emits a group claim.
- Set
group_claimto the name of the claim containing group names. Common values:groups,roles,https://example.com/claims/groups(Auth0-style namespaced claims). - Set
group_role_mappingto a JSON object mapping group names to GeoLens roles:
{ "GeoLens-Admins": "admin", "GeoLens-Editors": "editor", "GeoLens-Viewers": "viewer"}The first matching group wins. If no groups match, the user is assigned the provider’s default_role.
Example update via the API:
curl -X PATCH https://geolens.example.com/api/settings/oauth-providers/{provider_id} \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "group_claim": "groups", "group_role_mapping": { "GIS-Admins": "admin", "GIS-Staff": "editor" } }'Group-to-role mapping is re-evaluated on every login. A user removed from GIS-Admins in the IdP loses admin access at the next sign-in (or token refresh). For immediate revocation regardless of IdP state, deactivate the user in Admin → Users.
Configure programmatically
Section titled “Configure programmatically”Providers can be managed entirely via the API. All endpoints require the manage_settings capability (admin role). Obtain a JWT token first:
TOKEN=$(curl -s -X POST https://geolens.example.com/api/auth/login \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=admin&password=admin" | jq -r '.access_token')List providers
Section titled “List providers”curl https://geolens.example.com/api/settings/oauth-providers/ \ -H "Authorization: Bearer $TOKEN"The response never includes the client_secret. Secrets are write-only.
Update a provider
Section titled “Update a provider”curl -X PATCH https://geolens.example.com/api/settings/oauth-providers/{provider_id} \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"enabled": false}'Only include client_secret in the update payload if you need to rotate it. Omitting the field preserves the existing encrypted secret.
Delete a provider
Section titled “Delete a provider”curl -X DELETE https://geolens.example.com/api/settings/oauth-providers/{provider_id} \ -H "Authorization: Bearer $TOKEN"Deleting a provider also removes all linked OAuth accounts for that provider — affected users fall back to local-password login (if they have a password set) or lose access entirely.
Account linking
Section titled “Account linking”When a user signs in via OAuth, GeoLens applies these rules in order:
- Existing OAuth link. If the user has previously signed in with the same provider and subject ID, they are logged in to the existing account.
- Email match. If no prior OAuth link exists but a local user has the same email address (case-insensitive), the OAuth identity is linked to that existing user. The local password remains valid; the user can use either authentication method.
- New account. Otherwise, a new user account is created with a username derived from the email prefix or display name. The role assigned follows group-to-role mapping (if configured) or the provider’s
default_role.
This means existing local users can start using OAuth without losing their data — as long as the email addresses match. For organizations migrating from local-only auth, the recommended sequence is: enable the OAuth provider with default_role: viewer, instruct users to sign in via OAuth once (which auto-links by email), then optionally disable local-password login for OAuth-managed accounts.
See also
Section titled “See also”- User management & RBAC — for default-role assignment and the role/permission matrix
- Settings reference — system-wide auth settings beyond per-provider config
- API authentication — the JWT format the OAuth flow ultimately issues