Skip to main content

Enterprise SSO (SAML)

This document defines the draft SAML 2.0 single sign-on configuration for the IDP. It focuses on per-tenant configuration, metadata ingestion, and certificate rotation.

Status: Draft (groundwork for Phase 3 of the IDP roadmap)

Goals

  • Support per-tenant SAML configuration with clear validation rules.
  • Allow metadata ingestion via URL fetch or manual upload.
  • Provide a safe certificate rotation strategy without downtime.

Non-Goals

  • SCIM provisioning (covered in the SCIM roadmap item).
  • Full implementation details for UI and API (tracked in the SAML epic workstream).

Per-Tenant Configuration Schema (Draft)

This schema defines the inputs required to enable SAML for a tenant. The canonical data model is intentionally explicit and versioned to avoid metadata drift.

{
"version": "v1",
"tenantId": "<uuid>",
"enabled": true,
"mode": "enforced",
"entityId": "https://idp.digiwedge.com/saml/metadata/<tenantSlug>",
"acsUrl": "https://idp.digiwedge.com/api/auth/saml/acs/<tenantSlug>",
"sloUrl": "https://idp.digiwedge.com/api/auth/saml/slo/<tenantSlug>",
"idpMetadata": {
"source": "url",
"value": "https://idp.example.com/metadata",
"fetchedAt": "2026-01-27T12:00:00.000Z"
},
"idp": {
"entityId": "https://idp.example.com",
"ssoUrl": "https://idp.example.com/sso",
"sloUrl": "https://idp.example.com/slo",
"nameIdFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"signingCertificates": [
{
"kid": "primary",
"certificatePem": "-----BEGIN CERTIFICATE-----...",
"active": true
},
{
"kid": "next",
"certificatePem": "-----BEGIN CERTIFICATE-----...",
"active": true
}
]
},
"policy": {
"allowIdpInitiated": true,
"requireSignedAssertions": true,
"requireSignedResponse": true,
"forceReauthOnAcrChange": true
},
"mappings": {
"email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"firstName": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
"lastName": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
}
}

Field Notes

  • mode: disabled | optional | enforced
  • entityId/acsUrl/sloUrl are derived from the tenant slug and environment.
  • idpMetadata.source supports url or xml (manual upload).
  • signingCertificates supports two active certs to allow rotation.
  • mappings should support attribute aliases per tenant.

Metadata Ingestion

The IDP supports two ingestion modes (see ADR-0002):

  1. URL Fetch (preferred)

    • Store the metadata URL and fetch on save.
    • Re-fetch on a scheduled interval (e.g., every 6 hours).
    • Parse and persist a normalized representation (entity ID, SSO URL, certs).
  2. Manual Upload

    • Store the raw XML blob for traceability.
    • Parse and normalize into the same canonical fields.

Validation requirements:

  • Metadata must include a valid EntityDescriptor with at least one IDPSSODescriptor.
  • At least one signing certificate is required.
  • Supported bindings: HTTP-Redirect and HTTP-POST.

Certificate Rotation

See ADR-0004 for the rotation policy. Key points:

  • Allow multiple signing certs simultaneously.
  • Prefer the cert marked active but accept any valid cert during validation.
  • Rotate by publishing new metadata, then remove the old cert only after a grace period.

API Contract

DTOs are defined in apps/idp/src/app/dto/saml/.

Configuration Endpoints

MethodPathRequest DTOResponse DTODescription
GET/api/auth/saml/config/:tenantIdSamlConfigResponseDtoGet tenant SAML config
POST/api/auth/saml/config/:tenantIdCreateSamlConfigDtoSamlConfigResponseDtoCreate/replace config
PATCH/api/auth/saml/config/:tenantIdUpdateSamlConfigDtoSamlConfigResponseDtoPartial update
DELETE/api/auth/saml/config/:tenantId{ deleted: true }Disable/remove config

Metadata Endpoints

MethodPathRequest DTOResponse DTODescription
GET/api/auth/saml/metadata/:tenantSlugXMLSP metadata for IdP configuration
POST/api/auth/saml/config/:tenantId/ingest-urlIngestMetadataUrlDtoMetadataIngestionResultDtoIngest from URL
POST/api/auth/saml/config/:tenantId/ingest-xmlIngestMetadataXmlDtoMetadataIngestionResultDtoIngest from XML
POST/api/auth/saml/config/:tenantId/refreshRefreshMetadataDtoRefreshMetadataResultDtoRefresh cached metadata

Authentication Endpoints

MethodPathRequest DTOResponse DTODescription
GET/api/auth/saml/login/:tenantSlugInitiateSamlLoginDto (query)RedirectInitiate SP login
POST/api/auth/saml/acs/:tenantSlugSamlAcsCallbackDtoSamlAuthResultDtoACS callback
GET/api/auth/saml/logout/:tenantSlugInitiateSamlLogoutDto (query)RedirectInitiate SP logout
POST/api/auth/saml/slo/:tenantSlugSamlSloCallbackDtoRedirectSLO callback

Error Codes

CodeHTTPDescription
SAML_CONFIG_NOT_FOUND404No SAML config for tenant
SAML_DISABLED403SAML is disabled for tenant
METADATA_FETCH_FAILED422Could not fetch metadata URL
METADATA_PARSE_ERROR422Invalid metadata XML
ASSERTION_INVALID401SAML assertion validation failed
CERTIFICATE_EXPIRED401All IdP certificates expired

Open Questions

  • Where should SAML configs be stored: Access Control DB or IDP DB?
  • How do we expose tenant SSO settings in the admin UI without leaking secrets?
  • Should we support signed AuthnRequests by default?

References