Skip to content

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:

  1. Resolves the user in each targeted application (lookup).
  2. Calls that provider’s session-revoke API.
  3. Stores a single session revocation request with per-connector results.
  4. Reports the event on the Dashboard and (for completed requests) toward metered billing.

Supported connectors

ConnectorIntegration keyUsername format
OktaoktaOkta login or email (used in GET /api/v1/users/{id})
Microsoft EntraentraUser principal name (UPN) or mail
Google Workspacegoogle_workspacePrimary email address
Slack Enterpriseslack_enterpriseEmail address (users.lookupByEmail)
MiromiroEmail 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

  1. Log in at challenge.veraproof.io.
  2. Open Integrations and scroll to Session Revocation.
  3. 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:

SettingDescription
Allow revoke via MCP integrationMCP clients need the sessions:revoke scope and this checkbox enabled. See MCP Integration.
Allow revoke via Webhook integrationAccepts 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/webhook
X-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 hashlib
import hmac
import json
import 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,
"username": "[email protected]",
"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",
"username": "[email protected]",
"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

  1. In the Okta Admin Console, go to SecurityAPITokensCreate token.
  2. Name the token (for example, Challenge session revocation) and copy it immediately.
  3. 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 lookup
  • DELETE /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 settingOkta parameterEffect
Revoke OAuth/OIDC tokensoauthTokens=trueAlso revokes issued OAuth 2.0 and OpenID Connect refresh and access tokens for the user.
Forget remembered devicesforgetDevices=trueClears 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:

PermissionPurpose
User.Read.AllResolve user by UPN or mail
User.RevokeSessions.AllInvalidate 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:

  1. Create a Google Cloud project and enable the Admin SDK API.
  2. Create a service account and enable domain-wide delegation.
  3. In Google Workspace Admin, authorize the service account client ID with the scopes below.
  4. 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 scopePurpose
https://www.googleapis.com/auth/admin.directory.user.readonlyUser lookup
https://www.googleapis.com/auth/admin.directory.user.securitysignOut 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).

  1. Go to Slack API Apps and click Create New AppFrom manifest.
  2. Select your Enterprise Grid organization (or a workspace in the org).
  3. 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
}
}
  1. Open OAuth & Permissions.
  2. Under Scopes, confirm Bot Token Scopes includes users:read.email and User Token Scopes includes admin.users:write.
  3. Click Install to Organization (or Install to Workspace on Grid) and approve as an org/workspace admin.
  4. If prompted, complete user scope authorization so the app receives admin.users:write.
  5. 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:

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.lookupByEmail
  • admin.users.session.reset

Grant only:

ScopeToken typePurpose
users:read.emailBot or userResolve user by email
admin.users:writeUserReset 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 succeeded
  • user_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

SymptomThings to check
Session revocation is disabledMaster switch on Integrations page
MCP Insufficient scopeAuthorize sessions:revoke; enable MCP channel
Webhook invalid signatureUse the current sr_… secret from the last enable/rotate; sign raw body; header format sha256=...
Lost webhook signing secretToggle webhook off and on on Integrations to generate a new secret (shown once)
user_not_foundUsername format for that connector; user exists in target app
http_403 / permission errorsAPI token or Graph scopes; admin consent; domain-wide delegation
Okta optional flags too aggressiveDisable OAuth token or forget-devices if not required

Support

For help with session revocation configuration, contact [email protected].