Skip to main content

Keycloak SSO

SES authenticates every user with OpenID Connect (OIDC, Authorization Code + PKCE). The platform ships with a Keycloak realm as the default and test identity provider — it is bundled with the deployment so you can start working immediately.

Keycloak is the reference/test provider

The bundled Keycloak is ideal for development, evaluation and small installations. For production you will usually point SES at your own OIDC provider instead — whether that's a Keycloak you operate, or an external provider such as Microsoft Entra ID (Azure AD), Google, Auth0 or SURFconext. SES speaks standard OIDC, so any conforming provider works.

You can also set up and manage your own identity providers per institute from the admin panel — see Identity providers.

Integrating other OIDC providers (identity providers)

External authentication sources are registered in SES as identity providers. You can have several per institute (for example one for students and one for staff). SES never changes identity policy — the provider is used as-is.

Registering an identity provider

  1. In the admin panel go to Administration → Organisation → Identity providers → Add.
  2. Select Institute and give the provider a Name (e.g. Microsoft Entra ID).
  3. Choose Provider type: OIDC and enable Active.
  4. Fill in the provider's OIDC endpoints:
EndpointValue
Authorization URL<provider>/authorize
Token URL<provider>/token
Userinfo URL<provider>/userinfo
JWKS URL (keys)<provider>/jwks
End-session URL<provider>/logout
Issuer<provider>
  1. Enter the Client ID and Client secret SES uses with that provider (secret is encrypted at rest).
  2. Map the claims SES needs:
FieldPurposeTypical source
Username claimUsed as the student numbersub
Role claimContains role informationroles (or https://ses/roles)
Teacher role valueGrants teacher accessses-teacher
Admin role valueGrants admin/staff accessses-admin
Faculty claimScopes a teacher to a facultyfaculty
  1. Save.

Making roles work

SES reads the role claim and maps its values to platform roles (ses-superuser, ses-admin, ses-teacher, ses-student). Your provider must issue those role values (as realm/claim roles or a custom claim), or SES cannot grant admin/teacher access. Configure this either in the provider itself or via a claim mapper.

Making tenant access work

Tenant access is enforced by the institutes claim. Every identity provider must ensure a user's ID token carries an institutes claim listing the institutes the user may enter. Add an attribute/mapper on the provider side; without it, the login is refused.

Role + institutes are mandatory

A provider that does not issue the SES role values and the institutes claim will authenticate users but grant no admin access and no tenant access. Configure both before enabling the provider.

One way to ease integration: point SES at the bundled Keycloak and use its broker role mapper or a custom protocol mapper so your external IdP sessions still produce the roles and institutes claims SES expects.

Realm structure

The ses realm contains roles, a client, and a dedicated claim scope.

Roles

RoleDescription
ses-superuserFull superuser (is_superuser=True)
ses-adminStaff access (is_staff=True)
ses-teacherFaculty-scoped exam management
ses-studentExam access only

Client: ses-server

SettingValue
Client IDses-server
FlowAuthorization Code + PKCE
Scopesopenid profile email roles ses-claims

Client scope: ses-claims

MapperClaimSource
realm_rolesrolesUser's realm roles
facultyfacultyUser attribute
student_numberstudent_numberUser attribute
employee_numberemployee_numberUser attribute

Access claim: institutes

Tenant access is enforced through a signed institutes claim in the ID token. If a user's token does not contain the target institute, SES refuses the login — for every tenant.

This is a separate Keycloak setup, configured in the bundled ses realm:

PieceWhere in KeycloakWhat it does
ScopeClient scope ses-claimsCarries the claim into the ID token (the client includes this scope)
Mapperinstitutes-mapper on ses-claims (type "List user attribute")Reads the user's institutes attribute and emits it as the institutes claim
Per-user dataUser attribute institutesWhich institutes the user may enter (multivalued, e.g. superuser/admin = [default-institute, test-institute], others = [default-institute])
Giving a user access

Add the institute to the user's institutes attribute in Keycloak; the mapper turns it into the signed claim SES checks at login.

Tenants are access-controlled

A user cannot reach an institute's data unless the institutes claim explicitly includes it — even if the user has a valid Keycloak account.

Accessing the admin console

  • URL: https://<keycloak-domain>/admin/
  • Username: admin
  • Password: value of KEYCLOAK_ADMIN_PASSWORD in .env.secrets

OIDC endpoints

EndpointURL
Authorizationhttps://<keycloak-domain>/realms/ses/protocol/openid-connect/auth
Tokenhttp://keycloak:8080/realms/ses/protocol/openid-connect/token
JWKShttp://keycloak:8080/realms/ses/protocol/openid-connect/certs
Logouthttps://<keycloak-domain>/realms/ses/protocol/openid-connect/logout

Test users (seed data)

UsernameRolesIdentifier
superuserses-superuseremployee_number=SES-SUP
adminses-adminemployee_number=SES-ADM
teacher1ses-teacherfaculty=CS
teacher2ses-teacherfaculty=MATH
student1ses-studentstudent_number=S12345678
student2ses-studentstudent_number=S87654321

Security features

  • PKCE (S256) — proof key for code exchange
  • State parameter — CSRF protection
  • Nonce — replay-attack prevention
  • JWKS signature verification — ID-token signature validation