This guide explains how to configure Single Sign-On (SSO) using OpenID Connect (OIDC) for EdgeAI Telemetry.
EdgeAI Telemetry supports SSO via OIDC/OAuth2, allowing integration with identity providers like:
- Azure AD / Entra ID
- Okta
- Google Workspace
- Auth0
- Keycloak
- Any OIDC-compliant provider
- Prerequisites
- Provider Configuration
- Database Setup
- Environment Variables
- Testing SSO
- Troubleshooting
- EdgeAI Cloud Server v0.2.0 or later
- Administrator access to your identity provider
- Database migration
003_sso_alerting_audit.sqlapplied
-
Register an application in Azure Portal:
- Go to Azure Active Directory → App registrations → New registration
- Name:
EdgeAI Telemetry - Supported account types: Accounts in this organizational directory only
- Redirect URI:
Web→https://your-server/api/v1/auth/sso/callback/{provider-id}
-
Configure authentication:
- Go to Authentication → Add a platform → Web
- Add redirect URIs for all your server instances
- Enable "ID tokens" under Implicit grant and hybrid flows
-
Get credentials:
- Application (client) ID
- Create a client secret (Certificates & secrets)
- Note the tenant ID from Overview
-
OIDC Configuration URL:
https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration
-
Create an OIDC application:
- Go to Applications → Create App Integration
- Sign-in method: OIDC - OpenID Connect
- Application type: Web Application
-
Configure:
- Sign-in redirect URIs:
https://your-server/api/v1/auth/sso/callback/{provider-id} - Grant type: Authorization Code
- Sign-in redirect URIs:
-
Get credentials:
- Client ID and Client Secret from General tab
- Issuer URL:
https://{your-okta-domain}/oauth2/default
-
Configure OAuth consent screen:
- Go to Google Cloud Console → APIs & Services → OAuth consent screen
- Select "Internal" or "External"
- Add scopes:
openid,email,profile
-
Create OAuth 2.0 credentials:
- APIs & Services → Credentials → Create Credentials → OAuth client ID
- Application type: Web application
- Authorized redirect URIs:
https://your-server/api/v1/auth/sso/callback/{provider-id}
-
OIDC Configuration:
- Issuer URL:
https://accounts.google.com
- Issuer URL:
Insert your SSO provider configuration into the database:
INSERT INTO sso_providers (
name,
provider_type,
client_id,
client_secret,
issuer_url,
scopes,
is_active,
is_default
) VALUES (
'Azure AD',
'oidc',
'your-client-id',
'your-client-secret',
'https://login.microsoftonline.com/{tenant-id}/v2.0',
ARRAY['openid', 'email', 'profile'],
true,
true
);Or via API:
curl -X POST https://your-server/api/v1/auth/sso/providers \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Azure AD",
"provider_type": "oidc",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"issuer_url": "https://login.microsoftonline.com/{tenant-id}/v2.0",
"scopes": ["openid", "email", "profile"]
}'Add to your .env or environment:
# SSO Configuration
ENABLE_SSO=true
BASE_URL=https://your-server
# JWT Configuration
JWT_SECRET=your-256-bit-secret-key-here
JWT_EXPIRATION_HOURS=24curl https://your-server/api/v1/auth/sso/login/{provider-id}Response:
{
"success": true,
"data": {
"authorization_url": "https://login.microsoftonline.com/...",
"state": "random-state-string"
}
}- User clicks "Login with SSO" button
- Frontend calls
/api/v1/auth/sso/login/{provider-id} - Redirect user to
authorization_url - User authenticates with IdP
- IdP redirects to
/api/v1/auth/sso/callback/{provider-id} - Backend exchanges code for tokens
- User is logged in and receives JWT token
# Initiate SSO login
curl -X POST https://your-server/api/v1/auth/sso/login/{provider-id}
# After IdP redirects with code
curl -X POST https://your-server/api/v1/auth/sso/callback/{provider-id} \
-H "Content-Type: application/json" \
-d '{"code": "authorization-code-from-idp"}'When a user logs in via SSO for the first time:
- If email exists → Link SSO to existing account
- If email doesn't exist → Create new user with 'analyst' role
To pre-create users with specific roles:
-- Create user
INSERT INTO users (email, role, auth_method, sso_provider_id)
VALUES ('user@company.com', 'security_engineer', 'sso', {provider_id});
-- Assign roles
INSERT INTO user_roles (user_id, role_id)
SELECT u.id, r.id
FROM users u, roles r
WHERE u.email = 'user@company.com' AND r.name = 'security_engineer';- Verify client_id and client_secret are correct
- Check for extra spaces or encoding issues
- Ensure secret hasn't expired (Azure AD secrets expire)
- Exact match required (including protocol, port, path)
- No trailing slashes unless configured
- Must be HTTPS in production
- User's email in IdP must match email in EdgeAI
- Check
user_sso_linkstable for existing links
- Check system time is synchronized
- Verify issuer URL is correct
- Ensure signing algorithm matches (RS256)
Enable debug logging:
RUST_LOG=debug cargo run-- List all SSO providers
SELECT id, name, provider_type, issuer_url, is_active, is_default
FROM sso_providers;
-- List SSO-linked users
SELECT u.email, p.name as provider, usl.external_email, usl.last_login_at
FROM user_sso_links usl
JOIN users u ON usl.user_id = u.id
JOIN sso_providers p ON usl.provider_id = p.id;
-- Check user auth method
SELECT email, auth_method, sso_provider_id
FROM users
WHERE auth_method = 'sso';- Always use HTTPS in production
- Validate state parameter to prevent CSRF
- Short-lived authorization codes (max 10 minutes)
- Rotate client secrets regularly
- Use PKCE for public clients
- Validate ID token signatures with JWKS
- Check nonce to prevent replay attacks
- Configure MFA for additional security
- Set up Audit Logging to track SSO events
- Configure Role Mappings from IdP groups