SAML and SCIM
EthicsPortal supports two identity integrations. Each one is configured per organisation and works without the other:
- SAML 2.0 single sign-on lets members sign in through your identity provider.
- SCIM 2.0 provisioning lets your identity provider add, update and deactivate members.
Use both to keep access to cases in step with your directory: SCIM decides who is a member, and SAML decides how they sign in.
Before you start
Section titled “Before you start”| Requirement | Details |
|---|---|
| Role | Organisation Admin. Other roles do not see these settings. |
| Subscription | The organisation needs active access. Without it, the settings open the billing page instead. |
| Where | Organisation → Enterprise identity → Single sign-on (SSO) and Organisation → Enterprise identity → SCIM provisioning |
| Identity check | EthicsPortal asks you to confirm your identity before it opens either screen. |
| Credentials | SAML uses your identity provider’s signing certificate. SCIM uses its own bearer token. Neither uses an API token, and an API token does not work for either. |
All values on this page use the production host https://secure.ethicsportal.eu. The settings screens show the same values with a copy button.
SAML 2.0 single sign-on
Section titled “SAML 2.0 single sign-on”EthicsPortal acts as the SAML service provider (SP). One set of SP values serves every organisation: EthicsPortal finds the right organisation from the email domain the person enters, so there is no organisation-specific URL.
| Setting | Value |
|---|---|
| SP entity ID and metadata | https://secure.ethicsportal.eu/auth/saml/metadata |
| Assertion consumer service | https://secure.ethicsportal.eu/auth/saml/callback |
| Binding | HTTP-POST |
| NameID | Email address |
The metadata URL returns the SP metadata as XML. You can import it in identity providers that accept a metadata URL, or enter the two URLs by hand. The metadata states that assertions must be signed and requests the email and name attributes.
Identity provider requirements
Section titled “Identity provider requirements”| Item | Requirement |
|---|---|
| Sign-in flow | Service-provider-initiated only. People start at EthicsPortal. Sign-in started from an identity provider dashboard or app tile is refused. |
| Authentication request | EthicsPortal sends an unsigned request to your SSO URL with the HTTP-Redirect binding. Do not require signed requests. |
| Response | Sent to the assertion consumer service URL with HTTP-POST. The Destination must be that URL. |
| Audience | Exactly the SP entity ID: https://secure.ethicsportal.eu/auth/saml/metadata |
| Issuer | Exactly the identity provider entity ID you enter in EthicsPortal |
| Signature | The assertion must be signed. A response where only the outer envelope is signed is refused. Signing both is fine. |
| Algorithms | RSA-SHA256 signature and SHA-256 digest. SHA-1 is refused. |
| Encryption | Do not encrypt the assertion. The connection is protected by HTTPS. |
| Validity | The assertion must be inside its validity window. EthicsPortal allows 30 seconds of clock difference. |
| Time limit | The person must finish signing in within 10 minutes of starting at EthicsPortal. |
| Single logout | Not supported. Leave the single logout URL empty. |
Attributes
Section titled “Attributes”| Data | Where EthicsPortal reads it | Required |
|---|---|---|
| Email address | An attribute named email or mail. If neither is present, the NameID value. |
Yes |
| NameID format | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress, with the user’s email address as the value |
Yes |
| Display name | An attribute named name |
No |
Attribute names are matched exactly. Names written as URIs, or first_name and last_name, are not read. Without a name attribute, a person created on first sign-in is named after their email address.
The email address must be in one of the organisation’s verified domains. EthicsPortal compares addresses without regard to letter case.
Set up single sign-on
Section titled “Set up single sign-on”- In your identity provider, create a SAML 2.0 application for EthicsPortal. Enter the SP entity ID and the assertion consumer service URL from the table above. Set the NameID to the user’s email address with the email address format, and add a
nameattribute if you want display names. - Make sure the application signs the assertion with SHA-256.
- In EthicsPortal, open Organisation → Enterprise identity → Single sign-on (SSO). Copy these values from your identity provider:
- Identity provider entity ID: the issuer from your identity provider’s SAML metadata.
- Identity provider SSO URL: the sign-on endpoint. It must be an
https://URL. - Identity provider certificate: the X.509 signing certificate, in PEM format (with or without the
BEGIN CERTIFICATElines).
- Choose the Default role for provisioned members and whether to Provision members on first sign-in. Leave Enable single sign-on and Require single sign-on off for now. Select Save changes.
- Under Email domains, add each domain your people’s addresses use, then verify it. See Verify your email domains.
- Turn on Enable single sign-on and save. EthicsPortal refuses to enable a connection without the three identity provider values and at least one verified domain.
- Test it. Sign out, open the sign-in page, choose Sign in with single sign-on and enter your work email. You can also go straight to
https://secure.ethicsportal.eu/sso/new. The settings screen then shows the time of the last sign-in through your identity provider. - When the test works, decide whether to turn on Require single sign-on. See Require single sign-on.
Assign the EthicsPortal application in your identity provider to the people who handle cases. EthicsPortal accepts an assertion only for an address in a verified domain. The just-in-time provisioning setting and existing memberships decide what that person can then reach.
Verify your email domains
Section titled “Verify your email domains”A domain does nothing until it is verified. Only verified domains send people to your identity provider, and only addresses in verified domains are accepted from it.
-
Enter the domain under Email domains, for example
example.com, and select Add domain. -
Publish the TXT record shown for it at the root (
@) of that domain. It has this form:ethicsportal-verification=<token shown in EthicsPortal> -
Select Verify. EthicsPortal looks the record up when you press the button. If DNS has not updated yet, wait and try again; changes can take up to 24 hours.
Each domain matches exactly. Add subdomains separately: verifying example.com does not cover eu.example.com. One connection can hold several domains. Only one EthicsPortal organisation can hold a domain as verified.
Once verified, EthicsPortal treats your identity provider as the sign-in route for every EthicsPortal account with an address in that domain. This includes accounts that belong only to other EthicsPortal organisations. The identity provider signs those people in, but that does not add them to your organisation.
Removing a domain stops sending its addresses to your identity provider.
Just-in-time provisioning
Section titled “Just-in-time provisioning”Provision members on first sign-in is off by default. Leave it off if you add members with SCIM or invitations.
| Person signing in | Provisioning off | Provisioning on |
|---|---|---|
| Active member of your organisation | Signed in | Signed in |
| Deactivated member of your organisation | Signed in, no access to your organisation | Reactivated, then signed in |
| Has no EthicsPortal account | Refused | Account and membership created with the default role |
| Has an EthicsPortal account but is not a member | Signed in, not added to your organisation | Signed in, not added to your organisation |
People who already hold an EthicsPortal account join your organisation by accepting an invitation, sent by an administrator or by SCIM. Single sign-on alone never adds an existing account to an organisation.
A reactivated member returns with the lower of their previous role and the default role. The identity provider confirms who someone is. It does not restore a role an administrator removed.
If a member has turned on two-factor authentication in EthicsPortal, they still enter their authenticator code after signing in through your identity provider.
Require single sign-on
Section titled “Require single sign-on”Require single sign-on applies to every address in the connection’s verified domains:
- Emailed sign-in codes (magic links) are refused for those addresses. The sign-in page sends them to single sign-on with the message “Your organization requires single sign-on. Continue with your identity provider.”
- Existing sessions for those addresses that were not started through your identity provider end at their next request. This also happens when you enable an enforced connection or verify another domain on it.
- A member with an address in an enforced domain can change their email only to another address in the same domains. Nobody can change their email into a domain where another organisation requires single sign-on unless they are a member of that organisation.
To prevent a lockout, an administrator whose own address is in the domain must be signed in through single sign-on before turning this on. Otherwise saving fails with “Sign in through single sign-on once before requiring it, so a setup mistake can’t lock you out.”
Addresses outside the verified domains, such as external counsel, keep signing in with emailed codes.
Sessions and sign-out
Section titled “Sessions and sign-out”An EthicsPortal session ends after 14 days without activity, or when the person signs out. Signing out of your identity provider, or disabling the person there, does not end an EthicsPortal session that already exists. To remove access at once, deactivate the member: through SCIM, or in Team in EthicsPortal.
Rotate the signing certificate
Section titled “Rotate the signing certificate”Identity providers issue a new signing certificate before the old one expires. To rotate without interruption:
- Paste the new certificate below the old one in Identity provider certificate and save. Assertions signed with either certificate are accepted.
- Switch your identity provider to the new certificate.
- Remove the old certificate from the field and save.
The settings screen shows the latest expiry date among the certificates in the field. When every certificate has expired, it shows a warning and all sign-ins fail until you add a valid one.
| Okta field | Value |
|---|---|
| Single sign-on URL | https://secure.ethicsportal.eu/auth/saml/callback (keep it as the recipient and destination URL) |
| Audience URI (SP Entity ID) | https://secure.ethicsportal.eu/auth/saml/metadata |
| Name ID format | EmailAddress |
| Application username | |
| Attribute statements | email = user.email; name = user.firstName + " " + user.lastName |
| Assertion signature | Signed, RSA-SHA256 |
Copy Okta’s Identity Provider Issuer, Identity Provider Single Sign-On URL and X.509 Certificate into the matching EthicsPortal fields. Sign-in from the Okta dashboard tile is identity-provider-initiated and is refused. Hide the tile, or replace it with a bookmark to https://secure.ethicsportal.eu/sso/new.
Microsoft Entra ID
Section titled “Microsoft Entra ID”| Entra ID field | Value |
|---|---|
| Identifier (Entity ID) | https://secure.ethicsportal.eu/auth/saml/metadata |
| Reply URL (Assertion Consumer Service URL) | https://secure.ethicsportal.eu/auth/saml/callback |
| Sign on URL | https://secure.ethicsportal.eu/sso/new, so that opening the app from My Apps starts at EthicsPortal |
| Unique User Identifier (Name ID) | The user’s email address, for example user.mail, with the email address format |
| Additional claim | Name name with no namespace, source user.displayname |
| Signing option | Sign SAML assertion, or sign both the response and the assertion |
| Signing algorithm | SHA-256 |
Copy Microsoft Entra Identifier to Identity provider entity ID, Login URL to Identity provider SSO URL, and the contents of Certificate (Base64) to Identity provider certificate.
Entra ID’s default claims use URI names, which EthicsPortal does not read. The email address therefore comes from the NameID. If a user principal name differs from the email address, map the NameID to the email address.
Google Workspace and other identity providers
Section titled “Google Workspace and other identity providers”Any SAML 2.0 identity provider that meets the requirements works. In a custom SAML application, enter the assertion consumer service URL as the ACS URL and the SP entity ID as the entity ID. Set the NameID format to email, with the user’s primary email as the value. Add a name attribute for display names.
SCIM 2.0 provisioning
Section titled “SCIM 2.0 provisioning”| Setting | Value |
|---|---|
| Base URL | https://secure.ethicsportal.eu/scim/v2 |
| Authentication | Dedicated bearer token generated in organisation SCIM settings |
| Resource | /Users |
| Media type | application/scim+json |
The token identifies the organisation, so the base URL is the same for every organisation. A SCIM user is a person’s membership in your organisation.
Generate and manage the token
Section titled “Generate and manage the token”- Open Organisation → Enterprise identity → SCIM provisioning and select Generate token.
- Copy the token. It starts with
scim_and is shown only once. EthicsPortal cannot display it again. - In your identity provider, enter the base URL and the token as the bearer token or secret.
| Action | Effect |
|---|---|
| Regenerate token | Issues a new token. The old token stops working immediately. |
| Disable | Every request is refused with 401 until you select Enable. The token is kept. |
| Remove | Deletes the connection and its token. Members already provisioned stay. |
| Default role for provisioned members | The role new members receive: Admin, Handler or Viewer. Handler is the default. |
The screen shows the last four characters of the token and the time of the last request from your identity provider.
Send the token in the Authorization header on every request:
Authorization: Bearer scim_...Content-Type: application/scim+jsonEndpoints
Section titled “Endpoints”| Method | Path | Purpose |
|---|---|---|
GET |
/Users |
List members, with optional filter and paging |
GET |
/Users/{id} |
Read one member |
POST |
/Users |
Provision a member |
PUT |
/Users/{id} |
Replace a member’s attributes |
PATCH |
/Users/{id} |
Update attributes or deactivate |
DELETE |
/Users/{id} |
Deactivate a member |
GET |
/ServiceProviderConfig |
Supported features |
GET |
/ResourceTypes, /ResourceTypes/{name} |
Resource types |
GET |
/Schemas |
Schemas |
All endpoints require the token. There is no /Groups endpoint and no bulk endpoint. Turn off group push or group provisioning in your identity provider; assigning a group to the application still provisions its members one by one. Sorting and ETags are not supported.
Attribute mapping
Section titled “Attribute mapping”| SCIM attribute | Read and write | What it sets in EthicsPortal |
|---|---|---|
id |
Read only | EthicsPortal’s identifier for the member. Use it in /Users/{id}. |
externalId |
Read and write | Your identity provider’s identifier, stored and returned unchanged |
userName |
Read; written on create | The person’s email address. It must be an email address. |
emails[primary eq true].value |
Read; written on create | The same email address, returned with type work |
displayName |
Read and write | The person’s name in your organisation |
name.formatted |
Read and write | Same as displayName |
active |
Read and write | false deactivates the member, true reactivates them |
meta.created, meta.lastModified |
Read only | When the member was added and last changed |
Other attributes, including name.givenName, name.familyName and roles, are not stored. Map displayName if you want names to appear.
The email address is fixed once a member exists. A later change to userName or emails is accepted but has no effect. An EthicsPortal account can belong to several organisations, and one organisation’s identity provider cannot change it for the others.
A name set through SCIM applies in your organisation only. When SCIM creates a brand-new account, the name also becomes that account’s name.
Roles are not synchronised. New members receive the default role, and administrators change roles in EthicsPortal.
Provision a user
Section titled “Provision a user”POST /scim/v2/Users HTTP/1.1Host: secure.ethicsportal.euAuthorization: Bearer scim_...Content-Type: application/scim+json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "jane.doe@example.com", "externalId": "00u1abcd2EFGH3ijk4l5", "displayName": "Jane Doe", "emails": [{ "value": "jane.doe@example.com", "type": "work", "primary": true }], "active": true}Response 201 Created:
{ "id": "4821", "externalId": "00u1abcd2EFGH3ijk4l5", "userName": "jane.doe@example.com", "name": { "formatted": "Jane Doe" }, "displayName": "Jane Doe", "emails": [{ "primary": true, "value": "jane.doe@example.com", "type": "work" }], "active": true, "meta": { "location": "https://secure.ethicsportal.eu/scim/v2/Users/4821", "created": "2026-11-09T10:15:00Z", "lastModified": "2026-11-09T10:15:00Z", "resourceType": "User" }, "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"]}What POST /Users does depends on the address:
| Address | Result |
|---|---|
| No EthicsPortal account | Account and active membership created with the default role. 201. |
| Deactivated member of your organisation | Reactivated with the lower of their previous role and the default role. 201. |
| Active member of your organisation | 409, scimType uniqueness |
| Existing EthicsPortal account, not a member | Not added. EthicsPortal emails the person an invitation and answers 409. After they accept, retry the assignment: the identity provider finds the member by userName. |
| In a domain another organisation has verified for single sign-on | 409. Invite the person instead. |
An account that was never confirmed and belongs to no organisation counts as having no account if your organisation has verified its domain for single sign-on. Repeated requests for the same address do not send duplicate invitations while one is pending.
New members receive no welcome email from provisioning. They sign in through single sign-on, or with an emailed code if single sign-on is not required for their domain.
List and filter users
Section titled “List and filter users”GET /scim/v2/Users?filter=userName%20eq%20%22jane.doe%40example.com%22 HTTP/1.1{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"], "totalResults": 1, "startIndex": 1, "itemsPerPage": 100, "Resources": [{ "id": "4821", "userName": "jane.doe@example.com", "active": true }]}The list contains every member of your organisation, including members added by invitation and deactivated members ("active": false). The Resources entries are full user objects, shortened here.
| Filter attribute | Notes |
|---|---|
userName |
Matched without regard to letter case |
emails, emails.value |
Same as userName |
externalId |
Case-sensitive |
id |
Case-sensitive |
active |
Accepted, but does not narrow the results |
Supported operators: eq, ne, co, sw, ew, gt, ge, lt, le, pr, combined with and and or. Filtering on any other attribute returns 400 with scimType invalidFilter.
Pagination
Section titled “Pagination”| Parameter | Default | Meaning |
|---|---|---|
startIndex |
1 |
1-based position of the first result |
count |
100 |
Maximum number of results. 0 returns only totalResults. |
Results are ordered by id, oldest first. itemsPerPage repeats the requested count. Continue until startIndex + count is greater than totalResults.
Update and replace users
Section titled “Update and replace users”PATCH accepts a SCIM PatchOp with the operations add, replace and remove, with or without a path:
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "displayName", "value": "Jane Smith" }, { "op": "replace", "value": { "active": false } } ]}Send active as a JSON boolean (true or false).
PUT replaces the member’s attributes with the request body. Send the full user, including externalId and active. A PUT that leaves out active does not deactivate anyone.
Both return 200 with the updated user.
Deactivate users
Section titled “Deactivate users”DELETE /Users/{id}, or setting active to false, deactivates the membership. It does not delete it. DELETE returns 204 No Content and is safe to repeat.
When a member is deactivated:
- They lose access to the organisation at their next request.
- Their open reports are unassigned and they are removed from reports they participate in.
- They see a notification in EthicsPortal that their access ended.
- The change is recorded in the audit trail as made by SCIM.
- Their past actions stay attributed to them in case history and the audit trail.
Some members cannot be deactivated. EthicsPortal answers 409 with the reason, and the member stays active:
| Member | Reason returned | What to do |
|---|---|---|
| Organisation owner | The organization owner cannot be deactivated. | Transfer ownership in EthicsPortal first |
| Only active admin | This is the only active admin. | Make another member an Admin first |
| Compliance officer of the whistleblowing channel | This member is the whistleblowing channel’s compliance officer. | Assign a different compliance officer in the whistleblowing channel settings first |
Setting active to true, or a new POST for the same address, reactivates the member with the lower of their previous role and the default role.
SCIM errors
Section titled “SCIM errors”Errors use the SCIM error format:
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "detail": "User jane.doe@example.com is already provisioned in this organization.", "status": "409", "scimType": "uniqueness"}| Status | Cause |
|---|---|
400 |
Invalid JSON, empty body, invalid resource, unknown PATCH operation, or unsupported filter (invalidFilter) |
401 |
Missing or unknown token, a regenerated token, or a disabled or removed connection |
404 |
No member with that id in this organisation |
406 |
Unsupported media type. Send Content-Type: application/scim+json. |
409 |
See Provision a user and Deactivate users |
429 |
More than 300 requests in one minute with the same token. Retry after a pause. |
Okta provisioning
Section titled “Okta provisioning”In the Okta application’s provisioning settings, use SCIM 2.0 with:
| Okta field | Value |
|---|---|
| SCIM connector base URL | https://secure.ethicsportal.eu/scim/v2 |
| Unique identifier field for users | userName |
| Supported provisioning actions | Push New Users, Push Profile Updates. Do not select group push. |
| Authentication mode | HTTP Header, with the SCIM token as the bearer token |
Then enable creating users, updating user attributes and deactivating users. Make sure userName is the user’s email address and displayName is mapped.
Microsoft Entra ID provisioning
Section titled “Microsoft Entra ID provisioning”Set the provisioning mode to automatic and enter:
| Entra ID field | Value |
|---|---|
| Tenant URL | https://secure.ethicsportal.eu/scim/v2 |
| Secret token | The SCIM token |
Test the connection, then check the user attribute mappings. userName must hold the email address; if user principal names differ from email addresses, map userName to mail. Turn off group provisioning, because EthicsPortal has no /Groups endpoint.
Troubleshooting
Section titled “Troubleshooting”Single sign-on messages
Section titled “Single sign-on messages”| Message or symptom | Cause | Fix |
|---|---|---|
| “Single sign-on isn’t set up for that email domain.” | The connection is not enabled, or the address’s domain is not verified on it | Enable the connection, and add and verify the domain |
| “We couldn’t complete single sign-on. Please try again.” | The assertion was refused: wrong certificate, only the response signed, SHA-1, audience or issuer mismatch, wrong Destination, clock difference beyond 30 seconds, sign-in started from an identity provider tile, more than 10 minutes since starting, or the same response sent twice |
Check the values in identity provider requirements and start again at https://secure.ethicsportal.eu/sso/new |
| “Your identity provider signed you in, but you don’t have access here yet. Ask an administrator to add you.” | The asserted email address is not in a verified domain, the person has no account and just-in-time provisioning is off, or the account cannot be used | Check the email the identity provider sends, invite the person or provision them with SCIM, or turn on just-in-time provisioning |
| “needs at least one verified email domain before single sign-on can be enabled” | No verified domain | Verify a domain first |
| “Sign in through single sign-on once before requiring it, so a setup mistake can’t lock you out.” | Your current session did not start through single sign-on | Sign out, sign in through single sign-on, then turn on Require single sign-on |
| “doesn’t look like a valid X.509 certificate” | The certificate field contains something other than certificates | Paste the certificate from your identity provider, in PEM or Base64 form |
| “We couldn’t find the TXT record yet” | The record is not visible in DNS yet, or is not at the domain root | Check the record and wait for DNS to update. |
| “Another organisation has already verified this domain” | The domain is verified by a different organisation, and only one can hold it | If the domain is yours, contact support. |
| “Your organization requires single sign-on. Continue with your identity provider.” | Emailed sign-in codes are refused for this domain | Sign in through single sign-on |
| All sign-ins fail from one day | The identity provider certificate expired or was replaced | Paste the current certificate. See Rotate the signing certificate. |
Provisioning problems
Section titled “Provisioning problems”| Symptom | Cause | Fix |
|---|---|---|
401 on every request |
Wrong token, token regenerated, or connection disabled | Enter the current token, or select Enable |
409 with “an invitation to join this organization has been sent” |
The address already has an EthicsPortal account | Ask the person to accept the invitation, then retry the assignment |
409 with “is in a domain another organization has verified for single sign-on” |
Another organisation owns that domain | Invite the person instead |
409 when deactivating |
The member is the owner, the only active admin, or the channel’s compliance officer | Follow the table in Deactivate users |
| Members have no name | displayName is not mapped |
Map displayName in your identity provider |
| Email change in the directory not reflected | Email addresses are fixed once provisioned | The person changes their email in their EthicsPortal account settings |
Metadata API and member lifecycle
Section titled “Metadata API and member lifecycle”Deactivation through SCIM ends a member’s access to the organisation through the metadata API as well. Their personal API tokens stop reaching the organisation, and they stop receiving the alerts sent to administrators when a webhook fails. Organisation API tokens and webhooks belong to the organisation and keep working. API permissions.
The metadata API lists members and sends invitations, but it does not deactivate members or change roles. Use SCIM or the web application for that. See Members and invitations.
For identity-provider configuration assistance, contact support.