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¶
Rate Limiting¶
See Rate Limiting for more details.
Best Practices¶
1. Progressive Security¶
Start lenient, tighten based on behavior:
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:
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¶
- Check site key matches domain
- Verify captcha token is fresh (< 2 minutes)
- Check network connectivity
False Positives¶
If legitimate users are blocked:
- Lower risk thresholds
- Add IP to whitelist
- Review risk factors weights
High Bot Traffic¶
- Enable stricter captcha
- Lower blocking thresholds
- 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
}
}