Skip to main content

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 instead
  • Implicit 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:

ParameterTypeRequiredDescription
response_typestringYesValue must be code
client_idstringYesYour application's Client ID
redirect_uristringYesRegistered callback URL
scopestringYesSpace-separated list of scopes (e.g., openid profile email offline_access)
statestringYesRandom string to prevent CSRF attacks
response_modestringNoResponse mode: query, fragment, or form_post
noncestringNoRandom string for ID token replay protection
promptstringNologin or none
login_hintstringNoHint for which account to log in (email)
code_challengestringNoPKCE code challenge (required for PKCE)
code_challenge_methodstringNoPKCE code challenge method: S256 or plain
audiencestringNoTarget audience for the access token
organizationstringNoOrganization 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:

ParameterTypeRequiredDescription
post_logout_redirect_uristringNoURL to redirect after logout
id_token_hintstringNoID token to identify the user session
statestringNoRandom 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:

ScopeDescription
openidRequired for OpenID Connect authentication
profileAccess to user's profile information
emailAccess to user's email address
offline_accessEnables refresh tokens for long-term access
read:usersRead user information (management API)
write:usersCreate and update users (management API)
delete:usersDelete users (management API)
read:clientsRead application clients (management API)
write:clientsCreate and update clients (management API)

Token Response Fields

FieldTypeDescription
access_tokenstringBearer token to access protected resources
id_tokenstringJWT containing user identity information
refresh_tokenstringToken to obtain new access tokens
token_typestringAlways Bearer
expires_inintegerAccess token lifetime in seconds
scopestringGranted 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 CodeHTTP StatusDescription
invalid_request400Request is missing required parameters
unauthorized_client401Client authentication failed
access_denied403User denied authorization
unsupported_response_type400Response type not supported
invalid_scope400Scope is invalid or unauthorized
server_error500Authorization server error
temporarily_unavailable503Service temporarily unavailable
invalid_client401Client authentication failed
invalid_grant400Authorization code or refresh token invalid
unsupported_grant_type400Grant type not supported

Best Practices

  1. Always use HTTPS - Never send credentials over unencrypted connections
  2. Validate State - Always verify the state parameter after redirects
  3. Use PKCE - Always use PKCE for SPAs and native/mobile apps
  4. Secure Tokens - Store tokens securely (httpOnly cookies, secure storage)
  5. Implement Refresh - Use refresh tokens to maintain sessions
  6. Validate JWTs - Always validate JWT signatures and claims
  7. Handle Errors - Implement proper error handling for all endpoints
  8. 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