Admin Intelligence — Agent-First Business Management
2026-03-05
LOCKSTEP TRACEABILITY MATRIX --- api_endpoints:
- "GET /v1/admin/tenants"
- "GET /v1/admin/tenants/:id"
- "POST /v1/admin/tenants/:id/approve"
- "POST /v1/admin/tenants/:id/reject"
- "POST /v1/admin/tenants/:id/suspend"
- "POST /v1/admin/invite-codes"
- "GET /v1/admin/invite-codes"
- "DELETE /v1/admin/invite-codes/:id"
- "GET /v1/admin/digest"
sdk_methods_updated:
- "client.admin.listTenants()"
- "client.admin.getTenant()"
- "client.admin.approveTenant()"
- "client.admin.rejectTenant()"
- "client.admin.suspendTenant()"
- "client.admin.createInviteCode()"
- "client.admin.listInviteCodes()"
- "client.admin.deleteInviteCode()"
- "client.admin.digest()"
mcp_tools_updated:
- "br_list_tenants"
- "br_approve_tenant"
- "br_reject_tenant"
- "br_get_business_digest"
- "br_create_invite_code"
---
What We Built
Admin Intelligence is BrainstormRouter's agent-first business management layer — a complete platform administration system designed for AI agents, not dashboards. Instead of building charts and tables for humans to stare at, we built an event-driven control plane where Slack buttons, MCP tools, and API calls are the primary interfaces.
The system has four pillars: (1) a typed pub/sub event bus that fans out platform events to Slack, Email, and future internal agents; (2) a beta gate that holds new signups in "pending" status until approved, with invite codes for bypass; (3) a 9-endpoint admin API with platform-admin-only authentication (user ID allowlist, not RBAC); and (4) 3-layer tenant status enforcement ensuring non-active tenants are blocked at every auth boundary — JWT middleware, API key auth, and the provision handler.
Every mutation endpoint supports ?dry_run=true, enabling future Virtual C-Suite agents to propose actions ("I would approve tenant X because their domain matches our ICP") without executing them until a human confirms via Slack.
Why It Matters
Before this, BrainstormRouter had zero admin visibility. New users could sign up and immediately start routing API traffic — no approval, no notification, no oversight. For a beta-stage product with real provider costs, this is untenable. The founder couldn't see who was signing up, couldn't gate access, and couldn't understand usage patterns.
The traditional solution is a React admin dashboard. We rejected that entirely. BrainstormRouter is an API engine for AI agents — the admin experience should be agent-native too. When a new user signs up, the founder gets a Slack notification with Approve/Reject buttons. When agents need business data, they call br_get_business_digest via MCP. The dry_run parameter on every mutation turns the admin API into a proposal/approval workflow that AI agents can participate in directly.
How It Works
Event Bus (src/infra/notifications/dispatcher.ts): A typed pub/sub system with wildcard support. Channels (Slack, Email) subscribe at boot. Events are fanned out via Promise.allSettled — one failing subscriber never blocks others.
const bus = getEventBus();
bus.emit({
type: "tenant.signup",
timestamp: new Date().toISOString(),
data: { tenantId, tenantSlug, tenantName, email, source: "organic" },
});
Beta Gate: 3-layer enforcement ensures non-active tenants are blocked everywhere:
requireActiveTenant()middleware on all/auth/*JWT routes (workspace, OAuth, auth sub-apps)- Tenant status check in
apiKeyAuth()for all/v1/*API-key routes - Status-aware response in
provisionUser()(202 for pending, 403 for rejected)
Invite Codes: Atomic consumption via conditional UPDATE prevents race conditions:
UPDATE invite_codes SET used_count = used_count + 1
WHERE code = $1
AND (max_uses IS NULL OR used_count < max_uses)
AND (expires_at IS NULL OR expires_at > NOW())
RETURNING *;
Slack Interactive Buttons: HMAC-SHA256 verified webhook handler at /webhooks/slack/action. Replay protection (5-min timestamp skew), crypto.timingSafeEqual(), form-encoded payload parsing. Buttons trigger tenant approval/rejection with event emission.
Admin Auth Model: Platform admin is resolved by user ID allowlist (BRAINSTORMROUTER_PLATFORM_ADMIN_IDS), not RBAC roles. Admin routes get their own middleware stack registered before the global /v1/* chain, bypassing rbacMiddleware() entirely. The same model is used for MCP tools via an explicit platform.admin branch in checkToolPermission().
The Numbers
- 9 admin API endpoints with full dry_run support
- 5 MCP admin tools accessible from Claude Desktop
- 3 enforcement layers for tenant status (JWT, API key, provision)
- 26 security findings addressed across 5 review rounds
- 4 event types:
tenant.signup,tenant.approved,tenant.rejected,tenant.activated - 2 notification channels: Slack (Block Kit with interactive buttons) + Email (Resend API)
- 30s Redis cache on API key lookups with tenant status check (no extra latency for hot path)
- 0 dashboard pages — fully agent-native admin experience
Competitive Edge
No AI gateway competitor offers agent-first administration. Portkey, OpenRouter, and LiteLLM all have traditional admin dashboards — static pages that require a human to log in, navigate, and click. BrainstormRouter's admin layer is designed for the future: AI agents subscribe to business events, propose actions via dry_run, and execute via the same MCP tools humans use from Claude Desktop. The PlatformEventBus is explicitly designed for Phase 2's Virtual C-Suite — autonomous agents (Growth Agent, Ops Agent, Security Agent) that will manage the platform alongside the founder.
Lockstep Checklist
> _You MUST check these boxes [x] and verify the corresponding files are updated BEFORE committing this log._
- [x] API Routes:
src/api/routes/admin.ts— 9 endpoints + Slack webhook handler - [x] TS SDK:
packages/sdk-ts/src/resources/admin.ts—Adminclass with all methods + types - [x] Python SDK:
packages/sdk-py/src/brainstormrouter/resources/admin.py—Admin+AsyncAdminclasses - [x] MCP Schemas: 5 admin tools in
src/mcp/server.ts+site/.well-known/agents.json - [x] OpenAPI:
docs/openapi.yaml— admin route specs + schemas