API docs
Base URL https://auth.gallimoresoftware.com. Everything below is standard
OpenID Connect with PKCE - any compliant client library works. Responses are JSON unless noted.
How sign-in works
Gallimore Auth is a public OIDC client setup: no client secrets, PKCE (S256) is required on every flow.
- Your app redirects the user to GET /authorize with its client_id, an exact-match redirect_uri, and a PKCE code_challenge.
- We validate the request and redirect to Microsoft Entra for sign-in.
- Entra returns to us; we check the tenant, the app allowlist, and the required roles, then redirect back to your redirect_uri with a single-use authorization code (60 second lifetime).
- Your backend exchanges the code at POST /token with the PKCE code_verifier and receives an ID token plus an access token (both expire in 15 minutes).
- Call GET /userinfo with the access token to fetch the signed-in profile.
Discovery document
Standard OpenID Provider Metadata. Point any OIDC client library at this URL and it configures itself.
Example response
{
"issuer": "https://auth.gallimoresoftware.com",
"authorization_endpoint": "https://auth.gallimoresoftware.com/authorize",
"token_endpoint": "https://auth.gallimoresoftware.com/token",
"userinfo_endpoint": "https://auth.gallimoresoftware.com/userinfo",
"jwks_uri": "https://auth.gallimoresoftware.com/jwks.json",
"end_session_endpoint": "https://auth.gallimoresoftware.com/logout",
"revocation_endpoint": "https://auth.gallimoresoftware.com/revoke",
"response_types_supported": ["code"],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": ["none"],
"identity_providers_supported": ["microsoft"]
}
JSON Web Key Set
The RS256 public signing key. Use it to verify ID token and access token signatures locally.
Example response
{
"keys": [
{ "kty": "RSA", "use": "sig", "alg": "RS256", "kid": "…", "n": "…", "e": "AQAB" }
]
}
- The private half is never published. Keys are rotated by the service; always match on kid.
Start sign-in
Validates the request, then redirects (303) to Microsoft Entra. On validation failure the user is sent back to your redirect_uri with OAuth error parameters instead.
| Parameter | In | Required | Description |
|---|---|---|---|
| client_id | query | yes | Your registered application id. |
| redirect_uri | query | yes | Must exactly match a URI registered for the client. No wildcards, no prefixes. |
| response_type | query | yes | Must be code. |
| scope | query | yes | Space-separated scopes. Must include openid. profile and email are also supported. |
| state | query | yes | Opaque value returned to you unchanged. Use it for CSRF protection. |
| nonce | query | no | Returned inside the ID token so you can bind it to the session. |
| code_challenge | query | yes | PKCE challenge: base64url(sha256(code_verifier)). |
| code_challenge_method | query | yes | Must be S256. |
Example request
GET /authorize?client_id=your-app&redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback&response_type=code&scope=openid%20profile%20email&state=xyz&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256
- Unknown client_id or a non-matching redirect_uri returns an error page (400) instead of redirecting anywhere.
- Other validation errors redirect to your redirect_uri with error=invalid_request and an error_description.
- Success is a 303 redirect to login.microsoftonline.com. The upstream state is ours; your state comes back with the code.
Microsoft return
Where Microsoft Entra sends the browser after sign-in. You never call it yourself - it finishes what /authorize started.
- We exchange the Entra code, validate the ID token, then enforce the tenant boundary, the app email allowlist, and the required Entra roles.
- A failed or expired sign-in (attempts expire after 10 minutes) returns an error page here instead of your redirect URI.
- On success we redirect to your redirect_uri with code and state, exactly as documented under Start sign-in.
Exchange the code
Redeems a single-use authorization code for tokens. Accepts application/x-www-form-urlencoded or JSON. No client secret: authentication is the PKCE verifier.
| Parameter | In | Required | Description |
|---|---|---|---|
| grant_type | body | yes | Must be authorization_code. |
| code | body | yes | The code from the authorize redirect. Single use, expires after 60 seconds. |
| client_id | body | yes | Must match the client the code was issued to. |
| redirect_uri | body | yes | Must match the redirect_uri from the authorize request. |
| code_verifier | body | yes | The original PKCE verifier, 43 to 128 characters. |
Example request
POST /token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SPLIT…&client_id=your-app&redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Example response
{
"token_type": "Bearer",
"expires_in": 900,
"id_token": "eyJhbGciOi…",
"access_token": "eyJhbGciOi…",
"scope": "openid profile email"
}
- The access token is a JWT too: verify its RS256 signature against /jwks.json and call /userinfo with it.
- Reusing a code, or presenting it after the session was revoked, returns invalid_grant.
User profile
Returns the signed-in profile for a valid access token.
| Parameter | In | Required | Description |
|---|---|---|---|
| Authorization | header | yes | Bearer <access_token>. |
Example request
GET /userinfo Authorization: Bearer eyJhbGciOi…
Example response
{
"sub": "a-stable-user-id",
"email": "person@example.com",
"email_verified": true,
"name": "Person Name",
"provider": "microsoft",
"tenant_id": "…",
"roles": ["app-role"],
"session_id": "…"
}
- Tokens are rejected (401 invalid_token) when the signature, issuer, expiry, or session check fails.
Revoke a session
Ends a session immediately. Tokens already issued for it stop validating at /userinfo and /token.
| Parameter | In | Required | Description |
|---|---|---|---|
| session_id | body | yes | The session_id from the ID token or userinfo. |
Example request
POST /revoke
Content-Type: application/json
{ "session_id": "…" }
Example response
{ "revoked": true }
Sign out
Ends the session and optionally returns the user to your app.
| Parameter | In | Required | Description |
|---|---|---|---|
| session_id | query | no | Revoked when present. |
| client_id | query | no | Used to validate the post-logout redirect. |
| post_logout_redirect_uri | query | no | Must exactly match a URI registered for the client, otherwise a signed-out page is shown. |
Example request
GET /logout?session_id=…&client_id=your-app&post_logout_redirect_uri=https%3A%2F%2Fapp.example.com%2Fsigned-out
Service health
Liveness and provider state. Contains no secrets.
Example response
{
"ok": true,
"issuer": "https://auth.gallimoresoftware.com",
"clientCount": 9,
"signingKeyId": "…",
"providers": [
{ "id": "microsoft", "enabled": true },
{ "id": "google", "enabled": false }
]
}
Registering your app
There is no self-service registration endpoint. Apps are registered in server configuration.
- Each client declares an id, an application class, one or more exact-match redirect URIs (https only), and optional post-logout redirect URIs.
- Application classes set the authorization boundary: internal staff tools require the Gallimore tenant plus an Entra app role; other classes add their own tenant or allowlist rules.
- A client may also declare an email allowlist and required Entra roles. Sign-in succeeds only when all of them pass.
- To onboard an app, ask the platform team to register it with its redirect URIs.