Authentication

Authentication answers the question "who is making this request?" Manzano handles authentication in three layers — the browser, the edge, and your backend — and hands your Grove actions a validated identity in ctx.principal without ever exposing the raw token to application code.

Prerequisites: Familiarity with the Concepts Overview. What you'll learn: The three-layer authentication model, what Manzano does for you, and where to go to configure each piece.


Authentication vs. Authorization

These two words are often used interchangeably. In Manzano they are separate concerns with separate docs:

ConcernQuestionWhere it's configured
AuthenticationWho is making this request?This section (authentication/*)
AuthorizationIs this principal allowed to do X?Authorization Hooks and per-project Cedar policies

Authentication produces a ctx.principal. Authorization consumes it. If you are writing an authorize hook or a Cedar policy and wondering where ctx.principal.id comes from, you are in the right place.

The Three Layers

Every request to a Manzano-hosted app passes through three tiers. Each tier has a well-defined responsibility.

Layer 1 — Browser

The user's browser holds one long-lived cookie: the ID token, issued by whichever identity provider you have configured for your project. The browser never talks to your backend directly for login; it talks to Manzano's edge, which in turn talks to the identity provider.

Layer 2 — Edge

The edge worker sits in front of your backend and is responsible for:

Because the edge does the JWT work, your application code never validates tokens, never pulls JWKS, and never touches PKCE. That work is done once per request, at the edge, in a place that is always up to date.

Layer 3 — Backend (your Grove code)

Your Grove backend receives the request with identity headers already set and verified. The runtime:

In your action body, ctx.principal.id is simply the sub claim the identity provider issued — no extra configuration needed.

What Manzano does for you vs. what you configure

When you deploy a Manzano app, most of the machinery is automatic:

PieceHandled by ManzanoYour choice
Edge JWT validation✅—
JWKS fetching & caching✅—
Claim-to-header mapping✅ (defaults work)Optional overrides
HMAC request signing✅—
Login UI (chooser page)✅Optional theming
Session cookie handling✅Cookie name is tenant-configurable
Identity provider choice—You pick
Which routes require auth—You pick (see below)

Identity providers

Manzano supports two flavors of identity provider. You pick one (or one per environment) when you enable auth on your project.

External OIDC providers — Auth0, Clerk, WorkOS, Google, Apple, or any custom OIDC-compliant provider. You register your Manzano app in the provider's dashboard, paste the credentials into your project config, and the edge handles the rest.

Built-in email magic link — No external provider needed. The user enters their email on the login page, receives a one-time link, clicks it, and is signed in. Manzano mints its own short-lived JWT signed with a key it manages. Good for early-stage projects that want login without the Auth0 setup cost.

Both flavors are covered in Identity Providers, including per-provider setup steps.

Enabling auth on a project

Once you have picked a provider, enabling authentication is a matter of configuring it on your project and redeploying. See Enabling Authentication for the step-by-step.

One important behavior to know up front: when auth is configured, every dynamic route in your app requires authentication. Static assets stay public; your route.grove handlers and any [param] routes do not. This is all-or-nothing today; per-route opt-in is a planned future feature.

Anonymous routes are still possible — your Cedar policy can allow Role::"__anonymous" on specific actions. See the Authorization Hooks page for how that interacts with authentication state.

When you don't need auth

Many Grove projects start without authentication — workflow backends, webhook receivers, scheduled jobs, and read-only public sites all work fine without a principal. In that case:

You can add auth later without rewriting your actions.

Where to go next

See Also