Well-Known Pages
AuthProxy serves built-in HTML pages for a range of conditions — provider selection, invitation errors, tenant errors, and generic HTTP errors. Every page can be overridden by mounting a directory of custom pages into the container.
Built-in pages
Section titled “Built-in pages”The following pages are included with AuthProxy and are served automatically when the corresponding condition is detected:
| File name | Condition | HTTP status |
|---|---|---|
404.html | The requested resource was not found. | 404 |
403.html | The identity resolver denied access. | 403 |
not-authorized.html | The caller is signed in but does not satisfy the claim requirements declared in Cratis:AuthProxy:Authorization. | 403 |
tenant-not-found.html | The resolved tenant does not exist in the platform (see Tenant verification). | 404 |
select-provider.html | A protected resource was requested and multiple identity providers are configured. The page reads the .cratis-providers cookie to render a sign-in button for each available provider. | 200 |
select-tenant.html | Tenant selection is enabled and the authenticated user has not selected a tenant yet. The page reads the .cratis-tenants cookie to render selectable tenants. | 200 |
invitation-expired.html | The JWT token on an invite link has passed its expiry time. Served in either phase — when the link is followed (Phase 1) and when the token is re-validated at the exchange (Phase 2). | 401 |
invitation-invalid.html | The JWT token on an invite link is malformed or has an invalid signature. Served in either phase — when the link is followed (Phase 1) and when the token is re-validated at the exchange (Phase 2). | 401 |
invitation-select-provider.html | A valid invite link was followed and multiple identity providers are configured. The page reads the .cratis-providers cookie to render a sign-in button for each available provider. | 200 |
invitation-subject-already-exists.html | The authenticated user’s subject is already associated with an existing account during invite exchange (Phase 2). | 409 |
invitation-email-mismatch.html | Gateway email binding is enabled (Invite.EmailClaim) and the account signed in with has a verified email that does not match the email the invitation was issued for (Phase 2). | 403 |
Overriding pages
Section titled “Overriding pages”Mount a directory into the container and point Cratis:AuthProxy:PagesPath at the mount path.
AuthProxy looks up each page by its conventional file name inside that directory.
Any page file that is present overrides the built-in default; missing files fall back to the built-in version.
{ "Cratis": { "AuthProxy": { "PagesPath": "/mnt/pages" } }}Equivalent environment variable:
Cratis__AuthProxy__PagesPath=/mnt/pagesContainer mount example (Docker Compose)
Section titled “Container mount example (Docker Compose)”services: authproxy: image: cratis/authproxy:latest volumes: - ./my-pages:/mnt/pages environment: Cratis__AuthProxy__PagesPath: /mnt/pagesPage assets
Section titled “Page assets”Pages can reference stylesheets, images, and other assets.
Place asset files in the same pages directory — they are served at the /_pages/ URL prefix.
<!-- inside your custom page --><link rel="stylesheet" href="/_pages/styles.css" /><img src="/_pages/logo.svg" alt="Logo" />Provider selection pages
Section titled “Provider selection pages”select-provider.html and invitation-select-provider.html both serve the same purpose —
letting the user choose an identity provider when multiple are configured — but they are
triggered by different flows:
| Page | Triggered by |
|---|---|
select-provider.html | Direct navigation to a protected resource when not yet authenticated. |
invitation-select-provider.html | Following a valid invite link. |
Both pages receive provider data via the .cratis-providers cookie and work identically
from a customization standpoint. See Provider Selection Pages
for the full cookie schema, JavaScript examples, and guidance on building a custom branded page.
Invitation error pages
Section titled “Invitation error pages”Invitation error pages use full descriptive names rather than numeric HTTP status codes because they represent application-level conditions, not generic HTTP errors.
invitation-expired.html
Section titled “invitation-expired.html”Served when an invite token has a valid signature but has passed its exp claim. AuthProxy validates
the token both when the /invite/<token> link is followed (Phase 1) and again at the post-login
exchange (Phase 2), so this page is served whenever an expired token is detected in either phase.
The user should request a fresh invitation.
invitation-invalid.html
Section titled “invitation-invalid.html”Served when an invite token is malformed, carries an invalid signature, or cannot be parsed at all. Because AuthProxy re-validates the token at the Phase-2 exchange — not only when the link is first followed — this page is also served if a tampered or forged token is presented at the exchange.
invitation-subject-already-exists.html
Section titled “invitation-subject-already-exists.html”Served during Phase 2 (post-login invite exchange) when the exchange endpoint returns HTTP 409 Conflict, indicating that the authenticated user’s subject is already associated with an existing account.
invitation-email-mismatch.html
Section titled “invitation-email-mismatch.html”Served during Phase 2 (post-login invite exchange) when gateway email binding is enabled — the
Invite.EmailClaim claim is configured — the invite token was issued for a specific email address, and
the account the user signed in with does not own that verified email. This binds an invitation to its
intended recipient so it cannot be redeemed with a different account. Email binding is off by default;
see Invitation to Organization for how to configure the email
claim.
Tenant not found
Section titled “Tenant not found”tenant-not-found.html is served when tenant verification is enabled and the platform reports
that the resolved tenant ID does not exist. See Tenant verification
for how to configure the verification endpoint.
Not authorized
Section titled “Not authorized”not-authorized.html is served when first-gate authorization is configured and an
authenticated caller does not satisfy a required claim — a GitHub organization they do not belong to, a
role they do not hold. It is distinct from 403.html, which answers the application refusing a caller it
does recognize; this one is the proxy refusing before the application is reached at all.
If you override it, keep a way to sign out. It is the only refusal whose remedy is to come back as
somebody else, and someone who signed in with the wrong account is otherwise stuck looking at a page that
will not change. The built-in page links to /.cratis/logout?redirect=/:
<a href="/cratis/logout/?redirect=/">Sign out</a>This is a good page to brand and to make specific — “ask #it-support for access to the planner” is far more useful to the person reading it than “not authorized”.