OIDC SSO (Okta, Microsoft Entra ID, Google Workspace)¶
ARX provides native OpenID Connect (OIDC) single sign-on integrations for Okta, Microsoft Entra ID (formerly Azure AD), and Google Workspace. This guide covers the SSO flow, provider configuration, environment variables, and just-in-time (JIT) user provisioning.
Architecture¶
The OIDC SSO implementation uses the standard authorization code grant flow. ARX acts as the relying party (RP). The flow involves three endpoints:
POST /v1/auth/sso/authorize-- Initiates the SSO flow and returns the provider's authorization URL.POST /v1/auth/sso/callback-- Handles the callback after the user authenticates, exchanges the authorization code for tokens, and provisions the user.GET /v1/auth/sso/providers-- Lists configured SSO providers and their availability.
SSO Flow¶
Step 1: Initiate Authorization¶
The client sends a POST request to start the SSO flow:
curl -X POST "https://api.arxsec.io/v1/auth/sso/authorize" \
-H "Content-Type: application/json" \
-d '{
"provider": "okta",
"domain": "acme.okta.com"
}'
The provider field accepts okta, microsoft, or google. The optional domain field can be used for multi-tenant configurations.
The response contains a redirect_url:
{
"redirect_url": "https://acme.okta.com/oauth2/default/v1/authorize?response_type=code&client_id=...&redirect_uri=https://api.arxsec.io/v1/auth/sso/callback&scope=openid+profile+email&state=..."
}
A cryptographically random state parameter is generated and stored server-side for CSRF protection. The client redirects the user's browser to this URL.
Step 2: User Authenticates with Provider¶
The user authenticates with their identity provider using their organizational credentials and any MFA policies configured at the provider level. ARX does not control or have visibility into this step.
Step 3: Handle Callback¶
After successful authentication, the provider redirects the user back with an authorization code. The client posts the code to the callback endpoint:
curl -X POST "https://api.arxsec.io/v1/auth/sso/callback" \
-H "Content-Type: application/json" \
-d '{
"code": "AUTHORIZATION_CODE",
"state": "STATE_TOKEN",
"provider": "okta"
}'
ARX performs the following operations:
- Validates the
stateparameter against the stored value (CSRF protection). - Exchanges the authorization code for an ID token and access token at the provider's token endpoint.
- Validates the ID token signature (RS256 via JWKS), issuer, and audience.
- Extracts the
sub,email(orpreferred_username), andnameclaims. - Performs JIT user provisioning (creates the user if they do not exist).
- Returns the access token and user profile.
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"user": {
"id": "a1b2c3d4-...",
"org_id": "e5f6a7b8-...",
"email": "jane@acme.com",
"role": "viewer",
"full_name": "Jane Doe",
"sso_provider": "okta"
}
}
Configuring Okta¶
In the Okta Admin Console¶
- Navigate to Applications > Create App Integration.
- Select OIDC - OpenID Connect and Web Application.
- Set the Sign-in redirect URI to
https://api.arxsec.io/v1/auth/sso/callback. - Set Sign-out redirect URI (optional):
https://app.arxsec.io/login. - Under Assignments, assign the application to the appropriate users or groups.
- Copy the Client ID and Client Secret from the application settings.
- Note your Okta domain (e.g.,
acme.okta.com).
Environment Variables¶
OKTA_DOMAIN=acme.okta.com
OKTA_CLIENT_ID=0oa1b2c3d4e5f6g7h8i9
OKTA_CLIENT_SECRET=your-client-secret
Token Validation Parameters¶
| Parameter | Value |
|---|---|
| Authorization URL | https://<OKTA_DOMAIN>/oauth2/default/v1/authorize |
| Token URL | https://<OKTA_DOMAIN>/oauth2/default/v1/token |
| Expected Issuer | https://<OKTA_DOMAIN>/oauth2/default |
| Audience | Value of OKTA_CLIENT_ID |
| Algorithm | RS256 (via JWKS) |
| Scopes | openid profile email |
Configuring Microsoft Entra ID¶
In the Azure Portal¶
- Navigate to Microsoft Entra ID > App registrations > New registration.
- Set the Redirect URI to
https://api.arxsec.io/v1/auth/sso/callback(Web platform). - Under Certificates & secrets, create a new client secret and copy the value.
- Under API permissions, ensure
openid,profile, andemailare granted as delegated permissions. - Note the Application (client) ID and Directory (tenant) ID from the Overview page.
Environment Variables¶
MICROSOFT_TENANT_ID=your-tenant-id
MICROSOFT_CLIENT_ID=your-client-id
MICROSOFT_CLIENT_SECRET=your-client-secret
Token Validation Parameters¶
| Parameter | Value |
|---|---|
| Authorization URL | https://login.microsoftonline.com/<MICROSOFT_TENANT_ID>/oauth2/v2.0/authorize |
| Token URL | https://login.microsoftonline.com/<MICROSOFT_TENANT_ID>/oauth2/v2.0/token |
| Expected Issuer | https://login.microsoftonline.com/<MICROSOFT_TENANT_ID>/v2.0 |
| Audience | Value of MICROSOFT_CLIENT_ID |
| Algorithm | RS256 (via JWKS) |
| Scopes | openid profile email |
Configuring Google Workspace¶
In the Google Cloud Console¶
- Navigate to APIs & Services > Credentials > Create Credentials > OAuth 2.0 Client ID.
- Select Web application as the application type.
- Add
https://api.arxsec.io/v1/auth/sso/callbackto the Authorized redirect URIs. - Copy the Client ID and Client Secret.
Environment Variables¶
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
Token Validation Parameters¶
| Parameter | Value |
|---|---|
| Authorization URL | https://accounts.google.com/o/oauth2/v2/auth |
| Token URL | https://oauth2.googleapis.com/token |
| Expected Issuer | https://accounts.google.com |
| Audience | Value of GOOGLE_CLIENT_ID |
| Algorithm | RS256 (via JWKS) |
| Scopes | openid profile email |
JIT User Provisioning¶
When a user authenticates via OIDC SSO for the first time, ARX automatically creates a user record with the following attributes:
- Email: Extracted from the
emailorpreferred_usernameclaim. - Full name: Extracted from the
nameclaim. - SSO subject: The
subclaim, used as a stable identifier for subsequent logins. - SSO provider: The provider name (
okta,microsoft, orgoogle). - Role: Defaults to
viewer. Administrators can change roles after provisioning, or use SCIM group-to-role mapping for automated role assignment.
JIT-provisioned users are associated with an organization based on domain matching or the SSO configuration.
Checking Provider Availability¶
To determine which SSO providers are configured, call:
curl "https://api.arxsec.io/v1/auth/sso/providers"
The response lists each provider with a configured boolean:
{
"providers": [
{"provider": "okta", "configured": true},
{"provider": "microsoft", "configured": false},
{"provider": "google", "configured": true},
{"provider": "auth0", "configured": true},
{"provider": "supabase", "configured": true}
]
}
A provider is considered configured when its required environment variables (domain/tenant ID and client ID) are set.
All Environment Variables¶
| Variable | Required | Description |
|---|---|---|
OKTA_DOMAIN |
For Okta | Okta organization domain (e.g., acme.okta.com) |
OKTA_CLIENT_ID |
For Okta | OIDC application client ID |
OKTA_CLIENT_SECRET |
For Okta | OIDC application client secret |
MICROSOFT_TENANT_ID |
For Entra ID | Azure AD directory (tenant) ID |
MICROSOFT_CLIENT_ID |
For Entra ID | App registration client ID |
MICROSOFT_CLIENT_SECRET |
For Entra ID | App registration client secret |
GOOGLE_CLIENT_ID |
For Google | OAuth 2.0 client ID |
GOOGLE_CLIENT_SECRET |
For Google | OAuth 2.0 client secret |
ARXSEC_API_URL |
Yes | Base URL of the ARX API (used to construct callback URLs) |
Security Considerations¶
- State parameter: A cryptographically random
statetoken is generated for every authorization request and validated on callback to prevent CSRF attacks. - Token validation: ID tokens are validated for signature (RS256 via JWKS), issuer, and audience before extracting claims.
- HTTPS required: All redirect URIs must use HTTPS in production.
- Client secret storage: Store provider client secrets in a secrets manager. Never commit them to source control.
- Token exchange timeout: The HTTP client for token exchange uses a 15-second timeout to prevent hanging requests.
Troubleshooting¶
| Symptom | Cause | Resolution |
|---|---|---|
400 Okta SSO is not configured |
Missing OKTA_DOMAIN or OKTA_CLIENT_ID |
Set the required environment variables and restart the API. |
400 Invalid or expired state parameter |
CSRF state mismatch or timeout | Ensure the callback is invoked promptly after authorization. The state is stored in memory and lost on restart. |
502 Failed to exchange authorization code |
Token exchange with provider failed | Verify the client secret and redirect URI match the provider configuration exactly. |
502 SSO provider did not return an ID token |
Provider misconfiguration | Ensure the openid scope is included in the provider's application settings. |
401 SSO token validation failed |
ID token signature or claims invalid | Confirm the issuer, audience, and JWKS endpoint are accessible from the ARX API server. |
400 SSO token missing required claims |
Missing sub or email in ID token |
Verify that profile and email scopes are granted in the provider configuration. |