/api/v1/federation/* lets you create and manage the identity-provider connections your tenant accepts. Social providers (Google, GitHub, Microsoft, Apple), custom OIDC IdPs, and SAML 2.0 connections all live here. Scoped to federation:read and federation:write.
You rarely call this surface from an end-user app. It is for the tenant admin console, for Terraform-style automation, and for occasional B2B integrations where adding an SSO connection programmatically is faster than clicking through the UI.
Connection types
Section titled “Connection types”The kind field on every connection is one of:
| Kind | Use |
|---|---|
social.google | Google OAuth (web sign-in) |
social.github | GitHub OAuth |
social.microsoft | Microsoft Entra (OIDC mode) |
social.apple | Sign in with Apple |
oidc | Generic OIDC — any compliant IdP |
saml | SAML 2.0 |
Each kind has a slightly different config shape; the common fields are normalised under data.
List connections
Section titled “List connections”GET /api/v1/federation/connectionsAuthorization: Bearer <access-token>Required scope: federation:read
Query parameters: kind — filter by kind (multiple: kind=oidc&kind=saml) state — 'enabled' | 'disabled' cursor limit{ "data": [ { "id": "fed_01HZX...", "slug": "cymmetri-okta", "kind": "saml", "name": "Cymmetri Okta", "state": "enabled", "created_at": "2026-03-01T10:00:00Z" } ], "meta": { "next_cursor": null, "limit": 50 }}Create a social connection
Section titled “Create a social connection”POST /api/v1/federation/connectionsAuthorization: Bearer <access-token>Content-Type: application/jsonRequired scope: federation:write
{ "kind": "social.google", "name": "Google", "slug": "google", "client_id": "...", "client_secret": "...", "scopes": ["openid", "email", "profile"]}The slug must be URL-safe and unique within the tenant. Slugs are immutable once saved; renames mean delete + recreate.
Create a custom OIDC connection
Section titled “Create a custom OIDC connection”POST /api/v1/federation/connectionsContent-Type: application/json
{ "kind": "oidc", "name": "Cymmetri Internal SSO", "slug": "cymmetri-sso", "issuer": "https://login.cymmetri.com", "client_id": "...", "client_secret": "...", "scopes": ["openid", "email", "profile"], "use_discovery": true, "attribute_mapping": { "email": "$.email", "name": "$.preferred_username" }}When use_discovery: true, the platform fetches the IdP's .well-known/openid-configuration and pulls authorization, token, and JWKS endpoints from it.
Create a SAML connection
Section titled “Create a SAML connection”POST /api/v1/federation/connectionsContent-Type: application/json
{ "kind": "saml", "name": "Cymmetri Okta", "slug": "cymmetri-okta", "idp_metadata_url": "https://cymmetri.okta.com/app/.../sso/saml/metadata", "attribute_mapping": { "email": "emailaddress", "name": "name", "first_name": "givenname", "last_name": "surname", "groups": "groups" }, "jit_provisioning": true}If you prefer to paste the IdP metadata XML directly:
{ "kind": "saml", "name": "...", "slug": "...", "idp_metadata_xml": "<EntityDescriptor xmlns=...>...</EntityDescriptor>", "attribute_mapping": { ... }}The response includes the SP-side values the IdP needs:
{ "data": { "id": "fed_01HZX...", "slug": "cymmetri-okta", "acs_url": "https://banking-cymmetri.intelliauth.local/auth/saml/cymmetri-okta/acs", "sp_entity_id": "https://banking-cymmetri.intelliauth.local/saml/cymmetri-okta", "sp_metadata_url": "https://banking-cymmetri.intelliauth.local/saml/cymmetri-okta/metadata" }}Send these to whoever is configuring the IdP side.
Update a connection
Section titled “Update a connection”PATCH /api/v1/federation/connections/{connection_id}Content-Type: application/jsonRequired scope: federation:write
{ "attribute_mapping": { "groups": "memberOf" }, "scopes": ["openid", "email", "profile", "offline_access"]}slug and kind are immutable. Other fields are PATCH-mergeable.
Disable / enable a connection
Section titled “Disable / enable a connection”POST /api/v1/federation/connections/{connection_id}/disablePOST /api/v1/federation/connections/{connection_id}/enableRequired scope: federation:writeA disabled connection refuses new sign-ins. Existing users who signed in via the connection keep their sessions; only new attempts fail.
Test a connection
Section titled “Test a connection”POST /api/v1/federation/connections/{connection_id}/testRequired scope: federation:writeReturns a one-time test URL. Open it in a browser; complete the IdP flow; receive a JSON report:
{ "data": { "success": true, "duration_ms": 1842, "claims_received": { "sub": "...", "email": "...", "groups": [...] }, "warnings": [] }}Use this during integration to verify the round trip without involving real users.
Delete a connection
Section titled “Delete a connection”DELETE /api/v1/federation/connections/{connection_id}Required scope: federation:writeHard delete. Users previously signed in via the connection retain their user record (their external_identities array loses the connection entry, but they remain in the tenant).
Common errors
Section titled “Common errors”| Error | When |
|---|---|
slug_unavailable | Another connection already uses this slug |
slug_invalid | Slug isn't URL-safe or is reserved |
metadata_fetch_failed | IdP discovery URL or SAML metadata URL didn't return a valid document |
kind_unsupported | Unknown kind value |
attribute_mapping_invalid | A mapping references a claim the IdP isn't sending |