API reference

Integrate through standard OAuth2 and OpenID Connect endpoints.

Configure clients from the tenant discovery document. The issuer host is part of the security boundary: clients, authorizations, signing keys, consent, and passkeys are selected for that issuer.

Start with discovery

Replace the host with the tenant issuer selected for the application.

https://free.openissuer.com/issuer/.well-known/openid-configuration

Issuer endpoints

Public Gateway API paths

The public base URL is https://TENANT_HOST/issuer. The gateway strips /issuer before forwarding requests to the authorization server.

EndpointPathPurpose
Discovery/.well-known/openid-configurationIssuer metadata and supported protocol capabilities.
Authorize/oauth2/authorizeStarts authorization-code login and consent.
Token/oauth2/tokenExchanges codes, refresh tokens, or client credentials.
JWK set/oauth2/jwksPublic signing keys used to validate JWTs.
UserInfo/userinfoReturns claims authorized for the current OpenID Connect user.
Logout/connect/logoutStarts OpenID Connect relying-party initiated logout.

Client registration

Grant types, authentication, and scopes

User applications

authorization_code with S256 PKCE and optional refresh_token.

Service applications

client_credentials with a client authentication method assigned during registration.

Common scopes

openid profile email plus application scopes such as message.read.

Discovery reports server capabilities. A client can use only the grants, authentication methods, redirect URIs, and scopes stored in its own registration.

  1. Register the client under the same tenant issuer host used by the application.
  2. Match redirect URIs exactly, including scheme, host, port, base path, and provider callback id.
  3. Use authorization code with S256 PKCE for browser and server-rendered user sign-in.
  4. Use client credentials only for service clients that were registered for that grant.
  5. Request only scopes assigned to the registered client.
  6. Keep client secrets in a secret manager or Kubernetes Secret, never in source control.

Authorization code

Start browser authorization

GET https://free.openissuer.com/issuer/oauth2/authorize
  ?response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fapi%2Fauth%2Fcallback%2Fmyauth
  &scope=openid%20profile
  &state=RANDOM_STATE
  &nonce=RANDOM_NONCE
  &code_challenge=BASE64URL_SHA256_VERIFIER
  &code_challenge_method=S256

Generate and validate state, nonce, and the PKCE verifier with a maintained OAuth/OIDC client library rather than constructing the flow manually.

Token exchange

Exchange the authorization code

curl -X POST https://free.openissuer.com/issuer/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "CLIENT_ID:CLIENT_SECRET" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://app.example.com/api/auth/callback/myauth" \
  -d "code_verifier=PKCE_VERIFIER"

Confidential clients commonly use client_secret_basic. Public clients omit the secret and must be registered with no client authentication method and required PKCE.

Claims

Tenant-aware token data

ID token

{
  "iss": "https://free.openissuer.com/issuer",
  "sub": "user@example.com",
  "aud": "CLIENT_ID",
  "tenant_id": "free.openissuer.com",
  "name": "Example User",
  "email": "user@example.com",
  "picture": ""
}

Access token

{
  "iss": "https://free.openissuer.com/issuer",
  "sub": "user@example.com",
  "scope": ["openid", "profile"],
  "tenant_id": "free.openissuer.com",
  "userId": "USER_UUID",
  "userRole": ["ROLE_NAME"],
  "authFactors": ["FACTOR_PASSWORD"]
}

Claims depend on principal type, granted scopes, roles, and completed authentication factors. Optional claims may be absent.

Troubleshooting

Common integration failures

invalid_client
Client ID, secret, authentication method, or tenant issuer does not match the registration.
invalid_grant
The code is expired or reused, redirect URI changed, or the PKCE verifier is incorrect.
invalid_scope
The request contains a scope not assigned to the client.
Redirect URI rejected
The submitted URI does not exactly match a registered redirect URI.
Issuer repository not found
The request host is missing from tenant configuration or forwarded host handling is incorrect.