Aldine / Documentation / Single sign-on
Single sign-on for a self-hosted LaTeX editor
Aldine is an open-source, self-hosted collaborative LaTeX editor. It signs people in with your own OpenID Connect provider (Keycloak, Authentik, Authelia, Pocket ID, Dex), with Google, GitHub or ORCID, or with email and password. This page has every setting, the redirect URI and a recipe per provider. It also covers single sign-on on a self-hosted Overleaf, where it is part of Server Pro.
Applies to Aldine 0.11.0. Written by the Aldine project, so read it with that in mind. Statements about Overleaf are taken from the linked pages of Overleaf's own documentation. Checked on 12 October 2026.
Sign-in methods
Sign-in is off by default. Without AUTH_ENABLED an instance is single-tenant: there is no login, and everyone who can reach it has full access. AUTH_ENABLED=1 turns on accounts, per-project ownership and sharing (by invitation or by link).
| Method | Turned on by | Notes |
|---|---|---|
| Email and password | AUTH_ENABLED=1 | Available as soon as sign-in is on. Passwords are at least 8 characters and stored as scrypt hashes. ALDINE_SSO_ONLY=1 switches it off. |
| OpenID Connect | OIDC_ISSUER and OIDC_CLIENT_ID | One provider per instance. Authorization code flow with PKCE; the client secret is optional. |
GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET | Needs a verified email on the Google account. | |
| GitHub | GITHUB_LOGIN_CLIENT_ID and GITHUB_LOGIN_CLIENT_SECRET | Needs a verified email on the GitHub account. Separate from the OAuth app used for repository sync. |
| ORCID | ORCID_CLIENT_ID and ORCID_CLIENT_SECRET | The account is keyed by the ORCID iD, so it works when the researcher's email is private. |
Each provider is independent, and each one that is configured adds a button to the sign-in page. A session lasts 30 days.
Where the variables go
All configuration is environment variables on the app container. How they get there depends on which compose file you run (the self-hosting guide explains both):
- The minimal
docker-compose.yml(release images) has noenvironment:block. Put adocker-compose.override.ymlnext to it with the variables you need, then rundocker compose up -d. docker-compose.full.yml(from a clone of the repository) passes the sign-in and mail variables on this page through from a.envfile next to it. Two are not in it, so add them underenvironment:of theappservice yourself when you need them:ALDINE_ADMIN_EMAILSandNODE_EXTRA_CA_CERTS.
An override file for the minimal install, with OpenID Connect as the example:
services:
app:
environment:
AUTH_ENABLED: "1"
ALDINE_PUBLIC_URL: https://aldine.example.com
OIDC_ISSUER: https://auth.example.com/application/o/aldine/
OIDC_CLIENT_ID: <client id>
OIDC_CLIENT_SECRET: <client secret>
OIDC_LABEL: University login
ALDINE_ADMIN_EMAILS: you@example.org
The same settings in .env for docker-compose.full.yml:
AUTH_ENABLED=1
ALDINE_PUBLIC_URL=https://aldine.example.com
OIDC_ISSUER=https://auth.example.com/application/o/aldine/
OIDC_CLIENT_ID=<client id>
OIDC_CLIENT_SECRET=<client secret>
OIDC_LABEL=University login
In .env, give each comment its own line. Anything after a value becomes part of the value, so AUTH_ENABLED=1 multi-user login is not 1 and sign-in stays off without an error.
The redirect URI
Register exactly this redirect (callback) URI at the provider:
<ALDINE_PUBLIC_URL>/api/auth/oauth/<provider>/callback
<provider> is oidc, google, github or orcid. For OpenID Connect on aldine.example.com:
https://aldine.example.com/api/auth/oauth/oidc/callback
When Aldine is served under a path prefix, ALDINE_PUBLIC_URL carries the prefix and so does the URI, for example https://server.example.com/internal/aldine/api/auth/oauth/oidc/callback. Without ALDINE_PUBLIC_URL, Aldine derives the URI from the host of the request, which behind a proxy is often not what the provider has on file. Set it.
General settings
| Variable | Default | Meaning |
|---|---|---|
AUTH_ENABLED | unset | 1 or true turns on login, ownership and sharing. Unset: single-tenant, no login. |
ALDINE_PUBLIC_URL | unset | The public URL of the instance, with the path prefix if there is one. Used for the redirect URI and for password-reset links. When it starts with https, session cookies get the Secure flag. |
ALDINE_SSO_ONLY | unset | 1 or true disables registration, password sign-in, password reset and password change. Sign-in goes through the configured providers only. |
ALDINE_ADMIN_EMAILS | unset | Comma-separated addresses that may open /admin. Compared without regard to case. See administrators. |
OpenID Connect with your own identity provider
OpenID Connect needs AUTH_ENABLED=1 and ALDINE_PUBLIC_URL. OIDC_ISSUER and OIDC_CLIENT_ID turn it on. It appears on the sign-in page as one more button, labelled "Continue with" and the value of OIDC_LABEL.
| Variable | Default | Meaning |
|---|---|---|
OIDC_ISSUER | none, required | The issuer URL as the provider publishes it. Aldine reads <issuer>/.well-known/openid-configuration. An issuer with a path works; keep the trailing slash if the provider shows one. Must be https, except for localhost. |
OIDC_CLIENT_ID | none, required | The client ID you registered. |
OIDC_CLIENT_SECRET | unset | Set it for a confidential client: Aldine authenticates with client_secret_basic, or with client_secret_post when the discovery document offers only that. Leave it unset for a public client, which uses PKCE only. PKCE (S256) is used either way. |
OIDC_LABEL | Single sign-on | The button text and the provider's name on the account page, for example Keycloak or University login. |
OIDC_SCOPES | openid email profile | Scopes to request, separated by spaces or commas. openid is always added. Add groups for providers that send groups only when asked (Authelia, Pocket ID). |
OIDC_ALLOWED_GROUPS | unset | Comma-separated group names. When set, only members of at least one of them may sign in with OpenID Connect. Unset: everyone the provider authenticates gets in. It does not affect password accounts; see access control. |
OIDC_GROUPS_CLAIM | groups | The claim that lists the groups. Read from the ID token, or from the userinfo endpoint when the ID token has none. A single string counts as one group. |
OIDC_EMAIL_VERIFIED | require | require: Aldine uses the address only when the provider says email_verified: true. trust: it uses whatever address the provider sends. Read accounts and email addresses before choosing trust. |
At start, the log names the issuer, the client ID and whether the client is public or confidential. The secret is never printed:
[aldine] OIDC sign-in: issuer=https://auth.example.com/application/o/aldine/ client=aldine (confidential)
When some OIDC_* variables are set but OIDC_ISSUER or OIDC_CLIENT_ID is missing (a typo such as OIDC_CLIENTID), the log says which one and the feature stays off. A value of OIDC_EMAIL_VERIFIED other than require or trust is logged and treated as require.
The discovery document is fetched when Aldine starts and cached for an hour. When the hourly refresh fails, Aldine keeps the last good document and retries every 15 seconds. A provider that is down does not stop Aldine or the other sign-in methods.
A private CA or a self-signed certificate
Aldine checks the provider's TLS certificate against Node's built-in CA list. If the provider uses an internal CA, mount the CA certificate into the app container and point NODE_EXTRA_CA_CERTS at it:
services:
app:
environment:
NODE_EXTRA_CA_CERTS: /etc/aldine/ca.pem
volumes:
- ./ca.pem:/etc/aldine/ca.pem:ro
What Aldine checks
- Authorization code flow with PKCE (S256),
stateandnonce, bound to one attempt by a cookie that lasts 10 minutes. - The ID token's signature against the issuer's JWKS, with asymmetric algorithms only. Unsigned tokens and HMAC-signed tokens (
HS256) are refused, so the provider must sign with a key pair. iss,aud,azpwhen there are several audiences,exp,iat(at most 10 minutes old, with 60 seconds of clock skew tolerated) and thenonce.- The
issparameter on the callback (RFC 9207) when the provider advertises it. - Userinfo is consulted only for claims the ID token lacks, and only when its
submatches.
Provider recipes
Replace aldine.example.com with your ALDINE_PUBLIC_URL. A recipe that was checked against a running copy of the provider says so; the others follow the provider's documentation.
Keycloak
Verified against Keycloak 26.0 on 23 September 2026 (confidential client).
- In your realm: Clients → Create client. Client type OpenID Connect, Client ID
aldine. - Capability config: Client authentication on (confidential) and Standard flow on; everything else off.
- Login settings: Valid redirect URIs
https://aldine.example.com/api/auth/oauth/oidc/callback, Web originshttps://aldine.example.com. - Credentials tab: copy the client secret.
- Optional, for
OIDC_ALLOWED_GROUPS: Clients → aldine → Client scopes tab → aldine-dedicated → Add mapper → By configuration → Group Membership. Token claim namegroups, Full group path off (otherwise the claim holds/aldine-usersand nobody matches), Add to ID token on. With Add to ID token off and Add to userinfo on, Aldine reads the groups from userinfo.
OIDC_ISSUER=https://keycloak.example.com/realms/<realm>
OIDC_CLIENT_ID=aldine
OIDC_CLIENT_SECRET=<client secret>
OIDC_LABEL=Keycloak
Keycloak sends email_verified from the user's Email verified switch, and users created by an admin start unverified. Turn the switch on before they first sign in to Aldine, or give them the Verify Email required action.
Authentik
Verified against Authentik 2026.8.3 on 23 September 2026 (confidential and public client).
- Applications → Providers → New Provider → OAuth2/OpenID Provider → Next. Name Aldine, Authorization flow one of the
default-provider-authorization-…-consentflows. Client type Confidential, or Public if you will not use a secret. Under Redirect URIs/Origins, Add entry: Strict,https://aldine.example.com/api/auth/oauth/oidc/callback. - Signing Key: keep authentik Self-signed Certificate, or pick another RSA or EC certificate. Without a signing key, Authentik signs ID tokens with HS256 and the client secret, which Aldine refuses.
- Grant types: Aldine needs only Authorization Code. A provider created through a blueprint or the API has no grant types unless you list them (
grant_types: [authorization_code]), and Authentik then answers every sign-in withinvalid_request. A blueprint or API call must also list the scope mappings (goauthentik.io/providers/oauth2/scope-openid,-email,-profile) and the signing key; the form fills in both. - Applications → Applications → Create: name Aldine, slug
aldine, provider from step 1. - Copy the client ID and secret from the provider.
OIDC_ISSUER=https://auth.example.com/application/o/aldine/
OIDC_CLIENT_ID=<client id>
# leave the secret out for a public client
OIDC_CLIENT_SECRET=<client secret>
OIDC_LABEL=Authentik
The issuer ends in the application slug and a slash; the provider page shows it as OpenID Configuration Issuer. Renaming the slug changes the issuer (see changing the issuer). The default profile scope mapping sends a groups claim with the group names, so OIDC_ALLOWED_GROUPS works without extra setup.
The default email mapping sends email_verified: false for everyone, so with the default OIDC_EMAIL_VERIFIED=require people sign in to accounts without an email address. To give accounts their addresses, either set OIDC_EMAIL_VERIFIED=trust, or create a scope mapping for scope email that returns {"email": request.user.email, "email_verified": True} and select it on the provider in place of the default email mapping. Both amount to trusting Authentik's addresses. That is safe only while users cannot change their own address: keep Allow users to change email off under System → Settings (off by default) and do not grant goauthentik.io/user/can-change-email in a group's attributes.
Authelia
Verified against Authelia 4.39.28 on 23 September 2026 (confidential client; email, name and groups came from userinfo).
In configuration.yml (Authelia 4.38 or later), with the secret stored as a digest (authelia crypto hash generate pbkdf2 --variant sha512):
identity_providers:
oidc:
clients:
- client_id: 'aldine'
client_name: 'Aldine'
client_secret: '$pbkdf2-sha512$310000$...'
public: false
authorization_policy: 'two_factor'
require_pkce: true
pkce_challenge_method: 'S256'
redirect_uris:
- 'https://aldine.example.com/api/auth/oauth/oidc/callback'
scopes: ['openid', 'email', 'profile', 'groups']
response_types: ['code']
grant_types: ['authorization_code']
token_endpoint_auth_method: 'client_secret_basic'
OIDC_ISSUER=https://auth.example.com
OIDC_CLIENT_ID=aldine
# the secret itself, not the digest
OIDC_CLIENT_SECRET=<client secret>
OIDC_SCOPES=openid email profile groups
OIDC_LABEL=Authelia
Authelia 4.39 and later keep email, name and groups out of the ID token and serve them from the userinfo endpoint; Aldine reads them from there. two_factor stops everyone who has not registered a second factor at Authelia; use one_factor to try the setup first. Authelia only serves https, so an Authelia with a self-signed or internal certificate also needs NODE_EXTRA_CA_CERTS.
Pocket ID
- Administration → OIDC Clients → Add OIDC client. Name Aldine, callback URL
https://aldine.example.com/api/auth/oauth/oidc/callback. Turn on PKCE. Turn on Public client only if you will not use a secret. - Copy the client ID and, for a confidential client, the secret (shown once).
- Optional: restrict the client to user groups in Pocket ID itself, or list them in
OIDC_ALLOWED_GROUPS.
OIDC_ISSUER=https://id.example.com
OIDC_CLIENT_ID=<client id>
# leave the secret out for a public client
OIDC_CLIENT_SECRET=<client secret>
OIDC_SCOPES=openid email profile groups
OIDC_LABEL=Pocket ID
The issuer is Pocket ID's public URL (APP_URL) with no path. Pocket ID reports addresses as verified, including ones users set on their own account page. Before relying on the address for invites or ALDINE_ADMIN_EMAILS, turn off self-service account editing in Pocket ID's Application Configuration.
Dex
Verified against Dex v2.41.1 on 23 September 2026 (public and confidential client, static password connector).
In Dex's config.yaml:
staticClients:
- id: aldine
name: Aldine
# leave the secret out and set `public: true` for a public client
secret: <client secret>
redirectURIs:
- 'https://aldine.example.com/api/auth/oauth/oidc/callback'
OIDC_ISSUER=https://dex.example.com/dex
OIDC_CLIENT_ID=aldine
# leave the secret out for a public client
OIDC_CLIENT_SECRET=<client secret>
OIDC_LABEL=Dex
The issuer is Dex's issuer setting, usually with no trailing slash. Groups come only from connectors that provide them (LDAP, GitHub and others) and only with the groups scope (OIDC_SCOPES=openid email profile groups). The static password connector sends none, so OIDC_ALLOWED_GROUPS turns everyone away with it.
Google, GitHub and ORCID
Each of the three needs both its client ID and its client secret; with only one of them set, the button does not appear. Register the redirect URI from above with the provider's name in it.
| Provider | Variables | Redirect URI | Where to create the client |
|---|---|---|---|
GOOGLE_OAUTH_CLIENT_IDGOOGLE_OAUTH_CLIENT_SECRET | <ALDINE_PUBLIC_URL>/api/auth/oauth/google/callback | Google Cloud console, APIs and services, Credentials: an OAuth client of type "Web" | |
| GitHub | GITHUB_LOGIN_CLIENT_IDGITHUB_LOGIN_CLIENT_SECRET | <ALDINE_PUBLIC_URL>/api/auth/oauth/github/callback | GitHub, Settings, Developer settings: an OAuth app |
| ORCID | ORCID_CLIENT_IDORCID_CLIENT_SECRETORCID_SANDBOX (optional) | <ALDINE_PUBLIC_URL>/api/auth/oauth/orcid/callback | ORCID developer tools: a Public API client. The callback must be HTTPS. |
- Google. Aldine requests the scopes
openid email profileand accepts the sign-in only when Google reports the address as verified. - GitHub. Aldine requests
read:user user:emailand uses a verified address of the GitHub account. The GitHub app for sign-in is separate from the one for repository sync, which has its own variables (GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET) and its own callback. - ORCID. The account is keyed by the ORCID iD. Researchers whose ORCID email is private get an account without an email address; collaborators invite them by ORCID iD.
ORCID_SANDBOX=1points sign-in atsandbox.orcid.orgfor testing.
Email and password
With AUTH_ENABLED=1 and nothing else, people register with an email address and a password of at least 8 characters. Registration does not verify the address.
Password-reset links are sent by email when a mail transport is configured: SMTP_HOST, SMTP_PORT (default 587), SMTP_USER, SMTP_PASS and SMTP_FROM, with SMTP_SECURE=1 for implicit TLS, or SES_FROM with AWS_REGION for AWS SES. The link is built from ALDINE_PUBLIC_URL and expires after one hour. Without a transport, the reset token is written to the server log for the administrator to pass on.
ALDINE_SSO_ONLY=1 disables all of this. No mail transport is needed then.
Accounts and email addresses
An OpenID Connect account is keyed by the issuer and the provider's sub, not by the email address. Signing in again finds the same account even after the address changes at the provider.
- With a verified address (or
OIDC_EMAIL_VERIFIED=trust), the account gets that address and collaborators can invite it by email. - Without one, the account has no email address. It cannot be invited by email. The first later sign-in that brings a verified address gives the account that address, unless another account already has it.
- After that, the address stays as it is. Aldine does not follow a change of address at the provider, because project invites and shares are matched by the address on the account.
- A single-sign-on login never takes over an account that already exists with the same address: not a password account, not an account from another provider, and not another OpenID Connect identity that shares the address.
Choose OIDC_EMAIL_VERIFIED=trust only when users cannot set or change their own email address at the provider. Otherwise anyone who can edit their profile there can pick any address. The same applies to a provider that reports email_verified: true for every address, including ones users typed in themselves.
Changing the issuer
Because the account is keyed by the issuer URL exactly as the provider spells it, any change of that URL gives everyone new identities: a new host name, a renamed Authentik application slug, or a Keycloak upgrade that dropped the /auth prefix. If you can, keep the old issuer URL. The procedure for moving accounts onto a new issuer is in docs/OIDC.md.
Access control
- Accounts created by single sign-on never have a password. Aldine refuses to set one, sends no reset link for them and refuses password sign-in, so every sign-in goes through the provider.
OIDC_ALLOWED_GROUPSgates OpenID Connect sign-in only. Anyone can still register a password account unlessALDINE_SSO_ONLY=1is set. If the group is meant to decide who uses the instance, set both.- Group membership is checked at sign-in. Removing someone from the group, or disabling them at the provider, takes effect at their next sign-in. Until then their Aldine session (up to 30 days) and any access tokens they created keep working. Cutting access at once means removing the person's sessions and tokens; the commands are in docs/OIDC.md.
Administrators
ALDINE_ADMIN_EMAILS is a comma-separated list of addresses. A signed-in account whose email is on the list can open /admin: accounts, active users, projects and compile time. It shows metadata only. There is no role stored in the database; the list in the environment is the whole configuration.
- No compose file in the repository passes this variable through. Add it under
environment:of theappservice, as in the override file above. - An account without an email address cannot be an administrator, because the match is by address.
- A verified address from the provider decides who is an administrator. Create the administrator accounts (sign in once as each address on the list) before you open OpenID Connect sign-in to everyone.
- Making someone an administrator through a group is not supported yet.
Troubleshooting
Every sign-in failure ends on a short Aldine page titled "Sign-in failed" with the reason and a "Back to sign-in" link. The messages below are the start or the middle of that reason.
| Message | Cause |
|---|---|
This sign-in provider is not configured | AUTH_ENABLED is off, or the variables of that provider are not all set. |
is unavailable: the identity provider at … could not be reached (…) | Aldine cannot fetch <issuer>/.well-known/openid-configuration: a firewall between Aldine and the provider, a wrong port, or the provider is down. The bracket holds the network error (ECONNREFUSED, ETIMEDOUT). Failed lookups are retried after 15 seconds. |
presented a TLS certificate that is not trusted (…) | The provider's certificate is self-signed or from an internal CA. Set NODE_EXTRA_CA_CERTS. ERR_TLS_CERT_ALTNAME_INVALID means the certificate is for another host name. |
could not be found (ENOTFOUND): its host name does not resolve | The host in OIDC_ISSUER does not resolve from the Aldine server or container (an internal name, or a typo). |
answered with a redirect | OIDC_ISSUER redirects, often from http to https or because of a missing path. Use the URL it redirects to. |
the discovery document names issuer "…", not … | OIDC_ISSUER differs from the issuer the provider publishes. Copy it from the provider. |
must use https | The issuer or an endpoint in the discovery document is plain http on a host other than localhost. |
signs ID tokens only with algorithms Aldine does not accept | The provider signs with HS256 (Authentik without a signing key). Give it an RSA or EC key. |
the ID token signature could not be verified | The token is signed with a key or algorithm that is not in the provider's JWKS or discovery document. |
the identity provider's signing keys could not be fetched from … | Discovery worked, but the JWKS URL did not answer, answered with an error or a redirect, or timed out. Check that Aldine can reach that URL. |
the ID token is dated in the future (iat claim) | The provider's clock is more than a minute ahead of Aldine's. Sync both with NTP. |
the ID token has expired (… claim) | The token is past its exp, or more than 10 minutes old by Aldine's clock: Aldine's clock runs ahead of the provider's, or the sign-in took very long. |
the response did not name its identity provider (iss parameter missing) | The provider advertises the RFC 9207 iss parameter but the callback had none; something between the provider and Aldine rewrote the redirect. |
the ID token was rejected (aud claim) | OIDC_CLIENT_ID is not the client the token was issued to. |
the identity provider refused the sign-in (invalid_client …) | Wrong OIDC_CLIENT_SECRET, or a secret set for a public client (or the other way round). |
your account is not in a group that may use this Aldine instance | OIDC_ALLOWED_GROUPS is set and the person's groups claim names none of them. Check OIDC_GROUPS_CLAIM, and that the provider sends groups (Keycloak needs a mapper; Authelia and Pocket ID need the groups scope). |
OAuth state mismatch | The sign-in took more than 10 minutes, cookies are blocked, or the callback was opened in another browser. |
An account with this email already exists | The address belongs to a password account or to an account from another provider. Single sign-on never takes it over; the message names the method to use. |
An account with this email already belongs to a different single sign-on identity | Usually OIDC_ISSUER changed. See changing the issuer. |
no verified email on the Google account or no verified email on the GitHub account | The provider did not report a verified address. Verify the address there and sign in again. |
Password sign-in is disabled | ALDINE_SSO_ONLY is set, so the password endpoints answer 403. |
[aldine] OIDC sign-in is off: OIDC_CLIENT_ID is not set in the boot log | Some OIDC_* variables are set but not both required ones. Check the spelling. |
The provider reports a redirect_uri mismatch | The redirect URI at the provider differs from <ALDINE_PUBLIC_URL>/api/auth/oauth/oidc/callback. Check the path prefix and trailing slashes. |
Single sign-on on Overleaf: Community Edition and Server Pro
If you came here looking for SSO on a self-hosted Overleaf, this is what Overleaf's documentation says.
- It is a Server Pro feature. Overleaf's comparison table lists "Single sign-on (SSO) via SAML 2 and LDAP" and "Automatic user registration" for Server Pro and not for Community Edition. (Server Pro vs. Community Edition, checked 12 October 2026)
- The protocols are SAML 2.0 and LDAP. The Server Pro configuration section has a page for each. Both are configured in the Toolkit's
config/variables.env, by settingEXTERNAL_AUTHtosamlor toldap. The LDAP page says the integration "is compatible with Active Directory systems". (Overleaf docs: SAML 2.0, Overleaf docs: LDAP, checked 12 October 2026) - One method at a time. Overleaf states: "In Server Pro, we only support using a single method of authentication at any one time." With SAML 2.0 or LDAP, accounts are created when a person first logs in, and from Server Pro 5.2.1 the admin role can be granted or revoked through the SSO login. (Overleaf docs: user management, checked 12 October 2026)
- On overleaf.com, Group SSO is described as "a standard SAML-based SSO integration" that the administrator of a group subscription sets up. (Overleaf docs: Group SSO FAQs, checked 12 October 2026)
The SAML 2.0 and LDAP pages do not mention OpenID Connect, and we found no Overleaf page that documents it for either on-premises edition (checked 12 October 2026).
The two products cover different protocols. Aldine documents OpenID Connect and the OAuth providers on this page, not SAML or LDAP. If your institution offers only SAML or LDAP, Server Pro is the documented fit. If it runs Keycloak, Authentik or another provider that speaks OpenID Connect, the recipes above apply. The wider comparison is on self-hosting Overleaf (Community Edition, Server Pro) compared with Aldine.
What is not supported
- SAML and LDAP.
- Several OpenID Connect providers at once. There is one per instance, next to Google, GitHub and ORCID.
- Making someone an administrator through a group.
- Signing out of the identity provider when signing out of Aldine.
No account, no install. The demo is a shared sandbox without sign-in and resets every night.
Common questions
Does Overleaf Community Edition support single sign-on?
No. Overleaf's comparison table lists "Single sign-on (SSO) via SAML 2 and LDAP" for Server Pro and not for Community Edition. (Server Pro vs. Community Edition, checked 12 October 2026)
Which redirect URI do I register for Aldine?
<ALDINE_PUBLIC_URL>/api/auth/oauth/<provider>/callback, where the provider is oidc, google, github or orcid. For OpenID Connect on aldine.example.com that is https://aldine.example.com/api/auth/oauth/oidc/callback.
Can I turn passwords off and use only single sign-on?
Yes. Set ALDINE_SSO_ONLY=1. Registration, password sign-in, password reset and password change are then refused, and sign-in goes through the configured providers only.
Does Aldine support SAML or LDAP?
No. Aldine signs people in with OpenID Connect, Google, GitHub, ORCID or email and password. An identity provider that speaks both SAML and OpenID Connect, such as Keycloak or Authentik, can be connected over OpenID Connect.