SAML 2.0 Setup¶
ARX operates as a SAML 2.0 Service Provider (SP), enabling federated single sign-on with any SAML 2.0-compliant identity provider (IdP). This guide covers SP metadata, the Assertion Consumer Service, SP-initiated and IdP-initiated flows, IdP configuration for Okta, Microsoft Entra ID, and OneLogin, attribute mapping, Single Logout, and certificate management.
Endpoints¶
| Endpoint | Method | Description |
|---|---|---|
/v1/auth/saml/metadata |
GET | Returns the SP metadata XML for IdP configuration. |
/v1/auth/saml/login |
GET | Initiates SP-initiated SSO. Accepts org_id or domain query parameter. |
/v1/auth/saml/acs |
POST | Assertion Consumer Service. Receives and validates SAML responses. |
/v1/auth/saml/slo |
GET | Single Logout endpoint. Handles both IdP-initiated and SP-initiated logout. |
SP Metadata¶
The SP metadata endpoint provides the XML document that IdP administrators need to configure their side of the SAML trust relationship. Access it at:
https://api.arxsec.io/v1/auth/saml/metadata
The metadata contains:
| Element | Value |
|---|---|
| Entity ID | Configured via SAML_SP_ENTITY_ID. Defaults to https://api.arxsec.io/v1/auth/saml/metadata. |
| ACS URL | https://<ARXSEC_API_URL>/v1/auth/saml/acs (HTTP-POST binding) |
| SLO URL | https://<ARXSEC_API_URL>/v1/auth/saml/slo (HTTP-Redirect binding) |
| NameID Format | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress |
| AuthnRequests Signed | true |
| Want Assertions Signed | true |
| Signing Certificate | Included if SAML_SP_CERT is configured |
Most IdPs can consume this URL directly during application setup (often labeled "Upload metadata from URL").
SP-Initiated SSO Flow¶
In SP-initiated SSO, the user begins the login process at the ARX application.
User ARX (SP) IdP
| | |
|-- Login ----->| |
| |-- AuthnRequest --------->|
| | (HTTP-Redirect) |
| | |
| | User authenticates |
| | |
| |<-- SAML Response --------|
| | (HTTP-POST to ACS) |
| | |
| |-- Validate assertion |
| |-- JIT provision user |
| |-- Issue session JWT |
|<-- Token -----| |
- The client calls
GET /v1/auth/saml/login?org_id=<uuid>orGET /v1/auth/saml/login?domain=<domain>. - ARX looks up the SAML configuration in the
sso_configstable byorg_idordomain. - ARX fetches the IdP metadata from the stored
metadata_url. - ARX extracts the IdP's
SingleSignOnServiceURL (preferring HTTP-Redirect binding, falling back to HTTP-POST). - ARX builds a SAML
AuthnRequestXML document with a unique request ID, the ACS URL asAssertionConsumerServiceURL, and the SP entity ID as theIssuer. - The
AuthnRequestis DEFLATE-compressed and base64-encoded for the HTTP-Redirect binding. - A cryptographic
RelayStatetoken is generated for CSRF protection and stored with the org context. - The user's browser is redirected (HTTP 302) to the IdP's SSO URL with the
SAMLRequestandRelayStatequery parameters. - The user authenticates at the IdP.
- The IdP posts a SAML Response to the ACS URL.
IdP-Initiated SSO Flow¶
In IdP-initiated SSO, the user clicks the ARX application tile in their IdP portal.
- The IdP generates a SAML Response containing the user's assertion.
- The IdP posts the SAML Response directly to the ACS URL (
https://api.arxsec.io/v1/auth/saml/acs). - ARX validates the assertion, extracts attributes, and issues a session JWT.
- Since there is no
RelayStatefrom an SP-initiated request, ARX identifies the organization from the assertion'sIssuerelement.
Note: IdP-initiated SSO does not have the CSRF protection provided by the RelayState token. Organizations with strict security policies may choose to disable IdP-initiated SSO and require SP-initiated flows only.
Assertion Consumer Service (ACS)¶
The ACS endpoint (POST /v1/auth/saml/acs) processes the SAML Response:
- Decodes the base64-encoded
SAMLResponsefrom the POST body. - Parses the XML and locates the
Assertionelement. - Validates the SAML
StatusCodeisSuccess. - Extracts the
NameID(email address). - Extracts attributes from the
AttributeStatement. - Constructs a stable
sso_subjectin the formatsaml|<issuer>|<name_id>. - Performs JIT user provisioning or retrieves the existing user.
- Generates an HS256 session JWT (8-hour expiration) with audience
authenticated.
The ACS response body:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer",
"user": {
"id": "a1b2c3d4-...",
"org_id": "e5f6a7b8-...",
"email": "jane@acme.com",
"role": "viewer",
"full_name": "Jane Doe",
"sso_provider": "saml"
},
"saml_attributes": {
"groups": ["Engineering", "Deployers"],
"issuer": "https://idp.acme.com",
"name_id": "jane@acme.com"
}
}
Session JWT Structure¶
After successful SAML authentication, ARX issues a session JWT with the following claims:
| Claim | Value |
|---|---|
sub |
User ID (UUID) |
org_id |
Organization ID |
email |
User's email address |
role |
User's ARX role |
aud |
authenticated |
iss |
ARXSEC_API_URL |
exp |
8 hours from issuance |
auth_method |
saml |
The token is signed with HS256 using SUPABASE_ANON_KEY for compatibility with the standard JWT validation path.
Configuring Okta as the IdP¶
1. Create a SAML Application¶
- In the Okta Admin Console, navigate to Applications > Create App Integration.
- Select SAML 2.0.
- In General Settings, enter a name (e.g., "ARX").
- In Configure SAML, set the following:
| Field | Value |
|---|---|
| Single sign-on URL | https://api.arxsec.io/v1/auth/saml/acs |
| Audience URI (SP Entity ID) | https://api.arxsec.io/v1/auth/saml/metadata (or your custom SAML_SP_ENTITY_ID) |
| Name ID format | EmailAddress |
| Application username |
2. Configure Attribute Statements¶
| Name | Value |
|---|---|
email |
user.email |
firstName |
user.firstName |
lastName |
user.lastName |
displayName |
user.displayName |
3. Configure Group Attribute Statements¶
| Name | Filter |
|---|---|
groups |
Matches regex .* (or filter to specific groups) |
4. Complete Setup¶
- Click Finish and assign the application to users/groups.
- Copy the IdP metadata URL from the application's Sign On tab.
- In ARX, create an
sso_configsrow:
INSERT INTO sso_configs (org_id, provider, domain, metadata_url, enabled)
VALUES ('<org-id>', 'saml', 'acme.com', 'https://acme.okta.com/app/exk.../sso/saml/metadata', true);
Configuring Microsoft Entra ID as the IdP¶
1. Create an Enterprise Application¶
- In the Azure Portal, navigate to Microsoft Entra ID > Enterprise applications > New application > Create your own application.
- Select Integrate any other application you don't find in the gallery (Non-gallery).
- Under Single sign-on, select SAML.
2. Configure Basic SAML Settings¶
| Field | Value |
|---|---|
| Identifier (Entity ID) | https://api.arxsec.io/v1/auth/saml/metadata |
| Reply URL (ACS URL) | https://api.arxsec.io/v1/auth/saml/acs |
| Sign on URL | https://api.arxsec.io/v1/auth/saml/login?domain=acme.com |
| Logout URL | https://api.arxsec.io/v1/auth/saml/slo |
3. Configure Attributes & Claims¶
| Claim Name | Source Attribute |
|---|---|
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name |
user.displayname |
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname |
user.givenname |
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname |
user.surname |
http://schemas.microsoft.com/ws/2008/06/identity/claims/groups |
Group IDs |
4. Complete Setup¶
- Download the App Federation Metadata URL.
- Assign users and groups to the application.
- Store the metadata URL in the
sso_configstable.
Configuring OneLogin as the IdP¶
1. Add a SAML Application¶
- In the OneLogin Admin Console, navigate to Applications > Add App.
- Search for SAML Custom Connector (Advanced).
2. Configure the Connector¶
| Field | Value |
|---|---|
| Audience (EntityID) | https://api.arxsec.io/v1/auth/saml/metadata |
| ACS (Consumer) URL | https://api.arxsec.io/v1/auth/saml/acs |
| ACS URL Validator | https://api\\.arxsec\\.io/v1/auth/saml/acs |
| Single Logout URL | https://api.arxsec.io/v1/auth/saml/slo |
| SAML nameID format |
3. Configure Parameters¶
Map the following attributes under the Parameters tab:
| Field Name | Value |
|---|---|
name |
Name |
firstName |
First Name |
lastName |
Last Name |
groups |
User Groups |
4. Complete Setup¶
Copy the Issuer URL (metadata URL) from the SSO tab and store it in the sso_configs table.
Attribute Mapping¶
ARX extracts user attributes from the SAML assertion using a priority-based search across common attribute name patterns.
Display Name¶
Checked in order:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/namehttp://schemas.microsoft.com/identity/claims/displaynamedisplayNamenamecn
If none are found, ARX falls back to constructing a name from givenName + surname attributes using their respective claim URIs (e.g., http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname).
Groups¶
Checked in order:
http://schemas.xmlsoap.org/claims/Grouphttp://schemas.microsoft.com/ws/2008/06/identity/claims/groupsgroupsmemberOf
Group values returned in the assertion can be used with SCIM group-to-role mapping for automated RBAC assignment. See SCIM 2.0 Provisioning for details.
Single Logout (SLO)¶
ARX supports Single Logout via the /v1/auth/saml/slo endpoint using the HTTP-Redirect binding. The endpoint handles three scenarios:
IdP-initiated logout (LogoutRequest): The IdP sends a SAMLRequest query parameter containing a LogoutRequest. ARX parses the request, extracts the NameID, invalidates the session, and redirects the user to the login page with ?slo=1.
SP-initiated logout response: When the IdP responds to an SP-initiated logout request, it sends a SAMLResponse parameter. ARX processes the response and redirects the user to the login page.
SP-initiated logout start: When called without SAML parameters, ARX terminates the local session and returns a JSON confirmation: {"status": "logged_out", "message": "SAML session terminated"}.
Certificate Configuration¶
SP Certificate (Signing)¶
To enable AuthnRequest signing, configure the SP certificate and private key:
SAML_SP_CERT=-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----
SAML_SP_KEY=-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----
When SAML_SP_CERT is configured, the certificate is included in the SP metadata under a <md:KeyDescriptor use="signing"> element. IdPs that require signed requests will use this certificate for verification.
IdP Certificate (Verification)¶
The IdP's signing certificate is extracted automatically from the IdP metadata XML. ARX fetches the metadata from the configured metadata_url and parses the X509Certificate element from the IDPSSODescriptor. No manual certificate configuration is required on the ARX side as long as the IdP publishes its metadata at a reachable URL.
SSO Configuration Table¶
Each organization's SAML configuration is stored in the sso_configs table:
| Field | Description |
|---|---|
org_id |
The organization UUID |
provider |
Must be saml |
domain |
The organization's email domain (used for domain-based lookup) |
metadata_url |
The IdP's metadata XML URL |
enabled |
Boolean. Set to false to disable SAML without deleting the configuration |
Environment Variables¶
| Variable | Required | Default | Description |
|---|---|---|---|
SAML_SP_ENTITY_ID |
No | https://api.arxsec.io/v1/auth/saml/metadata |
The SP entity ID used in AuthnRequests and metadata |
SAML_SP_CERT |
No | None | PEM-encoded SP signing certificate |
SAML_SP_KEY |
No | None | PEM-encoded SP private key |
ARXSEC_API_URL |
Yes | http://localhost:8000 |
Base URL for constructing ACS and SLO URLs |
SUPABASE_ANON_KEY |
Yes | -- | Used to sign session JWTs after SAML authentication |
Troubleshooting¶
| Symptom | Cause | Resolution |
|---|---|---|
404 No SAML configuration found |
No sso_configs row for the org/domain |
Insert a row with provider=saml, enabled=true, and the correct org_id or domain. |
400 SAML configuration missing metadata_url |
Config row exists but metadata_url is null |
Update the sso_configs row with the IdP's metadata URL. |
502 Failed to fetch IdP metadata |
Metadata URL unreachable | Verify the URL is correct and accessible from the ARX API server (15-second timeout). |
502 IdP metadata missing IDPSSODescriptor |
Malformed or incomplete IdP metadata | Verify the metadata URL returns a valid SAML IdP metadata document. |
400 SAML Response missing Assertion |
Malformed SAML response | Check the IdP configuration and ensure the user is assigned to the application. |
401 SAML authentication failed |
StatusCode is not Success |
Review the IdP logs for authentication errors (user not assigned, MFA failure, etc.). |
400 SAML assertion missing email |
NameID not set to email format | Configure the IdP to use EmailAddress as the NameID format. |
| Attribute mapping issues | IdP sends non-standard attribute names | Enable debug logging and inspect the saml_attributes field in the ACS response. |