Skip to content

feat: add security audit plugin with brute-force detection#748

Merged
lane711 merged 6 commits intomainfrom
lane711/security-audit-plugin
Apr 7, 2026
Merged

feat: add security audit plugin with brute-force detection#748
lane711 merged 6 commits intomainfrom
lane711/security-audit-plugin

Conversation

@lane711
Copy link
Copy Markdown
Collaborator

@lane711 lane711 commented Apr 7, 2026

Summary

  • Adds a new opt-in Security Audit Plugin that logs login attempts (success/failure), registrations, logouts, and permission events
  • Includes brute-force detection with configurable per-IP and per-email thresholds, sliding-window counters via KV, and automatic lockout
  • Provides a full admin dashboard with stats cards, hourly trend chart, top IPs table, filterable event log, settings page, and JSON/CSV export
  • Introduces a dynamic plugin menu system via HTML marker injection middleware, so plugins can add sidebar links without modifying templates

Changes

  • packages/core/src/plugins/core-plugins/security-audit-plugin/ — Full plugin implementation (types, services, middleware, routes, components, manifest)
  • packages/core/src/middleware/plugin-menu.ts — New middleware for dynamic sidebar menu injection
  • packages/core/migrations/034_security_audit_plugin.sql — Migration for security_events table
  • packages/core/src/app.ts — Register plugin routes and middleware
  • packages/core/src/db/schema.ts — Add securityEvents Drizzle table definition
  • packages/core/src/db/migrations-bundle.ts — Include migration 034
  • packages/core/src/plugins/core-plugins/index.ts — Export new plugin
  • packages/core/src/routes/admin-plugins.ts — Add to AVAILABLE_PLUGINS with install handler
  • packages/core/src/templates/layouts/admin-layout-catalyst.template.ts — Add dynamic menu marker

Testing

  • Unit tests pass
  • E2E tests pass
  • Plugin can be installed/activated from admin Plugins page
  • Security sidebar link appears only when plugin is active
  • Dashboard loads with stats, charts, and event log
  • Brute-force lockout triggers after threshold exceeded
  • Settings save and persist correctly

🤖 Generated with Claude Code

Add a new opt-in security audit plugin that:
- Logs login attempts (success/failure), registrations, logouts, and permission events
- Detects brute-force attacks with configurable per-IP and per-email thresholds
- Provides lockout mechanism via KV with sliding-window counters
- Includes admin dashboard with stats cards, hourly trend chart, top IPs table
- Includes filterable/paginated event log with expandable detail rows
- Includes settings page for brute-force thresholds, logging toggles, and retention
- Exposes JSON API for events, stats, lockouts, and CSV/JSON export
- Adds dynamic plugin menu system via HTML marker injection middleware

New files:
- security-audit-plugin (types, services, middleware, routes, components, manifest)
- plugin-menu middleware for dynamic sidebar injection
- Migration 034 for security_events table

Modified files:
- app.ts: register plugin routes and middleware
- schema.ts: add securityEvents Drizzle table
- migrations-bundle.ts: include migration 034
- core-plugins/index.ts: export new plugin
- admin-plugins.ts: add to AVAILABLE_PLUGINS
- admin-layout-catalyst.template.ts: add dynamic menu marker

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Match both /auth/login and /auth/login/form paths
- Extract email before next() via request clone so it's available post-response
- Detect form login failures by checking auth_token cookie (form returns 200 for both success/failure)
- Enforce KV expirationTtl minimum of 60s (Cloudflare requirement)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rate limiter was silently broken because KV PUT rejected TTLs under
60s. Now that the TTL floor is fixed, the original tight limits (3-5
per minute) cause 429s in e2e tests and are too aggressive for
production use. Increase to reasonable values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test suite makes 30+ auth requests from the same IP within 60s.
With KV's 60s minimum TTL, the rate limit window persists at least
that long. Increase to 30/min for login and register routes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lane711 lane711 merged commit 32d0571 into main Apr 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant