Session Revocation
Session Revocation
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 | Setup guide |
|---|---|---|---|
| Okta | okta | Okta login or email | Okta |
| Microsoft Entra | entra | User principal name (UPN) or mail | Entra |
| Google Workspace | google_workspace | Primary email address | Google Workspace |
| Slack Enterprise | slack_enterprise | Email address | Slack Enterprise |
| Miro | miro | Email address | Miro |
| Zoom | zoom | Email or Zoom user ID | Zoom |
| Salesforce | salesforce | Salesforce | |
| GitHub | github | GitHub login (org member) | GitHub |
| Dropbox Business | dropbox | Dropbox | |
| Box | box | Email (Box login) | Box |
| PagerDuty | pagerduty | PagerDuty | |
| Zendesk | zendesk | Zendesk |
Connector API tokens and private keys are stored encrypted in Challenge. Secrets are write-only in the admin UI.
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, "username": "alice@example.com", "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": "alice@example.com", "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.
See the connector setup guides in the table above for credentials, API scopes, and least-privilege guidance.
Use the Responder page to test lookups and revocations against a dedicated test user before production rollouts.
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 and device containment. Your Billing page shows:
- Usage events = challenges + completed session revocations + completed device containments in the current period
- A breakdown of challenges, session revocations, and device containment
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 |
Connector-specific troubleshooting is covered in each setup guide linked above.
Related guides
- Responder — Manual challenges and session revocation from the admin UI
- Dashboard & Metrics — Revocation and containment statistics and activity
- MCP Integration —
revoke_sessionsandsessions:revokescope - Device Containment — MDM lock and EDR isolation
Support
For help with session revocation configuration, contact support@veraproof.io.