Agent SaaS Starter

Architecture

Process boundaries, data ownership, and the authorization path.

flowchart LR
  Browser -->|HttpOnly session cookie| Web[Next.js app / BFF]
  Web -->|Session authorization header| API[Axum API]
  Agent -->|OAuth discovery + consent| API
  Agent -->|Audience-bound bearer token| MCP[rmcp resource server]
  API --> DB[(PostgreSQL)]
  MCP -->|Local RS256 verification| MCP
  MCP -->|Authenticated random-number request| API

Responsibilities

ComponentOwns
apps/appForms, consent UI, and the opaque session cookie
services/apiUsers, sessions, tenancy, upstream OIDC, OAuth/OIDC issuance, and audit records
services/mcpMCP transport, resource discovery, bearer challenges, and tool authorization
crates/authPassword/token primitives, PKCE, JWT/JWK, and OAuth validation
crates/dbPostgreSQL connection and embedded migrations
crates/mcpReusable MCP authorization and security metadata helpers

MCP discovery validates tokens locally; each random-number tool call also reaches the API. It validates the JWT signature, issuer, audience, expiry, and scope locally. The access token carries the user, workspace, project, role, client, and scope chosen during consent.

Tenant invariant

Every application session has one active workspace and project. Every OAuth grant is bound to one project and one RFC 8707 resource. A tool therefore receives an explicit project context instead of relying on ambient global state.

On this page