skills/modular-sso/SKILL.md
Implements complete SSO and authentication flows using Scalekit. Handles modular SSO, IdP-initiated login, user session management, and enterprise customer onboarding. Use when adding authentication, SSO, SAML, OIDC, or user login to applications.
npx skillsauth add scalekit-inc/skills modular-ssoInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Choose your authentication mode:
This skill covers Modular SSO for applications with existing user management.
Copy this checklist and track progress:
Authentication Integration Progress:
- [ ] Step 1: Configure Modular Auth mode
- [ ] Step 2: Install and configure Scalekit SDK
- [ ] Step 3: Implement authorization URL generation
- [ ] Step 4: Handle IdP-initiated SSO (RECOMMENDED)
- [ ] Step 5: Process authentication callback
- [ ] Step 6: Validate tokens and extract user profile
- [ ] Step 7: Test SSO integration
- [ ] Step 8: Set up customer onboarding flow
Action: Configure environment for Modular SSO:
Result: System ready for modular integration.
Choose the SDK for the project's tech stack:
Node.js:
npm install @scalekit-sdk/node
Python:
pip install scalekit-sdk-python
Go:
go get github.com/scalekit-inc/scalekit-sdk-go
Java:
<dependency>
<groupId>com.scalekit</groupId>
<artifactId>scalekit-sdk-java</artifactId>
</dependency>
Add these credentials to .env file (fetch from Dashboard > Developers > Settings > API credentials):
SCALEKIT_ENVIRONMENT_URL=<environment-url>
SCALEKIT_CLIENT_ID=<client-id>
SCALEKIT_CLIENT_SECRET=<client-secret>
Create authorization URL to redirect users to their identity provider.
Use ONE of these identifiers (evaluated in precedence order):
Node.js:
const scalekit = new ScalekitClient(
process.env.SCALEKIT_ENVIRONMENT_URL,
process.env.SCALEKIT_CLIENT_ID,
process.env.SCALEKIT_CLIENT_SECRET
);
const options = {
organizationId: 'org_15421144869927830', // OR
connectionId: 'conn_15696105471768821', // OR
loginHint: '[email protected]'
};
const authUrl = scalekit.getAuthorizationUrl(
'https://yourapp.com/auth/callback',
options
);
// Redirect user to authUrl
Python:
from scalekit import ScalekitClient, AuthorizationUrlOptions
scalekit = ScalekitClient(
os.getenv('SCALEKIT_ENVIRONMENT_URL'),
os.getenv('SCALEKIT_CLIENT_ID'),
os.getenv('SCALEKIT_CLIENT_SECRET')
)
options = AuthorizationUrlOptions()
options.organization_id = 'org_15421144869927830'
auth_url = scalekit.get_authorization_url(
redirect_uri='https://yourapp.com/auth/callback',
options=options
)
Direct URL (no SDK):
<SCALEKIT_ENVIRONMENT_URL>/oauth/authorize?
response_type=code&
client_id=<CLIENT_ID>&
redirect_uri=<CALLBACK_URL>&
scope=openid profile email&
organization_id=<ORG_ID>
CRITICAL: Implement this to support users who start login from their identity provider portal.
IdP-initiated SSO converts potentially insecure flows into secure SP-initiated flows, protecting against SAML assertion theft and replay attacks.
https://yourapp.com/loginNode.js:
app.get('/login', async (req, res) => {
const { idp_initiated_login, error, error_description } = req.query;
if (error) {
return res.status(400).json({ message: error_description });
}
if (idp_initiated_login) {
// Decode JWT to extract connection details
const claims = await scalekit.getIdpInitiatedLoginClaims(idp_initiated_login);
const options = {
connectionId: claims.connection_id,
organizationId: claims.organization_id,
loginHint: claims.login_hint,
state: claims.relay_state
};
const authUrl = scalekit.getAuthorizationUrl(
'https://yourapp.com/auth/callback',
options
);
return res.redirect(authUrl);
}
// Handle normal login flow
});
Python:
@app.route('/login')
async def handle_login():
idp_initiated_login = request.args.get('idp_initiated_login')
error = request.args.get('error')
if error:
return {'error': request.args.get('error_description')}, 400
if idp_initiated_login:
claims = await scalekit.get_idp_initiated_login_claims(idp_initiated_login)
options = AuthorizationUrlOptions()
options.connection_id = claims.get('connection_id')
options.organization_id = claims.get('organization_id')
options.state = claims.get('relay_state')
auth_url = scalekit.get_authorization_url(
redirect_uri='https://yourapp.com/auth/callback',
options=options
)
return redirect(auth_url)
Handle the callback after successful IdP authentication.
/auth/callbackNode.js:
app.get('/auth/callback', async (req, res) => {
const { code, error, error_description } = req.query;
if (error) {
return res.status(400).json({ error: error_description });
}
try {
// Exchange code for user profile and tokens
const result = await scalekit.authenticateWithCode(
code,
'https://yourapp.com/auth/callback'
);
// Extract user information
const userEmail = result.user.email;
const userName = result.user.givenName + ' ' + result.user.familyName;
const userId = result.user.id;
// Create session for authenticated user
req.session.user = {
id: userId,
email: userEmail,
name: userName
};
res.redirect('/dashboard');
} catch (err) {
res.status(500).json({ error: 'Authentication failed' });
}
});
Python:
@app.route('/auth/callback')
async def auth_callback():
code = request.args.get('code')
error = request.args.get('error')
if error:
return {'error': request.args.get('error_description')}, 400
result = scalekit.authenticate_with_code(
code,
'https://yourapp.com/auth/callback'
)
# Create session
session['user'] = {
'id': result.user.id,
'email': result.user.email,
'name': f"{result.user.given_name} {result.user.family_name}"
}
return redirect('/dashboard')
ALWAYS validate tokens before trusting claims.
Node.js:
// Validate ID token
const idTokenClaims = await scalekit.validateToken(result.idToken);
// Validate access token
const accessTokenClaims = await scalekit.validateToken(result.accessToken);
Python:
id_token_claims = scalekit.validate_token(result['id_token'])
access_token_claims = scalekit.validate_token(result['access_token'])
ID Token includes:
email: User's email addressgiven_name, family_name: User's namesub: Unique user identifier (format: connectionId;userId)oid: Organization IDamr: Authentication method (SSO connection ID)Access Token includes:
sub: User identifierexp: Expiration timestampclient_id: Your application client IDUse the built-in IdP Simulator for comprehensive testing.
Your environment includes pre-configured test organization with domains:
@example.com@example.org@example.com domainTest ALL three scenarios:
Enable SSO for enterprise customers through self-service Admin Portal.
Create organization: Dashboard > Organizations > New Organization
Generate portal link (Node.js):
const portalLink = await scalekit.organization.generatePortalLink(
'org_32656XXXXXX0438'
);
// Share this link with customer's IT admin
console.log('Admin Portal:', portalLink.location);
Share link: Send to customer's IT administrator via email/Slack
Share setup guide: Include the Scalekit SSO setup guide — provider-specific steps for Okta, Azure AD, Google Workspace, and others.
Embed Admin Portal in your app for seamless experience:
// Backend: Generate portal link
const portalLink = await scalekit.organization.generatePortalLink(orgId);
res.json({ portalUrl: portalLink.location });
<!-- Frontend: Embed in iframe -->
<iframe
src="${portalUrl}"
width="100%"
height="600"
frameborder="0"
allow="clipboard-write">
</iframe>
Prevent failed redirects by checking SSO configuration before redirecting:
Node.js:
const domain = email.split('@').toLowerCase(); [reddit](https://www.reddit.com/r/ClaudeAI/comments/1qb1024/ultimate_claude_skillmd_autobuilds_any_fullstack/)
const connections = await scalekit.connections.listConnectionsByDomain({
domain
});
if (connections.length > 0) {
// SSO available - redirect to IdP
const authUrl = scalekit.getAuthorizationUrl(redirectUri, {
domainHint: domain
});
return res.redirect(authUrl);
} else {
// No SSO - show password login
return showPasswordLogin();
}
Enable seamless routing by verifying customer domains:
@megacorp.org) in Admin PortalSet secure session configuration:
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true, // HTTPS only
httpOnly: true, // Prevent XSS
maxAge: 86400000, // 24 hours
sameSite: 'lax' // CSRF protection
}
}));
Implement session refresh:
// Check token expiration
if (Date.now() / 1000 > accessTokenClaims.exp) {
// Redirect to re-authentication
return res.redirect('/login');
}
Configure Scalekit as Custom Social Connection in Auth0:
Add Scalekit as Custom Auth Provider:
Configure Scalekit as SAML Identity Provider:
Before production deployment, verify:
secure and httpOnly flagsCause: Callback URL not registered in dashboard Fix: Add URL to Dashboard > Authentication > Redirect URLs
Cause: Invalid organization ID or user doesn't belong to organization Fix: Verify organization ID and user's email domain
Cause: Initiate login URL not configured Fix: Set URL in Dashboard > Authentication > Redirects
Cause: Token expired or invalid signature Fix: Check token expiration and environment URL configuration
// Determine organization from subdomain
const subdomain = req.hostname.split('.');
const organization = await getOrganizationBySubdomain(subdomain);
const authUrl = scalekit.getAuthorizationUrl(redirectUri, {
organizationId: organization.scalekitOrgId
});
// Require re-authentication for sensitive operations
if (requiresStepUp && !session.recentAuth) {
return res.redirect('/auth/step-up');
}
app.post('/logout', (req, res) => {
req.session.destroy();
res.redirect('/');
});
Scalekit Dashboard: https://app.scalekit.com
Connection Selector Precedence: connectionId > organizationId > loginHint
Token Expiration: ID tokens expire in 15 minutes, access tokens in 24 hours
Admin Portal Events: Listen for sso.enabled, sso.disabled, session.expired
Support: docs.scalekit.com
Always validate tokens: Never trust token claims without validation
Handle errors gracefully: Show user-friendly messages, log details internally
Test all scenarios: SP-initiated, IdP-initiated, and domain-based routing
Enable domain verification: Provides best user experience
Use progressive enhancement: Start with basic SSO, add advanced features iteratively
Monitor authentication flows: Track success rates and common failure points
tools
Create or review Scalekit custom providers/connectors for proxy-only usage, including MCP providers. Use this skill when the task is to gather API docs, infer whether a connector is OAuth, Basic, Bearer, or API Key, determine if it is an MCP provider, determine required tracked fields like domain or version, generate provider JSON, check for existing custom providers, show update diffs, run approved create or update curls, and print resolved delete curls.
tools
Use when a developer is new to Scalekit and needs guidance on where to start, doesn't know which auth plugin or skill to choose, wants to connect an AI agent or agentic workflow to third-party services (Gmail, Slack, Notion, Google Calendar), needs OAuth or tool-calling auth for agents, wants to add authentication to a project but hasn't chosen an approach yet, or needs to install the Scalekit plugin for their AI coding tool (Claude Code, Codex, Copilot CLI, Cursor, or other agents).
tools
Use when a user asks to generate, review, validate, or fix any code snippet that uses Scalekit APIs or SDKs. This skill is the single source of truth for Scalekit code correctness — it can generate illustration-quality snippets from scratch (for docs, websites, or integration guides) and review existing code to catch wrong method names, missing parameters, security anti-patterns, and broken auth flows. Covers all four SDKs (Node, Python, Go, Java), raw REST API calls, and both Scalekit product suites — SaaSKit (SSO, login, sessions, RBAC, SCIM) and AgentKit (connections, tool calling, MCP auth). Use when the user says review my Scalekit code, generate a Scalekit example, validate this auth flow, check my SDK usage, fix my Scalekit integration, write a code sample for docs, or anything involving Scalekit code quality.
development
Walks through a structured production readiness checklist for Scalekit SSO implementations. Use when the user says they are going live, launching to production, doing a pre-launch review, hardening their SSO setup, or wants to verify their Scalekit implementation is production-ready.