Session Revocation Integration
Session Revocation Integration
Session revocation lets security and IT teams invalidate active sessions when account takeover or impersonation is suspected. Challenge orchestrates revocation across configured connectors, records per-app outcomes, and exposes the same capability through the admin UI, MCP, and a signed webhook API.
Overview
When you trigger a revocation, Challenge:
- Resolves the user in each targeted application (lookup).
- Calls that provider’s session-revoke API.
- Stores a single session revocation request with per-connector results.
- Reports the event on the Dashboard and (for completed requests) toward metered billing.
Supported connectors
| Connector | Integration key | Username format |
|---|---|---|
| Okta | okta | Okta login or email (used in GET /api/v1/users/{id}) |
| Microsoft Entra | entra | User principal name (UPN) or mail |
| Google Workspace | google_workspace | Primary email address |
| Slack Enterprise | slack_enterprise | Email address (users.lookupByEmail) |
| Miro | miro | Email address |
Need another IdP or SaaS app? Additional session revocation connectors can be added at no extra cost on request. Contact [email protected] with the application name, required admin APIs, and your use case.
By default, a revocation runs against all enabled connectors. You can limit targets with integration_targets (Responder checkboxes, MCP, or webhook payload).
Prerequisites
- Owner, Admin, or Analyst role to run revocations from the Responder UI (Viewer is read-only). Owner or Admin is required to configure connectors under Integrations.
- An active payment method on the tenant (required for revocation actions).
- Session revocation enabled at the tenant level (master switch).
Enable session revocation
- Log in at challenge.veraproof.io.
- Open Integrations and scroll to Session Revocation.
- Click Enable Session Revocation and confirm.
The master switch must be on for any entry point (Responder, MCP, webhook) to work.
Optional entry points
While session revocation is enabled, you can independently control:
| Setting | Description |
|---|---|
| Allow revoke via MCP integration | MCP clients need the sessions:revoke scope and this checkbox enabled. See MCP Integration. |
| Allow revoke via Webhook integration | Accepts signed POST requests to the session-revocation webhook when enabled. |
Webhook signing secret
When you enable Allow revoke via Webhook integration, Challenge generates a signing secret automatically and shows it once in a copy dialog (same pattern as challenge API keys). Store it in your SOAR or secrets manager immediately — it cannot be viewed again in the admin UI.
To rotate the secret, toggle webhook integration off, then on again. A new secret is generated and shown once; update your automations before relying on the new value.
The secret is stored encrypted in Challenge. It uses the sr_ prefix (for example, sr_…) so you can distinguish it from challenge API keys (ch_…).
Webhook endpoint (when enabled):
POST /api/v1/session-revocation/webhookX-Session-Revocation-Signature: sha256=<hex-digest>The signature is HMAC-SHA256 over the raw request body, using your webhook signing secret. Compare using a constant-time equality check in your automation.
Complete example (Python 3, no third-party dependencies):
import hashlibimport hmacimport jsonimport urllib.request
WEBHOOK_SECRET = "sr_your_signing_secret_here"BASE_URL = "https://challenge.veraproof.io"TENANT_ID = "your-tenant-uuid"
payload = { "tenant_id": TENANT_ID, "action": "revoke_sessions", "reason": "SOAR containment", "integration_targets": ["okta", "google_workspace"], "source": "tines-playbook",}
body = json.dumps(payload, separators=(",", ":")).encode()sig = "sha256=" + hmac.new(WEBHOOK_SECRET.encode(), body, hashlib.sha256).hexdigest()
req = urllib.request.Request( f"{BASE_URL}/api/v1/session-revocation/webhook", data=body, headers={ "Content-Type": "application/json", "X-Session-Revocation-Signature": sig, }, method="POST",)
with urllib.request.urlopen(req) as resp: result = json.loads(resp.read())
print(result)# {'request_id': '...', 'job_status': 'completed'}Poll status:
GET /api/v1/session-revocation/requests/{request_id}?tenant_id=<tenant-uuid>Example webhook body:
{ "tenant_id": "your-tenant-uuid", "action": "revoke_sessions", "reason": "SOAR containment", "integration_targets": ["okta", "google_workspace"], "source": "tines-playbook"}Omit integration_targets to revoke on all enabled connectors.
Configure app connectors
For each connector, expand its panel under Session Revocation, enable it, enter credentials, and click Save. Secrets are write-only in the UI: leave a password field blank to keep the existing value.
Use the Responder page to test lookups and revocations against a dedicated test user before production rollouts.
Okta
Credentials
- In the Okta Admin Console, go to Security → API → Tokens → Create token.
- Name the token (for example,
Challenge session revocation) and copy it immediately. - In Challenge, set Okta domain (for example,
https://your-org.okta.com) and API token.
Least-privilege guidance
Challenge calls:
GET /api/v1/users/{userId}— user lookupDELETE /api/v1/users/{userId}/sessions— clear sessions
Create a custom admin role (or use a narrowly scoped role) that allows user read and session management without unrelated admin rights. Okta documents API token administration in Create an API token.
Typical Okta permissions to include:
- Read users (for lookup by login)
- Clear user sessions / manage user sessions
Avoid granting full Super Administrator if a custom role suffices.
Optional settings
These map to query parameters on Okta’s Clear all sessions for a user API:
| Challenge setting | Okta parameter | Effect |
|---|---|---|
| Revoke OAuth/OIDC tokens | oauthTokens=true | Also revokes issued OAuth 2.0 and OpenID Connect refresh and access tokens for the user. |
| Forget remembered devices | forgetDevices=true | Clears remembered MFA factors on all devices for the user. |
Enable only what your incident-response policy requires. Revoking OAuth tokens is broader than ending browser IdP sessions alone; forgetting devices forces MFA on the next sign-in.
For full API semantics and parameter behavior, see Okta’s official documentation:
Microsoft Entra
Credentials
Challenge stores a Microsoft Graph access token (Bearer) used for lookup and revocation. Obtain a token through your preferred method:
- App registration (recommended for automation): Register an app in Entra ID, grant application permissions (see below), and acquire a client-credentials token for
https://graph.microsoft.com/.default. - Short-lived testing: Use Graph Explorer or similar to generate a token, paste it into Challenge, and replace it before expiry.
Least-privilege guidance
Challenge calls:
GET https://graph.microsoft.com/v1.0/users?$filter=userPrincipalName eq '...' or mail eq '...'POST https://graph.microsoft.com/v1.0/users/{id}/revokeSignInSessions
Grant application permissions (admin consent required), not excess directory roles:
| Permission | Purpose |
|---|---|
User.Read.All | Resolve user by UPN or mail |
User.RevokeSessions.All | Invalidate refresh tokens and end browser sessions per Microsoft’s model |
See revokeSignInSessions and Microsoft Graph permissions reference. Access tokens may remain valid until expiry; plan containment accordingly.
Rotate the client secret on your app registration on a schedule; update the token in Challenge when using client credentials.
Google Workspace
Credentials
Challenge stores a Google Admin SDK access token (Bearer). Typical setup:
- Create a Google Cloud project and enable the Admin SDK API.
- Create a service account and enable domain-wide delegation.
- In Google Workspace Admin, authorize the service account client ID with the scopes below.
- Use the service account to mint an access token for a super-admin or dedicated admin user impersonation target, then paste the token into Challenge (or automate refresh outside Challenge).
Least-privilege guidance
Challenge calls:
GET https://admin.googleapis.com/admin/directory/v1/users/{userKey}POST https://admin.googleapis.com/admin/directory/v1/users/{userKey}/signOut
Authorize only:
| OAuth scope | Purpose |
|---|---|
https://www.googleapis.com/auth/admin.directory.user.readonly | User lookup |
https://www.googleapis.com/auth/admin.directory.user.security | signOut for a user |
See Directory API: users.signOut. Use a dedicated admin role in Workspace that can manage user security settings, not full super-admin, when your policy allows.
Slack Enterprise
Session revocation for Slack requires Slack Enterprise Grid. The Admin API methods Challenge uses are not available on free or standard workspace plans.
Create a Slack app (manifest)
Use a dedicated Slack app for session revocation (separate from the Slack challenge integration app is recommended).
- Go to Slack API Apps and click Create New App → From manifest.
- Select your Enterprise Grid organization (or a workspace in the org).
- Paste the manifest below and click Create.
{ "display_information": { "name": "Veraproof Challenge Session Revocation", "description": "Reset member sessions for Challenge incident response", "background_color": "#1f2937", "long_description": "Used by Veraproof Challenge to look up users by email and reset all Slack sessions during account takeover response. Requires Enterprise Grid." }, "features": { "bot_user": { "display_name": "Veraproof Session Revoke", "always_online": false } }, "oauth_config": { "scopes": { "bot": [ "users:read.email" ], "user": [ "admin.users:write" ] } }, "settings": { "org_deploy_enabled": true, "socket_mode_enabled": false, "token_rotation_enabled": false }, "_metadata": { "major_version": 2, "minor_version": 1 }}- Open OAuth & Permissions.
- Under Scopes, confirm Bot Token Scopes includes
users:read.emailand User Token Scopes includesadmin.users:write. - Click Install to Organization (or Install to Workspace on Grid) and approve as an org/workspace admin.
- If prompted, complete user scope authorization so the app receives
admin.users:write. - Copy a bearer token that can call both APIs (see below) and paste it into Challenge as Slack bot token (admin scopes).
Obtain the API token
Challenge sends the token as a Bearer value on every Slack API call. Per Slack’s documentation:
users.lookupByEmailaccepts a bot or user token withusers:read.email.admin.users.session.resetrequires a user token withadmin.users:write(not a bot-only token).
After installation, use the User OAuth Token (xoxp-...) from OAuth & Permissions if it includes both required scopes. If lookup succeeds but session reset returns missing_scope or not_allowed_token_type, reinstall with user scopes approved or contact your Slack org admin to allow the app’s admin scopes.
Note: The Challenge field is labeled “bot token” for historical reasons; paste whichever single token your installation provides that satisfies both methods above.
Least-privilege guidance
Challenge calls:
users.lookupByEmailadmin.users.session.reset
Grant only:
| Scope | Token type | Purpose |
|---|---|---|
users:read.email | Bot or user | Resolve user by email |
admin.users:write | User | Reset all sessions for a member |
Do not add chat, slash-command, or broad admin.* scopes unless your security team requires them for unrelated reasons. See admin.users.session.reset.
Test with Responder using a non-production member account before production incidents.
Miro
Credentials
Obtain a Miro API access token from your enterprise integration settings (Miro Enterprise plans). Paste it into Challenge as Miro API access token.
Least-privilege guidance
Challenge calls:
POST https://api.miro.com/v2/sessions/reset_all?email={email}
Use an enterprise token limited to user session administration for your organization. See Reset all sessions for a user. Miro does not expose a separate lookup API in this flow; Challenge treats the email as the subject for reset.
Revocation outcomes
Each connector returns an outcome recorded on the request, for example:
revoked/tokens_revoked— provider API succeededuser_not_found— no matching user (lookup or provider 404)failed— configuration, permission, or HTTP error
A request is completed when no connector reports failed; if any connector fails, the overall request status is failed. Only completed requests count toward Stripe metered usage.
Billing
Completed session revocation requests are reported to the same Stripe meter as challenge creation. Your Billing page shows:
- Usage events = challenges + completed session revocations in the current period
- A breakdown of challenges vs session revocations
Failed revocations are not billed. See Upgrading Pricing Tiers for tier limits and overage behavior.
Test with Responder
After saving a connector, use Responder to run Revoke sessions for a test account, optionally selecting only the connector you are validating. Confirm success on the result JSON and on the Dashboard activity feed before enabling production automations.
Troubleshooting
| Symptom | Things to check |
|---|---|
Session revocation is disabled | Master switch on Integrations page |
MCP Insufficient scope | Authorize sessions:revoke; enable MCP channel |
Webhook invalid signature | Use the current sr_… secret from the last enable/rotate; sign raw body; header format sha256=... |
| Lost webhook signing secret | Toggle webhook off and on on Integrations to generate a new secret (shown once) |
user_not_found | Username format for that connector; user exists in target app |
http_403 / permission errors | API token or Graph scopes; admin consent; domain-wide delegation |
| Okta optional flags too aggressive | Disable OAuth token or forget-devices if not required |
Related guides
- Responder — Manual challenges and session revocation from the admin UI
- Dashboard & Metrics — Revocation statistics and activity
- MCP Integration —
revoke_sessionsandsessions:revokescope - Device Containment — Planned MDM/EDR actions (coming soon)
Support
For help with session revocation configuration, contact [email protected].