Identity providers and SSO
Configure Google, Microsoft, Keycloak, and custom OpenID Connect sign-in.
Identity providers and SSO
Logship supports OpenID Connect (OIDC) authorization code login with PKCE. Configure providers in System → Identity providers. Google, Microsoft, and Keycloak presets populate the common settings; custom OIDC servers use the same flow.
Providers authenticate users and apply their own MFA policies. External sign-in does not guarantee that MFA occurred. Logship does not enroll second factors or verify provider-specific MFA assurance claims. Logship permissions remain manually managed.
Sign-in settings
In System → Identity providers → Sign-in URLs, set the public backend URL and frontend URL, then save. These settings are persisted centrally and apply to every HTTP host without restarting. The UI suggests browser-visible URLs for convenience; they are used only after an administrator explicitly saves them. Copy the displayed callback URL into the provider's application registration.
Enable Allow HTTP for local development only when using local HTTP endpoints. Production URLs must use HTTPS. Updating these settings invalidates pending logins so that a callback never mixes old and new URLs.
No encryption-key configuration is required for normal setup. The database service automatically creates a 256-bit key file beside its SQLite catalog (<catalog-filename>.identity-key) on first use. On Unix it is created with owner-only read/write permissions. Encryption is performed by the catalog service, so HTTP hosts do not need their own copy of this key. Include this file in catalog backup and failover procedures; it is intentionally kept outside the database. A missing key is never silently replaced while managed encrypted identities still exist.
For unattended bootstrap, the same URLs and development policy can be seeded from JSON:
{
"backend": {
"services": {
"accountsService": {
"identity": {
"publicBackendUrl": "https://api.example.com",
"frontendUrl": "https://app.example.com",
"providers": []
}
}
}
}
}JSON initializes the persisted sign-in settings only when none exist. Later UI edits win over deployment JSON on every host and survive restarts. Existing deployments with configured JSON URLs are migrated automatically during bootstrap. Empty JSON defaults leave the initial setup editable in the UI. allowHttpForDevelopment: true is also available for unattended local development.
The callback registered with each provider is:
https://api.example.com/auth/identity/callbackThe frontend completion route is /login/identity/redirect. Configure proxies to preserve the backend /auth/identity routes and use the explicitly configured public URLs. Callback handling can run on any HTTP host; login transactions are stored centrally.
Identity endpoints allow 300 requests per minute per authenticated user, or per client IP for anonymous requests, and return HTTP 429 when exceeded. Configure trusted proxy forwarding so hosts see the intended client addresses.
Provider registration
| Provider | Registration and issuer |
|---|---|
Create an OAuth web application in Google Cloud, register the backend callback, and supply its client ID and secret. Issuer: https://accounts.google.com. | |
| Microsoft personal | Register an application supporting personal Microsoft accounts, add a Web callback and client secret, use https://login.microsoftonline.com/common/v2.0, and enable personal accounts. |
| Microsoft enterprise | Use https://login.microsoftonline.com/<tenant-guid>/v2.0 for one tenant. For the common authority, list permitted enterprise tenant GUIDs explicitly. App registration must support the selected account types. |
| Keycloak | Create an OIDC client with Standard Flow and PKCE S256 enabled, register the backend callback, and supply the client credentials. Issuer: https://keycloak.example.com/realms/<realm>. |
| Custom OIDC | Supply the exact issuer with discovery at <issuer>/.well-known/openid-configuration, an authorization-code client, and appropriate client credentials. |
The default scopes are openid profile email. Discovery must advertise the code response type and asymmetric signing keys. Confidential clients use client_secret_basic when supported, otherwise client_secret_post; public clients use PKCE without a client secret. Other client authentication methods are not supported. Non-OIDC OAuth or SAML providers need an OIDC broker such as Keycloak.
Use Validate connection to check discovery, then Test saved provider to exercise the credentials, callback, and ID-token validation. Test login does not create users, link identities, or replace the administrator's Logship session. Test providers before enabling registration or requiring SSO.
Connection validation first checks the provider fields and the persisted sign-in URLs, then fetches discovery. It does not exchange credentials with Google or another provider. Errors identify the failing field and include an HTTP status and a reference matching the server's identity logs. The admin page displays failures in a notification as well as the page error banner. Provider client secrets and request payloads are never included in those diagnostics.
Seeding from JSON
Add provider entries to identity.providers for unattended bootstrap:
{
"id": "enterprise",
"displayName": "Company SSO",
"enabled": true,
"issuer": "https://keycloak.example.com/realms/company",
"clientId": "logship",
"clientSecret": "<injected secret>",
"scopes": ["openid", "profile", "email"],
"allowRegistration": false
}Each ID is seeded once. Subsequent restarts preserve UI edits and deletion markers; changing JSON does not rotate an already seeded secret. Deleted IDs cannot be reused. Issuer and client ID are immutable after creation; create a new provider to change them.
Enabled-provider changes apply to new logins without restarting hosts. Editing a provider invalidates its pending logins. Disabling or deleting it blocks new logins and links; already issued Logship sessions and PATs retain their normal expiry and explicit revocation behavior.
Users and permissions
An external identity is the exact issuer and subject, uniquely bound to one Logship user. An email address is contact information and never automatically claims an existing user. Multiple users can legitimately have the same contact email. Missing email claims are supported; new external users receive a generated internal username.
Automatic user creation is disabled by default. Existing users can link providers from User → Security Settings after signing in within the last five minutes or confirming their current local password. External-only users should sign in again before changing linked identities. Unlinking the final usable sign-in method is rejected.
If provider authentication succeeds but login reports that the identity is not linked and automatic creation is disabled, use authenticated linking or an administrator invitation. To accept new users, enable Automatically create users accepted by this provider and save the provider. This creates a separate user; it does not attach an existing user with the same email. Connection tests validate the provider without provisioning a user, so a successful test does not grant access to Logship.
For users who cannot sign in locally, create/provision the user in System → Users, then create a provider-specific invitation in System → Identity providers. Share the link privately with the intended user. Invitations expire after 30 minutes and are single-use credentials authorizing attachment of the selected provider identity to that user. Opening an invitation requires an additional successful provider login.
Invitation secrets are carried in URL fragments, which browsers do not send in HTTP request URLs or referrer headers.
With automatic creation enabled, every identity accepted by the provider and its restrictions can create a user. Optionally configure a default Logship account and explicit initial account permissions, such as Logship.Data.Viewer. These are assigned only when the user is created. They do not synchronize groups or modify existing memberships on later logins. No global permissions are granted automatically.
Google Workspace restrictions use the signed hd claim, not the email suffix. Microsoft common-authority login accepts only explicitly permitted enterprise tenant GUIDs and/or the separately enabled personal-account tenant.
SSO-only and recovery
Passwords remain enabled by default. Before enabling SSO-only mode:
- Validate and test at least one enabled provider.
- Designate at least one enabled global administrator with a local password as a recovery administrator.
- Sign in again and save the authentication policy.
SSO-only mode rejects ordinary password logins and local self-registration on the backend. Designated recovery administrators retain local login. Resetting an ordinary user's password does not bypass SSO enforcement. The login page retains the local form for recovery access.
Logging out ends the local Logship session; it does not sign the user out of Google, Microsoft, or their enterprise provider.
Remove a recovery administrator from the policy before deleting, disabling, or demoting that user. If a provider fails, use a recovery administrator to repair or disable it, or turn off SSO-only mode. Provider outages do not make existing Logship sessions or PATs depend on an online provider.
Encryption-key rotation and migration
Provider secrets and login-transaction payloads are authenticated and encrypted with AES-GCM. Admin reads expose only whether a secret exists. Leaving a secret blank preserves it; explicitly selecting removal clears it. Secrets, cookies, and tokens are excluded from application authentication diagnostics.
Explicit deployment-managed encryption remains supported for operators who require an externally managed key ring: configure identity.activeEncryptionKeyId and identity.encryptionKeys (a map of IDs to Base64-encoded random 32-byte keys) consistently on HTTP hosts. These keys remain outside the catalog. Existing encrypted values retain their original format and remain readable with their existing keys.
To rotate an explicit key ring, deploy the new key alongside the old key to every host, switch activeEncryptionKeyId, then save each provider in the UI to re-encrypt its retained secret. Keep the old key until all provider secrets have been rewritten and pending login transactions have expired (at least ten minutes after the final host switches). Existing catalog-managed values remain readable when switching to explicit keys; retain the catalog key file until those values have also been rewritten or expired. Losing a required key makes its secrets unreadable; a database backup alone is insufficient.
Existing password, PAT, agent, /auth/oauth, and legacy external-bearer integrations remain available. Legacy subject bindings migrate on successful new-flow login only when the legacy provider ID matches and its configuration names exactly one issuer matching the validated token. Ambiguous bindings require an administrator invitation or authenticated linking. Retain the original provider ID and client ID during migration; neither usernames nor Logship user IDs are replaced.
The login page prefers the new flow when an enabled new provider has the same ID as a legacy provider. Legacy bearer authentication is still controlled by the existing oauth JSON configuration; disable it separately after migrating its clients. Disabling a new provider in the UI does not revoke separately configured legacy credentials.
Upgrade database services first so they expose the new storage RPCs, then upgrade account services and HTTP hosts, and finally deploy the frontend. Enable SSO-only mode only after all authentication-serving nodes are upgraded; older nodes do not enforce that policy. Mixed-version deployments retain existing login contracts, but the new login flow requires upgraded services.
Validation
Automated tests use a local OIDC server to verify token validation, PKCE, browser correlation, completion binding, replay rejection, identity uniqueness, seed preservation, secret protection, and recovery policy. Before production rollout, run a real login and test login against each configured provider, verify account restrictions, and confirm recovery access from a separate browser session.