Skip to content

Captcha & Risk Management

Protect your authentication endpoints from bots and automated attacks.


Overview

USSO includes built-in captcha and risk scoring to prevent: - Automated bot registrations - Brute force login attempts - Spam and abuse


Captcha Configuration

Enable Captcha

Configure in tenant settings:

curl -X PATCH http://localhost:8000/api/sso/v1/tenants/TENANT_ID \\
  -H "Authorization: Bearer TOKEN" \\
  -d '{
    "config": {
      "captcha_enabled": true,
      "captcha_threshold": 0.5
    }
  }'

Protected Endpoints

Captcha can be required for: - /auth/login - /auth/register - /auth/reset-password - /auth/request-otp


Usage

Request with Captcha

curl -X POST http://localhost:8000/api/sso/v1/auth/login \\
  -H "Content-Type: application/json" \\
  -d '{
    "identifier": "[email protected]",
    "secret": "password123",
    "captcha_token": "CAPTCHA_TOKEN_FROM_CLIENT"
  }'
response = requests.post(
    "http://localhost:8000/api/sso/v1/auth/login",
    json={
        "identifier": "[email protected]",
        "secret": "password123",
        "captcha_token": captcha_token
    }
)
const response = await fetch('http://localhost:8000/api/sso/v1/auth/login', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
        identifier: '[email protected]',
        secret: 'password123',
        captcha_token: captchaToken
    })
});

Client-Side Integration

Google reCAPTCHA

<script src="https://www.google.com/recaptcha/api.js"></script>

<form onsubmit="handleSubmit(event)">
  <input type="email" name="email" required>
  <input type="password" name="password" required>
  <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
  <button type="submit">Login</button>
</form>

<script>
async function handleSubmit(event) {
    event.preventDefault();

    const captchaToken = grecaptcha.getResponse();

    const response = await fetch('/api/sso/v1/auth/login', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({
            identifier: event.target.email.value,
            secret: event.target.password.value,
            captcha_token: captchaToken
        })
    });

    if (response.ok) {
        // Login successful
    } else {
        // Show error
    }
}
</script>

hCaptcha

<script src="https://js.hcaptcha.com/1/api.js"></script>

<form onsubmit="handleSubmit(event)">
  <input type="email" name="email" required>
  <input type="password" name="password" required>
  <div class="h-captcha" data-sitekey="YOUR_SITE_KEY"></div>
  <button type="submit">Login</button>
</form>

Risk Scoring

USSO analyzes multiple factors to assess login risk:

Risk Factors

Factor Weight Description
Failed attempts High Number of recent failures
IP reputation High Known malicious IPs
Location change Medium Login from new country
Device fingerprint Medium Unknown device
Time of day Low Unusual login time
Velocity High Too many attempts too fast

Risk Scores

{
  "risk_score": 0.75,  # 0 (safe) to 1 (high risk)
  "factors": [
    {"type": "failed_attempts", "score": 0.8},
    {"type": "ip_reputation", "score": 0.3},
    {"type": "new_device", "score": 0.6}
  ],
  "action": "require_captcha"  # or "block", "allow"
}

Action Thresholds

{
  "low_risk": 0.3,      # Allow without captcha
  "medium_risk": 0.6,   # Require captcha
  "high_risk": 0.8      # Block temporarily
}

IP Blocking

Automatic Blocking

{
  "ip_block_threshold": 10,        # Failed attempts
  "ip_block_window": 300,          # 5 minutes
  "ip_block_duration": 3600        # Block for 1 hour
}

Manual IP Blocking

curl -X POST http://localhost:8000/api/sso/v1/admin/ip-blocks \\
  -H "Authorization: Bearer TOKEN" \\
  -d '{
    "ip_address": "1.2.3.4",
    "reason": "Suspicious activity",
    "expires_at": "2025-10-05T00:00:00Z"
  }'

List Blocked IPs

curl -X GET http://localhost:8000/api/sso/v1/admin/ip-blocks \\
  -H "Authorization: Bearer TOKEN"

Rate Limiting

See Rate Limiting for more details.


Best Practices

1. Progressive Security

Start lenient, tighten based on behavior:

# First attempt: No captcha
# 2-3 attempts: Show captcha
# 5+ attempts: Block temporarily

2. User Experience

Balance security with UX:

# ✅ Good: Captcha only when needed
if risk_score > 0.6:
    require_captcha()

# ❌ Bad: Always require captcha
require_captcha()  # Annoys legitimate users

3. Monitor and Adjust

Track metrics:

metrics = {
    "captcha_success_rate": 0.95,
    "false_positives": 0.02,
    "blocked_bots": 1500
}

Adjust thresholds based on data.

4. Whitelist Trusted IPs

curl -X POST http://localhost:8000/api/sso/v1/admin/ip-whitelist \\
  -H "Authorization: Bearer TOKEN" \\
  -d '{
    "ip_address": "203.0.113.0/24",
    "description": "Office network"
  }'

Troubleshooting

Captcha Always Fails

  1. Check site key matches domain
  2. Verify captcha token is fresh (< 2 minutes)
  3. Check network connectivity

False Positives

If legitimate users are blocked:

  1. Lower risk thresholds
  2. Add IP to whitelist
  3. Review risk factors weights

High Bot Traffic

  1. Enable stricter captcha
  2. Lower blocking thresholds
  3. Consider additional authentication factors

Configuration Reference

{
  "captcha": {
    "enabled": true,
    "provider": "recaptcha",  # or "hcaptcha"
    "site_key": "...",
    "secret_key": "...",
    "threshold": 0.5
  },
  "risk_scoring": {
    "enabled": true,
    "thresholds": {
      "low": 0.3,
      "medium": 0.6,
      "high": 0.8
    }
  },
  "ip_blocking": {
    "enabled": true,
    "threshold": 10,
    "window": 300,
    "duration": 3600
  }
}