InfrastructureInfrastructure Plugins

Sentinel

Monitor auth risk signals around a Kernia deployment.

Better Auth Sentinel is a hosted infrastructure plugin for abuse detection and security enforcement. Kernia does not currently ship a managed Sentinel service. The Kernia equivalent is an application security layer built with rate limits, captcha, breached-password checks, hooks, audit events, and session revocation.

Use this page to design Sentinel-style protections without claiming that a hosted Sentinel plugin exists.

Installation

Install the protections you plan to use:

uv add kernia kernia-api-key kernia-redis-storage

Add provider packages for the checks you enable. Use Redis for shared rate limits and a captcha provider for bot challenges.

Server configuration

auth.py
from kernia import KerniaOptions
from kernia.auth import init
from kernia.plugins.captcha import captcha
from kernia.plugins.have_i_been_pwned import have_i_been_pwned
from kernia.plugins.rate_limit import rate_limit

auth = init(KerniaOptions(
    database=adapter,
    secret=env.KERNIA_SECRET,
    plugins=[
        rate_limit(storage=redis_storage),
        captcha(provider=turnstile_provider),
        have_i_been_pwned(),
    ],
))

Signals

Track security signals at the route boundary and store them as audit events:

SignalHow to collect
Repeated invalid passwordsEmail/password sign-in failure hook.
OTP failuresEmail OTP and phone verification failure hooks.
Captcha failuresCaptcha plugin result.
Impossible travelCompare new session IP geo to last session.
Unusual API key usageAPI key usage logs by key, route, and IP.
SSO errorsSSO callback and domain verification errors.
SCIM failuresSCIM token and directory sync errors.
Webhook signature failuresStripe webhook verification failure path.
Admin config changesAdmin config write routes.

Enforcement

Sentinel-style enforcement should happen before the sensitive auth action executes.

security.py
async def before_password_sign_in(ctx):
    key = f"password:{ctx.request.ip}:{ctx.body.email.lower()}"
    failures = await security_store.increment(key, ttl_seconds=3600)

    if failures >= 5:
        await audit("auth.blocked", reason="credential_stuffing", email=ctx.body.email)
        raise AuthError("RATE_LIMITED", status=429)

    if failures >= 3:
        await require_captcha(ctx)

Feature mapping

Better Auth Sentinel featureKernia implementation path
Credential stuffingRate-limit failed password attempts by IP, email, and visitor fingerprint.
Impossible travelCompare session geography and require step-up authentication.
Bot blockingCaptcha plugin or edge bot detection before auth routes.
Suspicious IP blockingEdge firewall plus application deny list.
Compromised passwordHave I Been Pwned plugin during sign-up and password change.
Stale account alertHook on sign-in when last_active_at is older than your threshold.
Free trial abuseBilling/customer checks and visitor fingerprint limits.

Response

Security responses should be explicit and testable:

  • Return 429 for rate limits.
  • Return a captcha challenge for suspicious but not blocked traffic.
  • Require two-factor or passkey verification for step-up flows.
  • Revoke sessions when account takeover is suspected.
  • Record audit events for every block, challenge, admin override, and session revoke.

Schema changes

Most teams add:

TablePurpose
security_eventImmutable stream of challenges, blocks, suspicious logins, and admin overrides.
rate_limit_bucketShared counters when Redis is not used.
trusted_deviceDevice identity for unknown-device notifications.
session_riskRisk score and reason attached to active sessions.