Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Intercept authentication flows

Authentication interceptors let you run custom validation at key points in the authentication flow. Use them to enforce security policies, apply business rules, or tailor the user experience during sign-up and login.

Scalekit exposes trigger points where you attach interceptors. For example, you can block sign-ups from suspicious IPs, restrict domains, or require approval for new registrations.


Pre-signup interceptor sequence
Trigger pointWhen it runs
Pre-signupBefore a user creates a new organization
Pre-session creationBefore session tokens are issued for a user
Pre-user invitationBefore an invitation is created or sent for a new organization member
Pre-M2M token creationBefore issuing a machine-to-machine access token

In the Scalekit dashboard, register an interceptor at a trigger point from the Interceptors tab.

Interceptors page Interceptors settings in the Scalekit dashboard


  1. Enter a descriptive name, choose a trigger point, and provide the HTTPS endpoint that will receive POST requests.
  2. Set the timeout for your app’s response.
  3. Choose the fallback behavior if your app fails or times out (allow or block the flow).
  4. Click Create.
  5. Toggle Enable to activate the interceptor.
PRE_SIGNUP — request body
{
"display_name": "Pre-Signup",
"trigger_point": "PRE_SIGNUP",
"interceptor_context": {
"environment_id": "env_92561807201272162",
"user_id": "usr_93418238346728951", // Present when the user already exists (for example, member of another organization)
"user_email": "john.doe@example.com",
"connection_details": [
6 collapsed lines
{
"id": "conn_92561808744978132",
"type": "OAUTH",
"provider": "GOOGLE"
}
],
"device_type": "Desktop",
"ip_address": "203.0.113.24",
"region": "IN",
"city": "Bengaluru",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
"triggered_at": "2025-10-09T09:48:02.875Z"
},
"data": {
// Present when the user already exists (for example, member of another organization)
"user": {
"id": "usr_93418238346728951",
"name": "John Doe",
5 collapsed lines
"email": "john.doe@example.com",
"email_verified": true,
"created_at": "2025-10-06T11:06:49.120Z",
"updated_at": "2025-10-06T13:33:06.479Z",
"first_name": "John",
"last_name": "Doe",
"memberships": [
{
"organization_id": "org_93418204671239864",
"status": "ACTIVE"
}
]
}
}
}
PRE_SESSION_CREATION — request body
{
"display_name": "Add custom claims to tokens",
"trigger_point": "PRE_SESSION_CREATION",
"interceptor_context": {
"environment_id": "env_92561807204567213",
"user_id": "usr_93418238346728951",
"user_email": "john.doe@example.com",
"organization_id": "org_93418204671239864",
"connection_details": [
{
6 collapsed lines
"id": "conn_92561808744978132",
"type": "OAUTH",
"provider": "GOOGLE"
}
],
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
"device_type": "Desktop",
"ip_address": "203.0.113.24",
"region": "US",
"city": "San Francisco",
"triggered_at": "2025-10-08T15:22:42.381Z"
},
"data": {
"user": {
"id": "usr_93418238346728951",
"name": "John Doe",
"email": "john.doe@example.com",
"email_verified": true,
"created_at": "2025-10-06T11:06:49.120Z",
"updated_at": "2025-10-06T13:33:06.479Z",
"first_name": "John",
"last_name": "Doe",
"memberships": [
{
5 collapsed lines
"organization_id": "org_93418204671239864",
"status": "ACTIVE"
}
]
}
}
}
PRE_USER_INVITATION — request body
{
"display_name": "Block invites to suspicious emails",
"trigger_point": "PRE_USER_INVITATION",
"interceptor_context": {
"environment_id": "env_92561807201272162",
"user_id": "usr_93418238346728951", // Present when the invited user already exists (for example, member of another organization)
"user_email": "john.doe@example.com",
"organization_id": "org_93731871904672153",
"city": "Bengaluru",
"device_type": "Desktop",
"ip_address": "182.156.5.2",
"region": "IN",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
"triggered_at": "2025-10-09T12:50:41.803Z"
},
"data": {
"organization": {
"id": "org_93731871904672153",
"name": "Acme Corp"
}
}
}
PRE_M2M_TOKEN_CREATION — request body
{
"display_name": "Add custom claim",
"trigger_point": "PRE_M2M_TOKEN_CREATION",
"interceptor_context": {
"environment_id": "env_17002334043308132",
"client_id": "m2morg_93710427703245914",
"user_agent": "PostmanRuntime/7.48.0",
"device_type": "Unknown",
"triggered_at": "2025-10-08T21:22:20.173Z"
},
"data": {
"m2m_token_claims": {
"client_id": "m2morg_93710427703245914",
"claims": {
4 collapsed lines
"custom_claims": {
"c1": "v1",
"c2": "v2"
},
"oid": "org_89669394174574792",
"scope": "deploy:applications read:deployments",
"scopes": [
3 collapsed lines
"deploy:applications",
"read:deployments"
]
}
}
}
}

Scalekit keeps a log of every interceptor request sent to your app and the response it returned. Use these logs to debug and troubleshoot issues.

Interceptor logs in the dashboard

Requests and responses generated by the “Test” button are not logged. This keeps production logs free of test data.

Scalekit sends POST requests to your registered interceptor endpoint. To ensure the request is coming from Scalekit and not a malicious actor, you should verify the request using the signing secret found in the Scalekit dashboard > Interceptors.

Here’s how to verify interceptor requests using the Scalekit SDK:

app.post('/auth/interceptors/pre-signup', async (req, res) => {
// Parse the JSON body of the request
const event = await req.json();
// Get headers from the request
const headers = req.headers;
// Secret from Scalekit dashboard > Interceptors
const secret = process.env.SCALEKIT_INTERCEPTOR_SECRET;
try {
// Verify the interceptor payload
await scalekit.verifyInterceptorPayload(secret, headers, event);
} catch (error) {
return res.status(400).json({
error: 'Invalid signature',
});
}
});

Open the Test tab on the Interceptors page. The left panel shows the request body sent to your endpoint, and the right panel shows your application’s response.

Based on your application’s response, you can decide to allow or deny the user auth flow to continue to sign up or log into your application. This allows for you to test and take the interceptors live in production.

Interceptors test tab example

For quick testing without building or deploying an endpoint, use a request bin service like Beeceptor or RequestBin. These services provide temporary endpoints that capture incoming requests and let you configure responses, making them ideal for interceptor development and validation.