Skip to main content
The documentation site is gated behind the platform login. When an unauthenticated visitor hits a private docs page, Papervine redirects them to a minting endpoint on the API, which authenticates them from their session cookie, signs a short-lived JWT, and redirects them back to the docs — already signed in. No SPA round-trip; it’s a plain server-side redirect.

The handshake

The JWT rides in the URL fragment (#…), never a query param, so the token stays out of server logs — Papervine reads it client-side.

Why a redirect works

A top-level browser redirect doesn’t carry the SPA’s Authorization header, but it does carry cookies, and the API authenticates from those:
SessionCookieAuthenticated on a redirect?
Legacy / tokenpixwel_api_credentialsyes — read by the Http auth adapter
Clerk__sessionyes — Session::docs() verifies it with the Clerk key when there’s no Authorization header
If the visitor has no valid session cookie, the endpoint redirects to the platform (pixwel_host) so they can sign in.

The pieces

ComponentPathRole
Minterapi/controllers/Session.phpdocs()GET /session/docs?redirect=… — authenticates from cookie, signs the JWT, and 302-redirects to the Papervine callback
No new API route or frontend page is needed — the catch-all /{:controller}/{:action} dispatches /session/docs to Session::docs.

The token

Signed EdDSA (Ed25519) with firebase/php-jwt. Claims:
ClaimValue
hostthe docs domain (docs.pixwel.com); must match or Papervine rejects it
expnow + 5s — the handshake window only (Papervine requires ≤ 10s)
expiresAtnow + 8h — the docs session length
groups["admin"] or ["user"], from $user->is(GroupsModel::ADMIN)
emailthe user’s email, for personalization
The redirect path is validated (must be site-relative) to prevent an open redirect.

Configuration

Point Papervine’s JWT login URL at the minter, and set two environment variables (both issued from the Papervine dashboard):
SettingValue
Papervine login URLhttps://platform.pixwel.com/api/session/docs
papervine_jwt_private_keybase64 Ed25519 private key (also accepts a PKCS#8 PEM)
papervine_docs_hostthe docs domain, e.g. docs.pixwel.com
If the key or host is unset, the endpoint returns 503 docs_auth_unconfigured.

Role-based pages

The groups claim drives per-page visibility. A page restricted to a group uses frontmatter:
---
title: "Slurpee3"
groups: ["admin"]
---
It’s an allow-list — a user outside the listed groups gets a 404, so the page is fully hidden, not just unlinked. Pages with no groups are visible to anyone past the docs login. The entire Engineering tab is tagged groups: ["admin"].
Group gating only activates once authentication is enabled — until then the markers are inert. Conversely, once auth is live, a page with a groups requirement 404s for any user without a matching group.

Setup checklist

1

Enterprise plan

Papervine JWT auth requires an Enterprise plan.
2

Generate the keypair

In the Papervine dashboard, generate the EdDSA keypair and set the JWT login URL to https://platform.pixwel.com/api/session/docs. Store the private key as papervine_jwt_private_key.
3

Serve on a subdomain

Host the docs at docs.pixwel.com — auth isn’t supported on a path basepath like pixwel.com/docs.
4

Gate pages

Engineering pages already carry groups: ["admin"]; add the marker to any other page that should be admin-only.