SAML SSO and SCIM setup
Overview
Section titled “Overview”Fencer supports any identity provider (IdP) that speaks SAML 2.0 for single sign-on and SCIM 2.0 for automated user provisioning. This guide covers the general setup process. If your IdP has a dedicated guide (see the sidebar), follow that instead — it includes provider-specific field names and screenshots.
You can configure SAML alone if you only need login. Set up SSO before SCIM: provisioned users have no Fencer password and sign in through your SSO connection (SAML, or OIDC).
Prerequisites
Section titled “Prerequisites”- An administrator account in your identity provider with permission to create SAML/SCIM applications.
- A Fencer organization administrator role.
- A plan that includes single sign-on and SCIM. Without it, the Single Sign-On and User provisioning (SCIM) sections of Settings > Authentication show Upgrade to unlock.
Part 1: SAML SSO setup
Section titled “Part 1: SAML SSO setup”Step 1: Collect Service Provider values from Fencer
Section titled “Step 1: Collect Service Provider values from Fencer”- In Fencer, navigate to Settings > Authentication and find the Single Sign-On section.
- Click Configure SSO (or Add SAML 2.0 connection if you already have an OpenID Connect connection). In the Add SSO connection dialog, keep SAML 2.0 selected as the Protocol.
- Note the values shown under Service Provider Details. The Entity ID and ACS URL appear in the dialog; the metadata URL appears as Metadata on the connection card once you save it:
| Value | Format |
|---|---|
| ACS URL | https://app.fencer.dev/accounts/saml/<your-org-uid>/acs/ |
| Entity ID | https://app.fencer.dev/accounts/saml/<your-org-uid>/metadata/ |
| Metadata | Same as the Entity ID — some IdPs can fetch this URL to auto-populate their SAML form |
<your-org-uid> is the Organization ID shown on Settings > Organization. Keep this dialog
open. You will return to it in Step 3.
Step 2: Create the SAML application in your IdP
Section titled “Step 2: Create the SAML application in your IdP”Create a new SAML application in your identity provider and configure it with the settings below. Field names vary by provider — match the intent of each setting to whatever your IdP calls it.
Service Provider settings
| Setting | Value |
|---|---|
| ACS / Reply URL | Paste the ACS URL from Fencer |
| Entity ID / Audience | Paste the Entity ID from Fencer |
| NameID format | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress |
| NameID value | User’s email address |
| SP-initiated login URL | https://app.fencer.dev/accounts/saml/<your-org-uid>/login/ |
Signing and security
| Setting | Value |
|---|---|
| Sign response | Yes |
| Sign assertion | Required — Fencer rejects unsigned assertions |
| Signature algorithm | http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 (RSA-SHA256) |
| Digest algorithm | http://www.w3.org/2001/04/xmlenc#sha256 (SHA-256) |
| Encrypt assertion | Not required (leave off unless your security policy demands it) |
Attribute mapping
Configure your IdP to send the following attributes in the SAML assertion. Fencer checks multiple common names for each attribute, so use whichever format your IdP supports. The first match found is used.
| Attribute | Recommended name | Alternatives accepted by Fencer |
|---|---|---|
urn:oid:0.9.2342.19200300.100.1.3 | urn:oid:1.2.840.113549.1.9.1, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress, email, Email, User.email | |
| First name | urn:oid:2.5.4.42 | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname, firstName, first_name, givenName, User.FirstName |
| Last name | urn:oid:2.5.4.4 | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname, lastName, last_name, sn, User.LastName |
| Role (optional) | https://app.fencer.dev/SAML/Attributes/role | None — the name is fixed. See The role attribute. |
Fencer uses the SAML NameID as a fallback for the email attribute, so the NameID must always be the user’s email address.
Step 3: Finish the connection on the Fencer side
Section titled “Step 3: Finish the connection on the Fencer side”- Return to the Add SSO connection dialog in Fencer.
- Under IdP Configuration Method, choose how to describe your IdP:
- Metadata URL — paste your IdP’s metadata URL (sometimes called “Federation Metadata” or “SAML Metadata”) into IdP Metadata URL, and its entity ID into IdP Entity ID.
- Manual — enter the IdP Entity ID, the IdP SSO URL, optionally the IdP SLO URL, and paste the IdP signing certificate in PEM format into IdP X.509 Certificate.
- Leave Reject IdP-initiated SSO on unless your IdP must launch Fencer from its own portal (for example an app dashboard). See Troubleshooting.
- Under Provisioning, Just-in-Time provisioning is on by default: users who sign in through SSO for the first time get an account and join your organization with the Default role for new users (Administrator, Team Member, Read Only, or a custom role). Optionally, restrict it to specific Allowed email domains (comma-separated; leave empty to allow all domains). Turn Just-in-Time provisioning off to admit only people who are already members, by invitation or by SCIM in Part 2.
- Check Enable SSO so users can sign in with this connection. Leave Enforce SSO off until you have tested the connection; turning it on requires every member to sign in through SSO.
- Click Save Configuration.
- On the connection card, click Test Connection. Fencer redirects you through your IdP. On
success, you return to Settings > Authentication with a confirmation banner. On failure,
Fencer shows an error page with a diagnostic of what went wrong and a reference ID (for example
sso-1a2b3c4d). Share this ID with support@fencer.dev if you need help resolving the issue.
If the test fails, see the Troubleshooting section.
The role attribute
Section titled “The role attribute”Fencer can take each user’s role from your IdP instead of having admins set it in Fencer. To do that, send one extra attribute in the SAML assertion. Both the attribute name and its values are fixed — there is nothing to configure on the Fencer side.
- Attribute name:
https://app.fencer.dev/SAML/Attributes/role(name formatURI). Fencer does not read a plainroleattribute — the full name keeps it from colliding with role attributes your IdP may already send to other apps. - Value: one of the role values below
| Value | Fencer role |
|---|---|
admin | Administrator |
member | Team Member |
read_only | Read Only |
| custom slug | A custom role you created under Admin > Team > Roles (see below) |
A custom role’s value is its slug: the role name in lower case, with spaces replaced by hyphens and
punctuation removed. For example, Security Lead becomes security-lead. The slug is also the last
part of the role’s address when you open it under Admin > Team > Roles
(…/team/roles/security-lead/), and it never changes, even if you rename the role. The Penetration
Tester role cannot be granted through SSO.
Example assertion:
<saml:Attribute Name="https://app.fencer.dev/SAML/Attributes/role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"> <saml:AttributeValue>member</saml:AttributeValue></saml:Attribute>How Fencer applies it:
- At every SSO sign-in, including the first. Whenever the attribute names a valid role, the user’s Fencer role is set to it, so changing a user’s role in your IdP takes effect at their next sign-in. A role an admin changed by hand in Fencer is overwritten at that point.
- Values are matched without regard to case.
Adminandadminare the same. - One role per user. If the attribute carries several different roles, Fencer ignores it.
- A missing, empty or unrecognised value changes nothing. The user keeps their current role, and a user signing in for the first time gets the connection’s Default role for new users. To demote someone, send their new role; removing the attribute does not demote them.
- Fencer never demotes the organization’s only administrator, whatever the IdP sends.
- SCIM wins. For a user whose role SCIM sets — through the SCIM role attribute or a role group — Fencer ignores the SSO attribute, so a sign-in never undoes the last sync.
Linking existing users to SSO
Section titled “Linking existing users to SSO”After enabling SAML SSO, existing users who were created before SSO was configured need to link their accounts. Fencer does not automatically bind SSO identities to existing accounts by email — each user must explicitly link their SSO identity once.
- For users: A Link your account to SSO banner appears in Fencer for unlinked users. While signed in with their usual method (password or social login), the user clicks Link SSO Account, confirms on the next page, and signs in with the IdP. Once linked, only an administrator can unlink the SSO identity.
- For admins: The Members tab of Admin > Team shows each user’s SSO link status next to their status. Admins can send a reminder email to a user who has not linked yet with Send SSO Linking Reminder in the member’s actions menu.
- New users provisioned via SCIM or created through JIT (just-in-time) provisioning are linked automatically — no action needed.
Part 2: SCIM provisioning setup
Section titled “Part 2: SCIM provisioning setup”SCIM provisioning lets your IdP automatically create, update, deactivate, and delete Fencer user accounts. Fencer implements SCIM 2.0 with bearer token authentication.
Step 1: Generate a SCIM token in Fencer
Section titled “Step 1: Generate a SCIM token in Fencer”- In Fencer, navigate to Settings > Authentication and find the User provisioning (SCIM) section.
- Click Enable SCIM.
- In the Enable SCIM provisioning dialog, choose the Default role for provisioned users and click Enable SCIM.
- Fencer displays the SCIM Bearer Token once. Copy it now — you will not be able to see it again. If you lose it, you can rotate to a new token from the same section.
- Note the SCIM Base URL shown below the token:
https://app.fencer.dev/scim/v2. Click Done when you have copied both.
You can change the Default Role later from the same section.
Step 2: Configure your IdP’s SCIM connector
Section titled “Step 2: Configure your IdP’s SCIM connector”Open the SCIM provisioning settings in your IdP and configure using the values below.
| Setting | Value |
|---|---|
| SCIM base URL / Tenant URL | https://app.fencer.dev/scim/v2 |
| Authentication method | Bearer Token (OAuth Bearer Token) |
| Bearer token | Paste the token from Step 1 |
| SCIM version | 2.0 |
Supported SCIM attributes:
| Attribute | Required | Notes |
|---|---|---|
userName | Yes | Must be the user’s email address |
externalId | No | Your IdP’s unique identifier for the user |
name.givenName | No | First name |
name.familyName | No | Last name |
displayName | No | Display name |
emails[].value | No | Primary email (usually same as userName) |
title | No | Job title |
timezone | No | IANA timezone (e.g. America/New_York) |
preferredLanguage | No | Language preference |
active | No | Used for deactivation and reactivation |
urn:ietf:params:scim:schemas:extension:fencer:2.0:User:role | No | The user’s Fencer role. See The SCIM role attribute |
Supported operations
Section titled “Supported operations”| Operation | Description |
|---|---|
| Create user | Creates a new user in your Fencer organization. Immediately active. If the user was previously deactivated, this reactivates the existing account instead of failing. |
| Update user | Keeps profile fields (name, title, timezone, language) and the role attribute in sync via PUT. |
| Deactivate | PATCH (or PUT) active=false removes the user from your organization. The SCIM mapping is preserved so the user can be reactivated later. Use this for offboarding. |
| Reactivate | PATCH active=true restores the user’s membership with the role from their role attribute or role group, or the default role. |
| Delete user | Removes the user from your Fencer organization and deletes their SCIM mapping. The user cannot be reactivated via PATCH after a delete — a new POST is required to re-provision them. |
| Filter users | Filter by userName or externalId (equality only). |
| Push groups | Create, rename, update members of and delete groups. See SCIM role groups. |
| Filter groups | Filter by displayName or externalId (equality only). |
Not supported: sort, ETag, bulk operations, password change endpoints. User PATCH supports only
replace operations on the active attribute and the role attribute — unsupported operations are
rejected with a 400 error. Other user attribute updates use PUT. Most IdPs handle this fallback
automatically. Group PATCH supports add, remove and replace on members, and replace on
displayName and externalId.
The SCIM role attribute
Section titled “The SCIM role attribute”Your IdP can set each user’s Fencer role over SCIM, either with role groups or with a role attribute, the same way the SAML role attribute does at sign-in. When a user has both, the role attribute wins. Fencer reads the attribute from its own SCIM schema extension, so both the attribute and its values are fixed — there is nothing to configure on the Fencer side.
- Schema extension:
urn:ietf:params:scim:schemas:extension:fencer:2.0:User - Attribute:
role, a string. Its full path isurn:ietf:params:scim:schemas:extension:fencer:2.0:User:role. - Value: a role value from the table above —
admin,member,read_onlyor a custom role’s slug.
Example create or replace request:
{ "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:fencer:2.0:User" ], "userName": "pat@example.com", "active": true, "urn:ietf:params:scim:schemas:extension:fencer:2.0:User": { "role": "member" }}PATCH can also set it, with "path": "urn:ietf:params:scim:schemas:extension:fencer:2.0:User:role".
How Fencer applies it:
- On every create, replace and PATCH that carries the attribute. Changing a user’s role in your IdP takes effect at the next sync, without anyone signing in. A role an admin changed by hand in Fencer is overwritten at that point.
- It outranks role groups. A user whose attribute names a valid role gets that role, whatever groups they are in.
- A missing, empty or unrecognised value hands the decision to the user’s role groups. Without a role group, a new user gets the SCIM Default Role and an existing user keeps their role.
- Removing the attribute takes the role away. When your IdP stops sending a value it sent before, the user drops to the SCIM Default Role, unless a role group gives them another role.
- The same guards as SSO apply: Fencer never demotes the organization’s only administrator, never grants the Penetration Tester role, and ignores a value naming several roles.
- Fencer returns the role attribute it last received when your IdP reads a user back, not the role the user ends up with, so reading a user and writing it back never pins their role.
SCIM role groups
Section titled “SCIM role groups”If your IdP can push groups over SCIM (Okta calls it Push Groups), you can manage Fencer roles
by group membership instead. Fencer stores every group you push, but only a role group changes
roles: one whose display name is a Fencer role’s name or its value from
the table above, ignoring case. For example, a group called Administrator
or admin grants Administrator, Read Only or read_only grants Read Only, and Security Lead or
security-lead grants a custom role named Security Lead. Other groups, such as Engineering,
change nothing. A name that matches two different roles matches neither. Renaming a role in Fencer
changes which group matches it by name, so name groups after the role’s value if you expect to
rename roles.
How Fencer applies them:
- A member of one role group gets that group’s role.
- A member of no role group gets the SCIM Default Role, once at least one role group exists. Until then, groups change nobody’s role. Removing someone from their last role group, or deleting or renaming the last role group, also drops its members to the default role.
- A member of several role groups keeps their current role. Put each user in one role group.
- The role attribute wins for a user whose attribute names a valid role.
- Rippling wins. If Rippling also provisions a user and manages roles with Rippling role groups (when enabled for your organization), SCIM leaves that user’s role alone.
- Changes take effect at the next push. Adding someone to a role group, removing them, or renaming or deleting the group updates roles straight away, without anyone signing in. A role an admin changed by hand in Fencer is overwritten at that point.
- Only users your IdP manages over SCIM are affected: users it created, and existing members it has matched, updated or added to a group. The same guards as the role attribute apply.
SCIM endpoints reference
Section titled “SCIM endpoints reference”| Endpoint | Methods | Purpose |
|---|---|---|
/scim/v2/Users | GET, POST | List users / Create user |
/scim/v2/Users/{id} | GET, PUT, PATCH, DELETE | Manage individual user |
/scim/v2/Groups | GET, POST | List groups / Create group |
/scim/v2/Groups/{id} | GET, PUT, PATCH, DELETE | Manage individual group |
/scim/v2/ServiceProviderConfig | GET | SCIM capabilities discovery |
/scim/v2/Schemas | GET | Supported schemas |
/scim/v2/ResourceTypes | GET | Supported resource types |
All SCIM endpoints accept both application/json and application/scim+json (RFC 7644) content
types.
Token rotation
Section titled “Token rotation”If your bearer token is compromised or you want to rotate credentials:
- In Fencer, navigate to Settings > Authentication and find User provisioning (SCIM).
- Click Rotate Token.
- Copy the new token immediately — the old one stops working as soon as you rotate.
- Update the bearer token in your IdP’s SCIM connector. The next sync will use the new token.
Troubleshooting
Section titled “Troubleshooting”-
“Invalid SAML response” or digest mismatch errors. Your IdP is using SHA-1 instead of SHA-256 for the signature or digest algorithm. Update both to SHA-256 in your IdP’s SAML configuration.
-
“Client not found” or unknown service provider errors. The ACS URL or Entity ID in your IdP does not match what Fencer expects. Confirm that both URLs include your organization’s UID exactly as shown under Service Provider Details in Fencer. Watch for trailing slashes — they matter.
-
“401 Unauthorized” on every SCIM sync. The bearer token is wrong or expired. Verify that your IdP is sending the token using the
Authorization: Bearer {token}header format. If unsure, rotate the token in Fencer and paste the new value into your IdP. -
Synced users appear as having missing data. You likely selected
name.formattedin the supported attributes list. Remove it — Fencer does not return that field. -
“Email domain not allowed for SSO” when a SAML user tries to sign in. The connection has an Allowed email domains restriction that excludes the user’s domain. Either add the domain to the allow list, or pre-provision the user via SCIM so JIT is bypassed.
-
A deactivated user can still sign in. Confirm that your IdP sends PATCH
active=falsewhen users are offboarded. Some IdPs require explicit configuration to send deactivation events. -
“SSO identifier does not match a linked account.” The user exists in Fencer but has not linked their SSO identity. They need to complete the SSO linking flow — a Link your account to SSO banner guides them through it. Admins can also send a linking reminder from Admin > Team.
-
IdP-initiated SSO is rejected. Fencer rejects unsolicited (IdP-initiated) SAML responses by default for security. Use SP-initiated login instead: direct users to
https://app.fencer.dev/accounts/saml/<your-org-uid>/login/or Login with SSO on the Fencer login page. If your IdP must launch Fencer from its own portal, edit the connection and turn off Reject IdP-initiated SSO. -
A sign-in or test shows a reference ID (e.g.
sso-1a2b3c4d). Note this ID and share it with support@fencer.dev along with a description of what you configured. The ID helps the support team locate the exact failure in the logs.