๐ Single sign-on (OIDC)
LibrePhotos can hand login over to an external identity provider that speaks OpenID Connect โ Keycloak, Authentik, Authelia, Zitadel, Okta, Google, Entra ID and so on. After the provider confirms who someone is, LibrePhotos issues its own normal session, so everything downstream behaves exactly as it does for a password login.
Username-and-password login keeps working alongside it. Turning SSO on does not take anyone's existing way of logging in away.
What you need before startingโ
- Your server's public URL, set as the
FRONTEND_BASE_URLenvironment variable (for examplehttps://photos.example.com). This one is not optional. The reverse proxy in front of the backend rewrites theHostheader, so LibrePhotos genuinely cannot work out its own public address from an incoming request โ it has to be told. Without it the login button reports that SSO is not fully configured. - An email provider configured in Site Settings, if you want LibrePhotos to create accounts on first login. See the email settings page. Without email configured, LibrePhotos will not create accounts over SSO, because it has no way to act on the provider's claim that an address is verified.
Registering LibrePhotos with your identity providerโ
Create a confidential client (one with a client secret) at your provider and give it this redirect URI:
https://your-librephotos-url/api/accounts/oidc/<provider_id>/login/callback/
<provider_id> is a short name you choose in the next step โ keycloak,
authentik, google, whatever you like. It must match exactly.
Note down the client ID, the client secret, and the provider's issuer URL (the
one whose /.well-known/openid-configuration document describes it).
Telling LibrePhotos about the providerโ
In the Django admin (/api/django-admin/), under Social applications, add one:
| Field | Value |
|---|---|
| Provider | OpenID Connect |
| Provider ID | the <provider_id> you used in the redirect URI |
| Name | what the login button should say, if you add more than one provider |
| Client id | from your provider |
| Secret key | from your provider |
| Settings | {"server_url": "https://your-idp/realms/example"} โ the issuer URL |
| Sites | pick your site |
Then, in the app, open Admin Area > Site Settings and find the Single sign-on group. Each change saves at once. New in 1.5.0 Up to 1.4.0 these switches were only on the Constance page of the Django admin, under the names in brackets.
- Show the single sign-on button (
OIDC_ENABLED): the on/off switch. While it is off, the login button is hidden and the SSO endpoints are inactive, so switching it off is a real way to stop SSO logins. - Button label (
OIDC_BUTTON_LABEL): the text on the login button, e.g. "Sign in with Keycloak", at most 64 characters. With more than one provider each button shows its provider's name instead. - Allow sign-ups over single sign-on (
OIDC_ALLOW_SIGNUP): whether a first-time SSO login may create a new LibrePhotos account. Off by default; also requires email to be configured.
The provider itself is only added and changed in the Django admin, as above. The
group lists the providers it finds, and warns under the switches when SSO cannot
work yet: no provider attached to this site, no public URL
(FRONTEND_BASE_URL), or, for sign-ups, no email set up.
How accounts are matched upโ
On a first SSO login, LibrePhotos looks for an existing account whose email matches the one the provider reports:
- A single matching account, and the provider says the address is verified โ the two are linked, and from then on the provider's stable user id identifies that person.
- The provider has not verified the address โ refused. Otherwise anyone able to register your email address at the provider could claim your account.
- Two or more accounts share the address โ refused, whether or not sign-ups over SSO are on, because there is no single right answer. LibrePhotos does not create yet another account with the same address either.
- The provider sends no address โ refused, since there is nothing to match on and no verified address to create an account with.
- No matching account โ a new one is created only if
OIDC_ALLOW_SIGNUPis on and email is configured. Otherwise create the account first (or set its email to match) and let the user sign in again.
Accounts created through SSO are never administrators. Grant that in the admin afterwards if you want it.
Using LDAP accountsโ
LibrePhotos does not connect to an LDAP directory itself. Instead, point your identity provider at the directory and LibrePhotos at the provider: people then log in with their directory username and password at the provider, and LibrePhotos gets the result over OpenID Connect. Every common self-hosted provider can do this.
- Authelia: set up the LDAP authentication backend (it works with LLDAP, OpenLDAP and Active Directory), then add LibrePhotos as an OpenID Connect client.
- Authentik: add an LDAP source that syncs your directory, then an OAuth2/OpenID provider with an application for LibrePhotos.
- Keycloak: in your realm, add User Federation with an LDAP provider, then a confidential OpenID Connect client. Turn on Trust Email on the LDAP provider, or Keycloak reports directory addresses as unverified and LibrePhotos refuses them.
What this means for accounts: LibrePhotos matches people by the email address the directory holds, and only when the provider says it is verified (see How accounts are matched up). Either give each LibrePhotos account the same email as in the directory, or turn on sign-ups over SSO so that a first login creates the account.
The mobile app logs in with a username and password, not with SSO. A user who only ever signed in through the provider has no LibrePhotos password yet; they can set one with Forgot your password? on the login page (this needs email to be configured).
When something goes wrongโ
A failed attempt returns to the login page with an explanation. The usual causes:
| Message | What to change |
|---|---|
| Account not known to LibrePhotos | Create the account, or turn on OIDC_ALLOW_SIGNUP |
| Email address not verified | Verify the address at your identity provider |
| More than one account uses this email address | Give each LibrePhotos account its own email address (or clear it on the ones that should not log in over SSO) |
| Sign-in was cancelled at your identity provider | Nothing to fix: the user pressed Cancel or declined access. Try again |
| Your identity provider could not complete the sign-in | Look in the server log for the line starting SSO login via; it names the reason (for example an expired login, or the provider refusing the client secret) |
| Public URL not configured | Set FRONTEND_BASE_URL |
| Provider-side "invalid redirect URI" | The redirect URI at your provider must match the callback URL above exactly, including the trailing slash |