Skip to content

IR-2: Compromised API Key

A compromised API key occurs when a credential has been exposed and may have been used by an unauthorized actor. Common causes include accidental commit to a public repository, inclusion in logs or error messages, insecure sharing (Slack, email), or exfiltration from a developer workstation.

For unified credential management and rotation procedures, see Credential Management. For Credential Intelligence breach detection, see Credential Intelligence.


This incident is typically detected through one or more of the following signals:

Signal Source Confidence
CredInt hit — key prefix found in breach corpus credint_hit audit event HIGH
GitHub secret scanning alert (via webhook) External — GitHub Advanced Security HIGH
Customer report — key found in public repository Out-of-band HIGH
API calls from unexpected IP addresses auth.api_key_used with anomalous GeoIP MEDIUM
Unusual request volume on a key Rate limit events / usage dashboard MEDIUM
Admin operations by non-admin user Audit events from unexpected user role HIGH

Identify the specific credential from a CredInt alert:

Terminal window
# Look up credint audit events for the org
curl -s "https://api.arbitex.ai/api/v1/admin/audit-logs/?action=credint_hit&created_after=<window_iso>" \
-H "Authorization: Bearer $STAFF_TOKEN" | jq '.events[] | {timestamp, metadata}'

The metadata field on a credint_hit event includes key_prefix (first 8 characters), org_id, and match_source (corpus name).

Find credential record from key prefix:

Terminal window
curl -s "https://api.arbitex.ai/api/v1/admin/credentials?key_prefix=<8_char_prefix>" \
-H "Authorization: Bearer $STAFF_TOKEN" | jq '.credentials[] | {id, type, org_id, owner_id, created_at, last_used}'

Condition Severity
Key exposed but no unauthorized use detected MEDIUM
Key used from unexpected IP, no admin operations HIGH
Key used for admin-scoped operations HIGH
New credentials, users, or policy changes created with the key CRITICAL
Data exfiltration confirmed — large content volume or export operations CRITICAL

Escalate to CRITICAL immediately if any of the following appear in the audit trail for the compromised key:

  • credential.created (attacker created a backdoor key)
  • user.created or user.role_changed (privilege escalation)
  • policy.updated or dlp.rule_updated (sabotage of security controls)
  • audit.export (data exfiltration)

Step Action Command / UI
1 Declare incident POST /api/staff/incident/declare
2 Revoke the compromised key immediately DELETE /api/v1/admin/credentials/{id}
3 Kill all sessions for the key owner DELETE /api/v1/admin/users/{user_id}/sessions
4 Freeze audit log POST /api/staff/emergency/audit/freeze
5 Begin audit trail investigation Query events filtered by key prefix

Step 1 — Declare incident:

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/staff/incident/declare" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Compromised API key — prefix <key_prefix>",
"severity": "HIGH",
"playbook": "IR-2",
"org_id": "<org_uuid>"
}' | jq '{incident_id: .id, ic_expires: .ic_window_expires}'

Step 2 — Revoke the compromised key immediately:

Terminal window
curl -s -X DELETE "https://api.arbitex.ai/api/v1/admin/credentials/<credential_id>" \
-H "Authorization: Bearer $STAFF_TOKEN" \
| jq '{status, revoked_at}'

Revocation is immediate. There is no grace period — the key becomes invalid for all subsequent requests upon revocation.

Step 3 — Kill sessions for the key owner:

Terminal window
# Find the owner user_id from the credential record
OWNER_ID=$(curl -s "https://api.arbitex.ai/api/v1/admin/credentials/<credential_id>" \
-H "Authorization: Bearer $STAFF_TOKEN" | jq -r '.owner_id')
curl -s -X DELETE "https://api.arbitex.ai/api/v1/admin/users/${OWNER_ID}/sessions" \
-H "Authorization: Bearer $STAFF_TOKEN"

Step 4 — Freeze audit log:

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/staff/emergency/audit/freeze" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{"incident_id": "<incident_id>", "reason": "IR-2: Preserving audit evidence for compromised key investigation"}'

After the key is revoked, conduct a thorough investigation of what the key was used for. The goal is to determine the full scope: what was accessed, what was created, and whether lateral movement occurred.

Retrieve all audit events attributed to the compromised key:

Terminal window
# The key_prefix is used as a filter — all requests authenticated with this key share this prefix in metadata
curl -s "https://api.arbitex.ai/api/v1/admin/audit-logs/?org_id=<org_uuid>&key_prefix=<8_char_prefix>&limit=500" \
-H "Authorization: Bearer $STAFF_TOKEN" | jq '.events[] | {timestamp, action, source_ip, metadata}'

Check for unauthorized admin operations:

Terminal window
# Look for admin-class actions during breach window
curl -s "https://api.arbitex.ai/api/v1/admin/audit-logs/?org_id=<org_uuid>&action=admin.config_read&created_after=<breach_start_iso>" \
-H "Authorization: Bearer $STAFF_TOKEN" | jq '.events'

Check for new credentials created during breach window:

Terminal window
curl -s "https://api.arbitex.ai/api/v1/admin/audit-logs/?org_id=<org_uuid>&action=credential.created&created_after=<breach_start_iso>" \
-H "Authorization: Bearer $STAFF_TOKEN" | jq '.events[] | {timestamp, metadata}'

If any credential.created events are found during the breach window and not attributable to legitimate activity, revoke those credentials immediately — they are backdoors.

Check for new users or role changes:

Terminal window
curl -s "https://api.arbitex.ai/api/v1/admin/audit-logs/?org_id=<org_uuid>&action=user.created&created_after=<breach_start_iso>" \
-H "Authorization: Bearer $STAFF_TOKEN" | jq '.events'

Verify audit chain integrity over the breach window:

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/v1/admin/audit/verify" \
-H "Authorization: Bearer $STAFF_TOKEN" \
| jq '{valid, total_entries, errors}'

Assess data exfiltration risk:

Review audit events for content API calls (gateway.request, gateway.response) during the breach window. Look for:

  • Unusually high request counts compared to normal baseline
  • Requests for content types outside the key’s normal usage pattern
  • Any audit.export events

Scale containment to the confirmed scope of the breach.

Condition Action
Single key, no lateral movement Revoke key (done in step 3), issue replacement
Backdoor credentials found Revoke each backdoor, then bulk revoke all org credentials
New users created Disable unauthorized user accounts, audit their activity
Policy/DLP changes made Revert changes, follow IR-3 if DLP was modified
Admin operations confirmed Bulk revoke all org credentials, isolate tenant

Revoke backdoor credentials found during investigation:

Terminal window
# Repeat for each unauthorized credential ID found in audit trail
curl -s -X DELETE "https://api.arbitex.ai/api/v1/admin/credentials/<backdoor_credential_id>" \
-H "Authorization: Bearer $STAFF_TOKEN"

Bulk revoke all org credentials (lateral movement confirmed):

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/staff/emergency/credentials/revoke-all" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"org_id": "<org_uuid>",
"incident_id": "<incident_id>",
"reason": "IR-2: Lateral movement confirmed — bulk revocation of all org credentials"
}' | jq '{revoked_count: .revoked}'

Tenant isolation (CRITICAL — admin operations or exfiltration confirmed):

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/staff/emergency/tenant/isolate" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"org_id": "<org_uuid>",
"incident_id": "<incident_id>",
"reason": "IR-2 CRITICAL: Admin operations or data exfiltration confirmed — tenant isolated"
}'

Begin recovery only after containment is complete and the breach scope is fully understood.

Step Action Verification
1 Revert any unauthorized config changes Check each resource class modified during breach
2 Remove unauthorized users Audit user.created events, deactivate unauthorized accounts
3 Issue replacement API key to customer POST /api/v1/admin/credentials/{id}/rotate
4 Notify customer to update integrations Provide new key prefix and rotation instructions
5 Restore tenant access if isolated POST /api/staff/emergency/tenant/restore
6 Verify platform health /readyz, /health/deep

Issue replacement credential (rotate):

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/v1/admin/credentials/<credential_id>/rotate" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{"grace_period_seconds": 0}'

The rotated response includes the new secret value — provide this to the key owner via a secure channel (Staff UI credential delivery, not email).

Restore tenant access after CRITICAL isolation:

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/staff/emergency/tenant/restore" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"org_id": "<org_uuid>",
"incident_id": "<incident_id>",
"reason": "IR-2: Containment complete, replacement credentials issued, org admin identity verified"
}'

Verify platform health:

Terminal window
curl -s "https://api.arbitex.ai/readyz" | jq '.'
curl -s "https://api.arbitex.ai/health/deep" | jq '{status, db, redis, providers}'

Initial notification to key owner (within 15 minutes of revocation)

Section titled “Initial notification to key owner (within 15 minutes of revocation)”
Subject: [ACTION REQUIRED] Your Arbitex API key has been revoked — security incident
Your API key (prefix: <KEY_PREFIX>) has been revoked due to a security incident.
What happened:
Your API key was detected in an external breach corpus / public repository / [source].
We have revoked the key immediately to prevent unauthorized access.
What you need to do:
1. Contact our security team to verify your identity and receive a replacement key.
2. Audit any systems that used this key for unauthorized access.
3. Search your codebase and logs for any other exposed secrets.
Your key was last used: [LAST_USED_TIMESTAMP] from IP [LAST_USED_IP]
Incident reference: [INCIDENT_ID]

Notification to org admin (if key owner is not the org admin)

Section titled “Notification to org admin (if key owner is not the org admin)”

Send simultaneously to the org admin to ensure visibility:

Subject: [ALERT] API key in your organization has been revoked — security incident
An API key belonging to [USER_EMAIL] in your Arbitex organization has been revoked.
Reason: Key was found exposed externally.
Incident: [INCIDENT_ID]
Please review your organization's credential inventory and contact [email protected]
if you have concerns about other exposed credentials.
Terminal window
curl -s -X POST "https://api.arbitex.ai/api/v1/admin/audit/export" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"org_id": "<org_uuid>",
"start_date": "<breach_start_date>",
"end_date": "<recovery_complete_date>",
"format": "json",
"filter_key_prefix": "<8_char_prefix>",
"include_metadata": true
}' -o "incident-<incident_id>-key-usage-export.json"

Evidence preservation checklist:

Item Status
Compromised key ID and prefix recorded [ ]
Full audit export (breach window) saved to secure storage [ ]
All IP addresses key was used from documented [ ]
All operations performed with key enumerated [ ]
Any backdoor credentials found and revoked [ ]
HMAC chain verification result recorded [ ]
Incident timeline document created [ ]

Close incident:

Terminal window
curl -s -X POST "https://api.arbitex.ai/api/staff/incident/<incident_id>/close" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"resolution": "Key revoked, scope assessed, replacement issued, customer notified",
"root_cause": "<describe: public repo commit / credential stuffing / insider / unknown>",
"data_exfiltrated": false
}'

Lessons learned template:

  • What was the exposure path (public repo, log file, Slack message, other)?
  • How long was the key exposed before detection?
  • Did CredInt detection fire, or was this customer-reported?
  • Were any backdoor credentials or users created that were not immediately obvious?
  • Does the customer have a secrets scanning solution in their CI/CD pipeline? If not, recommend one.

Related playbooks: