Authentication API (OAuth 2.0 & OpenID Connect)
The Guardhouse Authentication API provides OAuth 2.0 and OpenID Connect (OIDC) endpoints for user authentication, token management, and authorization.
Base URL
All authentication endpoints are available at:
https://your_tenant.guardhouse.cloud
Overview
The Authentication API supports the following flows:
- Authorization Code Flow with PKCE - For SPAs and native/mobile apps
- Client Credentials Flow - For machine-to-machine (M2M) authentication
- Refresh Token Flow - For obtaining new access tokens
The following flows are not available:
Authorization Code Flow- Use Authorization Code Flow with PKCE insteadImplicit Flow- Legacy flow (not available, use PKCE instead)Resource Owner Password Credentials- Not available for security reasons
OpenID Connect Discovery
The OpenID Connect discovery endpoint provides metadata about the Guardhouse authorization server.
.well-known/openid-configuration
Endpoint: GET /.well-known/openid-configuration
Example Request:
curl -X GET https://your_tenant.guardhouse.cloud/.well-known/openid-configuration
Response:
{
"issuer": "https://your_tenant.guardhouse.cloud",
"authorization_endpoint": "https://your_tenant.guardhouse.cloud/oauth/authorize",
"token_endpoint": "https://your_tenant.guardhouse.cloud/oauth/token",
"jwks_uri": "https://your_tenant.guardhouse.cloud/.well-known/jwks.json",
"userinfo_endpoint": "https://your_tenant.guardhouse.cloud/oauth/userinfo",
"revocation_endpoint": "https://your_tenant.guardhouse.cloud/oauth/revoke",
"introspection_endpoint": "https://your_tenant.guardhouse.cloud/oauth/introspect",
"end_session_endpoint": "https://your_tenant.guardhouse.cloud/oauth/logout",
"registration_endpoint": "https://your_tenant.guardhouse.cloud/oauth/register",
"response_types_supported": [
"code"
],
"response_modes_supported": [
"query",
"fragment",
"form_post"
],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"client_credentials"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"profile",
"email",
"offline_access"
],
"claims_supported": [
"sub",
"name",
"given_name",
"family_name",
"email",
"picture"
]
}
Authorization Endpoint
The authorization endpoint is used to initiate the authentication flow and obtain an authorization code.
/oauth/authorize
Endpoint: GET /oauth/authorize
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
response_type | string | Yes | Value must be code |
client_id | string | Yes | Your application's Client ID |
redirect_uri | string | Yes | Registered callback URL |
scope | string | Yes | Space-separated list of scopes (e.g., openid profile email offline_access) |
state | string | Yes | Random string to prevent CSRF attacks |
response_mode | string | No | Response mode: query, fragment, or form_post |
nonce | string | No | Random string for ID token replay protection |
prompt | string | No | login or none |
login_hint | string | No | Hint for which account to log in (email) |
code_challenge | string | No | PKCE code challenge (required for PKCE) |
code_challenge_method | string | No | PKCE code challenge method: S256 or plain |
audience | string | No | Target audience for the access token |
organization | string | No | Organization ID for multi-tenant apps |
Example Request:
curl -X GET "https://your_tenant.guardhouse.cloud/oauth/authorize? \
response_type=code \
&client_id=YOUR_CLIENT_ID \
&redirect_uri=https://app.example.com/callback \
&scope=openid%20profile%20email%20offline_access \
&state=xyzABC123 \
&nonce=abc123XYZ"
Response:
On success, redirects to redirect_uri with authorization code:
https://app.example.com/callback?code=AUTH_CODE&state=xyzABC123
Token Endpoint
The token endpoint is used to exchange authorization codes or credentials for access tokens.
/oauth/token
Endpoint: POST /oauth/token
Content-Type: application/x-www-form-urlencoded
1. Authorization Code Flow with PKCE
Request Body:
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=https://app.example.com/callback
&client_id=YOUR_CLIENT_ID
&code_verifier=CODE_VERIFIER
Example:
curl -X POST https://your_tenant.guardhouse.cloud/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=https://app.example.com/callback" \
-d "client_id=YOUR_CLIENT_ID" \
-d "code_verifier=CODE_VERIFIER"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "v1.XXXX.YYYY.ZZZZ",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile email offline_access"
}
2. Client Credentials Flow (M2M)
Request Body:
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&audience=https://your_tenant.guardhouse.cloud/api/v2
Example:
curl -X POST https://your_tenant.guardhouse.cloud/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "audience=https://your_tenant.guardhouse.cloud/api/v2"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read:users write:users delete:users"
}
3. Refresh Token Flow
Request Body:
grant_type=refresh_token
&refresh_token=REFRESH_TOKEN
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Example:
curl -X POST https://your_tenant.guardhouse.cloud/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=REFRESH_TOKEN" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "v1.NEW_REFRESH_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile email offline_access"
}
4. Authorization Code Flow with PKCE (Client Secret Optional)
For confidential clients, you may optionally include client_secret:
Request Body:
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=https://app.example.com/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&code_verifier=CODE_VERIFIER
Token Introspection
The introspection endpoint allows you to validate tokens and retrieve their metadata.
/oauth/introspect
Endpoint: POST /oauth/introspect
Content-Type: application/x-www-form-urlencoded
Request Body:
token=ACCESS_TOKEN
&token_type_hint=access_token
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Example:
curl -X POST https://your_tenant.guardhouse.cloud/oauth/introspect \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=ACCESS_TOKEN" \
-d "token_type_hint=access_token" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
Response (Active Token):
{
"active": true,
"client_id": "YOUR_CLIENT_ID",
"sub": "usr_123456789",
"aud": [
"https://your_tenant.guardhouse.cloud/api/v2"
],
"iss": "https://your_tenant.guardhouse.cloud",
"exp": 1640995200,
"iat": 1640991600,
"scope": "openid profile email read:users write:users",
"token_type": "Bearer"
}
Response (Inactive Token):
{
"active": false
}
Token Revocation
The revocation endpoint allows you to revoke tokens.
/oauth/revoke
Endpoint: POST /oauth/revoke
Content-Type: application/x-www-form-urlencoded
Request Body:
token=TOKEN_TO_REVOKE
&token_type_hint=refresh_token
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Example:
curl -X POST https://your_tenant.guardhouse.cloud/oauth/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=REFRESH_TOKEN" \
-d "token_type_hint=refresh_token" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
Response:
200 OK
JWKS Endpoint
The JSON Web Key Set (JWKS) endpoint provides the public keys used to verify JWT signatures.
/.well-known/jwks.json
Endpoint: GET /.well-known/jwks.json
Example Request:
curl -X GET https://your_tenant.guardhouse.cloud/.well-known/jwks.json
Response:
{
"keys": [
{
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR...",
"e": "AQAB",
"kid": "RkK7b4c9i8Q9j8k4m4k8m4k8m4k8m4k8m4k8m4k8",
"x5t": "k7b4c9i8Q9j8k4m4k8m4k8m4k8m4k8m4k8m4"
}
]
}
Logout Endpoint
The logout endpoint ends the user's session.
/oauth/logout
Endpoint: GET /oauth/logout
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
post_logout_redirect_uri | string | No | URL to redirect after logout |
id_token_hint | string | No | ID token to identify the user session |
state | string | No | Random string to prevent CSRF attacks |
Example Request:
curl -X GET "https://your_tenant.guardhouse.cloud/oauth/logout? \
post_logout_redirect_uri=https://app.example.com/logout& \
id_token_hint=ID_TOKEN"
Response:
Redirects to post_logout_redirect_uri after successful logout.
User Info Endpoint
The userinfo endpoint returns claims about the authenticated user.
/oauth/userinfo
Endpoint: GET /oauth/userinfo
Authorization: Bearer ACCESS_TOKEN
Example Request:
curl -X GET https://your_tenant.guardhouse.cloud/oauth/userinfo \
-H "Authorization: Bearer ACCESS_TOKEN"
Response:
{
"sub": "usr_123456789",
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"email": "john.doe@example.com",
"email_verified": true,
"picture": "https://cdn.example.com/avatars/john.jpg",
"updated_at": 1640995200
}
Scopes
Guardhouse supports the following OAuth 2.0 scopes:
| Scope | Description |
|---|---|
openid | Required for OpenID Connect authentication |
profile | Access to user's profile information |
email | Access to user's email address |
offline_access | Enables refresh tokens for long-term access |
read:users | Read user information (management API) |
write:users | Create and update users (management API) |
delete:users | Delete users (management API) |
read:clients | Read application clients (management API) |
write:clients | Create and update clients (management API) |
Token Response Fields
| Field | Type | Description |
|---|---|---|
access_token | string | Bearer token to access protected resources |
id_token | string | JWT containing user identity information |
refresh_token | string | Token to obtain new access tokens |
token_type | string | Always Bearer |
expires_in | integer | Access token lifetime in seconds |
scope | string | Granted scopes |
PKCE (Proof Key for Code Exchange)
PKCE is an extension to the Authorization Code flow that prevents authorization code interception attacks. It's recommended for SPAs and native/mobile applications.
Generate Code Verifier
// Generate a random code verifier
function generateCodeVerifier() {
const array = new Uint32Array(32);
window.crypto.getRandomValues(array);
const verifier = Array.from(array, (dec) => dec.toString(16).padStart(2, '0')).join('');
return verifier;
}
const codeVerifier = generateCodeVerifier();
Generate Code Challenge
// Generate SHA-256 hash and base64 URL encode
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await window.crypto.subtle.digest('SHA-256', data);
const challenge = btoa(String.fromCharCode(...new Uint8Array(hash)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
return challenge;
}
const codeChallenge = await generateCodeChallenge(codeVerifier);
Use in Authorization Request
GET /oauth/authorize? \
response_type=code \
&client_id=YOUR_CLIENT_ID \
&redirect_uri=https://app.example.com/callback \
&scope=openid%20profile%20email \
&state=xyzABC123 \
&code_challenge=CODE_CHALLENGE \
&code_challenge_method=S256
Exchange Code with Verifier
POST /oauth/token
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=https://app.example.com/callback
&client_id=YOUR_CLIENT_ID
&code_verifier=CODE_VERIFIER
Error Responses
All endpoints may return OAuth 2.0 errors:
{
"error": "invalid_request",
"error_description": "The request is missing a required parameter"
}
Error Codes
| Error Code | HTTP Status | Description |
|---|---|---|
invalid_request | 400 | Request is missing required parameters |
unauthorized_client | 401 | Client authentication failed |
access_denied | 403 | User denied authorization |
unsupported_response_type | 400 | Response type not supported |
invalid_scope | 400 | Scope is invalid or unauthorized |
server_error | 500 | Authorization server error |
temporarily_unavailable | 503 | Service temporarily unavailable |
invalid_client | 401 | Client authentication failed |
invalid_grant | 400 | Authorization code or refresh token invalid |
unsupported_grant_type | 400 | Grant type not supported |
Best Practices
- Always use HTTPS - Never send credentials over unencrypted connections
- Validate State - Always verify the
stateparameter after redirects - Use PKCE - Always use PKCE for SPAs and native/mobile apps
- Secure Tokens - Store tokens securely (httpOnly cookies, secure storage)
- Implement Refresh - Use refresh tokens to maintain sessions
- Validate JWTs - Always validate JWT signatures and claims
- Handle Errors - Implement proper error handling for all endpoints
- Rate Limiting - Respect rate limits and implement backoff
Testing
Use tools like Postman, curl, or your browser's developer tools to test the authentication endpoints.
Next Steps
- See User API for user management
- Learn about Token Validation
- Explore SDKs for easier integration