Endpoints
Paths are relative to the issuer. On the hosted gateway that is
https://auth.resoauth.cloud; on your own deployment it is whatever
SAG_ISSUER says, including any base path.
| Path | Method | What it is |
|---|---|---|
/.well-known/openid-configuration | GET | OpenID Connect discovery. Start here |
/.well-known/oauth-authorization-server | GET | The same instance described as an OAuth authorisation server (RFC 8414) |
/.well-known/oauth-protected-resource | GET | Describes /userinfo as a protected resource (RFC 9728) |
/.well-known/jwks.json | GET | The public keys that verify an id_token |
/jwks.json | GET | The same keys at the pre-RFC 8414 location, for older libraries |
/authorize | GET, POST | Where you send the person to sign in |
/callback | GET | Where an upstream provider returns them. Not for your application |
/token | POST | Exchange an authorisation code for an id_token |
/userinfo | GET, POST | Claims about the signed-in person, using the access token |
/logout | GET, POST | End the session (end_session_endpoint) |
/healthz | GET | Whether this instance can actually sign somebody in |
/alive | GET | Whether a process is listening at all |
The /authorize/* sub-paths (/authorize/email, /authorize/otp,
/authorize/resend, and the rest) belong to the sign-in screens themselves.
They are form targets, not an API, and their shape may change between
releases. Your application only ever needs /authorize.
/ is deliberately not a landing page. It returns 404 with "This is a
sign-in service. Start from the application you want to use."
Which of these are stable
/authorize, /token, /userinfo, /logout, the discovery documents, and
the JWKS are the interface. They follow OpenID Connect and RFC 8414, and a
change to them is a breaking change.
The /authorize/* form targets and /static/* are internal. They are the
sign-in screens talking to themselves, and they may change in any release.
Do not hard-code any of them. Read the discovery document, which is the point of having one.
The discovery document describes the instance
This is worth stating on its own, because it catches people out.
SAG advertises what the running instance can actually do, not what the
software supports. No profile scope when nothing could fill it. No federated
acr value without an upstream configured. No signing algorithm without a key
behind it.
So a claim, scope, or algorithm missing from discovery is missing because this deployment cannot provide it. Reading discovery at startup and configuring from it is not defensive programming here; it is the intended way to use it.
Extensions SAG publishes under its own namespace:
| Key | Meaning |
|---|---|
urn:sag:require_pkce | Always true. PKCE is not optional |
urn:sag:post_quantum_signing_supported | Whether a post-quantum key is published |
urn:sag:post_quantum_algs | Which post-quantum algorithms, if any |
urn:sag:client_registration | How this instance accepts relying parties |
urn:sag:protected_resources | Resources the access token is good for. /userinfo, and nothing else |
/alive versus /healthz
These answer different questions, and using the wrong one causes real incidents.
/alive returns 200 and the body ok. Nothing else. It is handled
before configuration is even parsed, so it answers 200 on an instance that
is misconfigured and cannot sign anybody in. Use it for a container liveness
probe, and for load-balancer target health.
/healthz returns JSON and answers whether this instance can actually
sign somebody in. It reports the running version, the issuer, the signing
setup, warnings, which upstream providers are configured and how many domains
each covers, whether email codes are on, how relying parties are described,
and the state of any peer JWKS federation.
Point failover checks at /healthz. Pointing them at /alive means traffic
keeps arriving at an instance that will fail every sign-in.
/healthz deliberately will not tell you whether a state store is configured,
name any upstream domain, or identify any relying party. Those would turn a
public endpoint into a description of who uses the service. Operators get that
from the start-up banner and the logs instead.
Reading both is covered in operations, and the multi-region routing case in multi-region.