Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions content/docs/permissions/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,10 @@ the identity provider to it, then revoke the old one; both authenticate until
you do. Each mint and each revoke writes one `sys_audit_log` row naming the
administrator and the connection, never the credential.

A connection's groups grant permission sets through the same group mappings an
SSO provider's sign-in uses; see
[Grant permission sets from IdP groups](/docs/permissions/sso#grant-permission-sets-from-idp-groups).

---

## Client Integration
Expand Down
58 changes: 58 additions & 0 deletions content/docs/permissions/sso.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,64 @@ before this rule, turn on `allowJit` for that provider.

---

## Grant permission sets from IdP groups

An SSO provider, OIDC or SAML, can decide what its users may do from the groups
the identity provider sends at sign-in. It uses the same group mappings
(`sys_idp_group_mapping`) as a
[SCIM connection](/docs/permissions/authentication#scim-connection-credentials):
one mapping model, two sources.

**Where the groups come from.** Set the provider's own claim mapping to fill
`groups`: `mapping.extraFields.groups` names the OIDC claim or the SAML attribute
that carries the user's groups, for example `extraFields: { groups: 'groups' }`
in `oidcConfig.mapping` (or `samlConfig.mapping`) when the provider is registered
through `POST /api/v1/auth/sso/register`. The **Setup → SSO Providers** form does
not set it. The value may be one string or a list of strings. A provider whose
mapping fills no `groups` signs users in as before.

**Saving a mapping.** A platform administrator saves one mapping per group and
permission set through `POST /api/v1/auth/admin/scim/set-group-mapping`, naming
the provider with `providerId`:

```bash
curl -X POST http://localhost:3000/api/v1/auth/admin/scim/set-group-mapping \
-H 'Content-Type: application/json' -H "Authorization: Bearer $ADMIN_SESSION" \
-d '{ "providerId": "okta", "groupDisplayName": "Sales", "permissionSet": "sales_rep" }'
# → { success, data: { mappingId, created, providerId, permissionSet, organizationId, reprojected: false, … } }
```

- Name the source with exactly one of `connectionId` (a SCIM connection) or
`providerId` (an SSO provider). Name the group with exactly one of
`groupExternalId` (matched against the group's id, such as an Entra ID group
object id) or `groupDisplayName` (matched against its exact name).
- The grant's organization is the provider's own organization. An unknown
provider, or one that belongs to no organization, is refused
`400 VALIDATION_FAILED` on `providerId`. With SSO off the save is refused `503`.
- Only an ordinary permission set inside that organization can be granted. An
administrator set, or any set outside the organization boundary, is refused
`400 VALIDATION_FAILED` on `permissionSet`, and nothing is stored. With no
security service to judge the boundary, the save is refused `503`.
- `POST /api/v1/auth/admin/scim/delete-group-mapping` with `{ "mappingId": "…" }`
removes a mapping, and at once the grants of that set its provider made in
that organization, unless another of the provider's mappings still names the
set.

**At every sign-in.** The user's grants follow the IdP's groups. A mapped group
grants its set in the provider's organization, and a group the user has left
loses its set at their next sign-in. A sign-in with no groups claim removes the
grants that provider made earlier. The boundary is judged again before every
grant. Only grants the provider itself made are ever removed: a grant made by
hand or through SCIM is never touched. A saved mapping applies at each member's
next sign-in, because a provider sends groups only when someone signs in; use
SCIM when a group change must take effect between sign-ins.

**When applying the mappings fails**, the sign-in still succeeds and the failure
is logged at `error`. The user keeps the grants of their previous sign-in until
the next one applies the mappings again.

---

## Verify configuration

Restart the server (`pnpm dev`), then:
Expand Down
Loading