Skip to main content

Custom Connectors

Any system that can make an HTTP POST request can integrate with Humifortis. No SDK required.


Two Integration Patterns

Async — fire and forget. Send events to POST /events. The engine scores them asynchronously. No changes to your login flow. Ideal for evaluation and initial rollout.

Inline — enforce at authentication time. Call POST /evaluate during the login flow. The engine scores the event synchronously and returns a decision: ALLOW, CHALLENGE_MFA, or BLOCK.


Async Mode — Simplest Integration

import requests

def on_login_event(user_id, event_type, ip, user_agent):
requests.post(
"https://your-humifortis-instance/api/v1/events",
headers={
"X-API-Key": "YOUR_KEY",
"Content-Type": "application/json",
},
json={
"event": {
"event_id": str(uuid.uuid4()),
"entity_id": f"user:{user_id}",
"entity_type": "user",
"event_type": event_type, # e.g. "auth.login.failed"
"timestamp": datetime.utcnow().isoformat() + "Z",
"metadata": {
"ip_address": ip,
"user_agent": user_agent,
},
}
},
timeout=2,
)
# Fire-and-forget: POST /events returns 202 immediately

Inline Enforce Mode — Decision at Login Time

Use POST /evaluate to get a synchronous enforcement decision. The event is scored and the decision is returned in the same request.

import uuid
import requests
from datetime import datetime

def authenticate(user_id, ip, user_agent, enrolled_mfa_methods=None):
try:
resp = requests.post(
"https://your-humifortis-instance/api/v1/evaluate",
headers={
"X-API-Key": "YOUR_KEY",
"Content-Type": "application/json",
},
json={
"event": {
"event_id": str(uuid.uuid4()),
"entity_id": f"user:{user_id}",
"entity_type": "user",
"event_type": "auth.login.attempt",
"timestamp": datetime.utcnow().isoformat() + "Z",
"metadata": {
"ip_address": ip,
"user_agent": user_agent,
},
},
"user_mfa_profile": {
"enrolled_methods": enrolled_mfa_methods or [],
"email_verified": True,
"has_email": True,
},
},
timeout=3,
).json()

action = resp.get("action", "ALLOW")

if action == "BLOCK":
raise AuthenticationError("Login blocked by risk policy")
elif action == "CHALLENGE_MFA":
method = resp.get("recommended_mfa_method", "TOTP")
trigger_mfa_challenge(user_id, method)
# else ALLOW — proceed normally

except requests.Timeout:
pass # fail-open: allow if Humifortis is slow

Custom Event Mapping

If your system uses non-standard event names, map them in the Humifortis dashboard under Policies → Event Mappings → New mapping.

Your eventMapped toEffect
okta.user.session.startAUTH_LOGIN_SUCCESS+2.0 risk delta
my-app.brute-force-detectedAUTH_BRUTE_FORCE+30.0 risk delta
ad.account.lockoutAUTH_ACCOUNT_LOCKED+20.0 risk delta

Once mapped, send the original event name — Humifortis translates it internally.

Custom Event Mapping docs


Pull Model — Query Risk Scores

Instead of (or in addition to) inline enforcement, you can query risk scores on demand:

curl https://your-humifortis-instance/api/v1/risk/user:alice@example.com \
-H "X-API-Key: YOUR_KEY"

Use this for:

  • Pre-authorizing sensitive operations (admin panel access, data export)
  • Building custom dashboards or SIEM integrations
  • Periodic risk audits on your user base

Webhooks & CAEP

Humifortis can push risk events to your systems via webhooks or CAEP (Continuous Access Evaluation Protocol):

  • Webhooks: POST a payload when a risk threshold is crossed or a playbook action fires
  • CAEP SET tokens: signed Security Event Tokens that allow downstream systems (Keycloak, custom apps) to revoke active sessions in real time

Configure both under Settings → Integrations in the dashboard.


See Also