Skip to main content

Setup SAML

Configure SAML 2.0 for enterprise single sign-on integration with your AI applications and MCP servers.

Overview

Security Assertion Markup Language (SAML) 2.0 is an XML-based standard for exchanging authentication and authorization data between identity providers and service providers. SAML is commonly used in enterprise environments for single sign-on (SSO).

Benefits of SAML

  • Enterprise Integration: Works with existing enterprise identity systems
  • Single Sign-On: Users authenticate once across multiple applications
  • Centralized Management: IT administrators control access from one location
  • Security: Strong security with digital signatures and encryption
  • Compliance: Meets enterprise security and compliance requirements

SAML Configuration

1. Configure SAML in Authsec

Set up SAML as an identity provider connection:

  1. Navigate to ConnectionsEnterprise
  2. Click Create ConnectionSAML
  3. Configure the connection settings:
{
"name": "Enterprise SAML",
"strategy": "samlp",
"options": {
"sign_in_endpoint": "https://idp.company.com/sso/saml",
"sign_out_endpoint": "https://idp.company.com/slo/saml",
"x509_signing_cert": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----",
"tenant_domain": "company.com",
"domain_aliases": ["company.com", "subsidiary.com"],
"sign_saml_request": true,
"signature_algorithm": "rsa-sha256",
"digest_algorithm": "sha256"
}
}

2. Metadata Configuration

Service Provider Metadata

Authsec provides metadata for your identity provider:

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="https://your-domain.authsec.com">
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIIDEjCCAfqgAwIBAgIJALV...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://your-domain.authsec.com/login/callback"
index="0" isDefault="true"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>

Identity Provider Metadata

Configure your IdP metadata in Authsec:

{
"idp_metadata": {
"entity_id": "https://idp.company.com",
"sso_url": "https://idp.company.com/sso/saml",
"slo_url": "https://idp.company.com/slo/saml",
"certificate": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----"
}
}

3. Attribute Mapping

Map SAML attributes to user properties:

{
"attribute_mapping": {
"user_id": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
"email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"given_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
"family_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
"groups": "http://schemas.microsoft.com/ws/2008/06/identity/claims/groups",
"department": "http://schemas.company.com/identity/claims/department",
"employee_id": "http://schemas.company.com/identity/claims/employeeid"
}
}

Implementation

Web Application Integration

import { AuthsecClient } from '@authsec/sdk';

const authsec = new AuthsecClient({
domain: 'your-domain.authsec.com',
clientId: 'your-client-id'
});

// Initiate SAML login
function loginWithSAML() {
const authUrl = authsec.buildAuthorizeUrl({
response_type: 'code',
scope: 'openid profile email',
connection: 'samlp-enterprise' // SAML connection name
});

window.location.href = authUrl;
}

Handle SAML Response

// Handle SAML authentication callback
async function handleSAMLCallback(req, res) {
try {
const { code } = req.query;

// Exchange code for tokens
const tokens = await authsec.exchangeCodeForTokens({
code: code,
redirect_uri: 'https://yourapp.com/callback'
});

// Get user information
const user = await authsec.getUserInfo(tokens.access_token);

// Process SAML attributes
const enterpriseUser = {
id: user.sub,
email: user.email,
name: user.name,
department: user.department,
employeeId: user.employee_id,
groups: user.groups || [],
lastLogin: new Date()
};

// Store user session
req.session.user = enterpriseUser;
req.session.accessToken = tokens.access_token;

res.redirect('/dashboard');
} catch (error) {
console.error('SAML authentication failed:', error);
res.redirect('/login?error=saml_failed');
}
}

Group-Based Authorization

// Check user group membership for authorization
function checkGroupMembership(user, requiredGroups) {
const userGroups = user.groups || [];
return requiredGroups.some(group => userGroups.includes(group));
}

// Middleware for group-based access control
function requireGroups(groups) {
return (req, res, next) => {
if (!req.session.user) {
return res.status(401).json({ error: 'Not authenticated' });
}

if (!checkGroupMembership(req.session.user, groups)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}

next();
};
}

// Usage
app.get('/admin/users', requireGroups(['IT-Admins', 'HR-Managers']), (req, res) => {
// Only users in IT-Admins or HR-Managers groups can access
res.json({ users: getUserList() });
});

Advanced Configuration

Just-In-Time (JIT) Provisioning

Automatically create users when they first log in:

{
"jit_provisioning": {
"enabled": true,
"connection": "samlp-enterprise",
"user_creation": {
"enabled": true,
"sync_attributes": true
},
"profile_sync": {
"enabled": true,
"sync_on_login": true,
"attributes": ["name", "email", "department", "groups"]
}
}
}

Single Logout (SLO)

Configure single logout to end sessions across all applications:

// Initiate single logout
async function singleLogout() {
try {
// Revoke local tokens
await authsec.revokeToken(req.session.refreshToken);

// Clear local session
req.session.destroy();

// Redirect to SAML SLO endpoint
const sloUrl = authsec.buildLogoutUrl({
connection: 'samlp-enterprise',
returnTo: 'https://yourapp.com/'
});

res.redirect(sloUrl);
} catch (error) {
console.error('Single logout failed:', error);
res.redirect('/');
}
}

Custom SAML Attributes

Handle custom enterprise attributes:

// Process custom SAML attributes
function processCustomAttributes(samlUser) {
return {
standardProfile: {
id: samlUser.sub,
email: samlUser.email,
name: samlUser.name
},
enterpriseProfile: {
employeeId: samlUser['http://schemas.company.com/identity/claims/employeeid'],
department: samlUser['http://schemas.company.com/identity/claims/department'],
manager: samlUser['http://schemas.company.com/identity/claims/manager'],
costCenter: samlUser['http://schemas.company.com/identity/claims/costcenter'],
location: samlUser['http://schemas.company.com/identity/claims/location']
},
permissions: {
aiAccess: checkAIPermissions(samlUser.groups),
mcpTools: getMCPToolAccess(samlUser.department),
dataAccess: getDataAccessLevel(samlUser.groups)
}
};
}

Security Best Practices

Certificate Management

// Validate SAML certificates
function validateSAMLCertificate(cert) {
try {
const x509 = new crypto.X509Certificate(cert);

// Check certificate validity
const now = new Date();
if (now < x509.validFrom || now > x509.validTo) {
throw new Error('Certificate is expired or not yet valid');
}

// Verify certificate chain if applicable
return true;
} catch (error) {
console.error('Certificate validation failed:', error);
return false;
}
}

Signature Verification

// Verify SAML response signature
function verifySAMLSignature(samlResponse, certificate) {
try {
const verify = crypto.createVerify('RSA-SHA256');
verify.update(samlResponse);

return verify.verify(certificate, signature, 'base64');
} catch (error) {
console.error('Signature verification failed:', error);
return false;
}
}

Assertion Validation

// Validate SAML assertions
function validateSAMLAssertion(assertion) {
const checks = {
// Check assertion is not expired
notExpired: () => {
const conditions = assertion.Conditions;
const now = new Date();
return now >= new Date(conditions.NotBefore) &&
now <= new Date(conditions.NotOnOrAfter);
},

// Check audience restriction
audienceValid: () => {
const audience = assertion.Conditions.AudienceRestriction.Audience;
return audience === 'https://your-domain.authsec.com';
},

// Check subject confirmation
subjectConfirmed: () => {
const confirmation = assertion.Subject.SubjectConfirmation;
return confirmation.Method === 'urn:oasis:names:tc:SAML:2.0:cm:bearer';
}
};

return Object.values(checks).every(check => check());
}

Troubleshooting

Common Issues

  1. Certificate Errors: Verify certificate format and validity
  2. Attribute Mapping: Check attribute names match IdP configuration
  3. Clock Skew: Ensure server times are synchronized
  4. Signature Failures: Verify signing certificates and algorithms
  5. Redirect Loops: Check callback URL configuration

Debug SAML Responses

// Debug SAML response
function debugSAMLResponse(samlResponse) {
try {
// Decode base64 SAML response
const decoded = Buffer.from(samlResponse, 'base64').toString('utf-8');

// Parse XML
const parser = new xml2js.Parser();
parser.parseString(decoded, (err, result) => {
if (err) {
console.error('XML parsing failed:', err);
return;
}

console.log('SAML Response:', JSON.stringify(result, null, 2));

// Extract key information
const assertion = result.Response.Assertion[0];
console.log('Subject:', assertion.Subject[0].NameID[0]._);
console.log('Attributes:', assertion.AttributeStatement[0].Attribute);
});
} catch (error) {
console.error('SAML response debug failed:', error);
}
}

Validation Tools

Use online tools to validate SAML configuration:

  • SAML Response validators
  • Certificate validators
  • Metadata validators
  • Clock skew checkers

Enterprise Integration Examples

Active Directory Federation Services (ADFS)

{
"name": "ADFS Connection",
"strategy": "samlp",
"options": {
"sign_in_endpoint": "https://adfs.company.com/adfs/ls/",
"x509_signing_cert": "MIIDEjCCA...",
"tenant_domain": "company.com",
"field_map": {
"email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
}
}

Okta SAML Integration

{
"name": "Okta SAML",
"strategy": "samlp",
"options": {
"sign_in_endpoint": "https://company.okta.com/app/authsec_app/exk.../sso/saml",
"x509_signing_cert": "MIIDpDCCAoygAw...",
"tenant_domain": "company.com"
}
}

Azure AD SAML

{
"name": "Azure AD SAML",
"strategy": "samlp",
"options": {
"sign_in_endpoint": "https://login.microsoftonline.com/.../saml2",
"x509_signing_cert": "MIIC8DCCAdigAwIBA...",
"tenant_domain": "company.onmicrosoft.com"
}
}