Skip to main content

Provider Access Token Acquisition Guide

Audience: External provider teams integrating with Kontrolle+ Provider API.

Scope: This guide explains only how to obtain an access token for provider API calls. It does not cover payload schemas or business submission rules.

1. What You Need

Before requesting a token, ensure you have these values from the Kontrolle+ team:

  • Authority base URL
  • OAuth token endpoint
  • Client ID
  • Client secret (or certificate-based client assertion flow, if agreed)
  • Scope in the format: /.default
  • Expected audience value (aud) used by the API runtime

Important:

  • Token flow is machine-to-machine only: OAuth 2.0 client credentials.
  • No user login is involved.

2. Required Request Format

HTTP method:

  • POST

Content type:

  • application/x-www-form-urlencoded

Form fields:

  • client_id
  • client_secret
  • grant_type=client_credentials
  • scope=/.default

3. curl Example: Get Access Token

Replace placeholders with the values provided to your provider environment.

curl -sS -X POST "https:////oauth2/v2.0/token"
-H "Content-Type: application/x-www-form-urlencoded"
--data-urlencode "client_id="
--data-urlencode "client_secret="
--data-urlencode "grant_type=client_credentials"
--data-urlencode "scope=/.default"

Typical successful response includes:

  • token_type (Bearer)
  • expires_in (seconds)
  • access_token

4. curl Example: Extract Only the Token

If jq is available:

ACCESS_TOKEN=$(curl -sS -X POST "https:////oauth2/v2.0/token"
-H "Content-Type: application/x-www-form-urlencoded"
--data-urlencode "client_id="
--data-urlencode "client_secret="
--data-urlencode "grant_type=client_credentials"
--data-urlencode "scope=/.default" | jq -r '.access_token')

echo "$ACCESS_TOKEN"

5. Validate Token Claims Before First API Call

At minimum, validate the token contains:

  • aud: must match the audience expected by the API runtime
  • roles: must include ProviderApi.Access
  • exp: token is not expired

Quick local decode (header and payload only, no signature verification):

echo "$ACCESS_TOKEN" | awk -F '.' '{print $2}' | tr '_-' '/+' | base64 -d 2>/dev/null

6. Common Errors and Fixes

400 invalid_client:

  • Cause: wrong client_id/client_secret, disabled credential, expired secret.
  • Fix: verify credential pair and secret validity window.

400 invalid_scope:

  • Cause: incorrect scope value.
  • Fix: use exact value /.default.

401 when calling API with token:

  • Cause: token issuer/audience mismatch or expired token.
  • Fix: verify authority, emitted aud claim, and token lifetime.

403 when calling API with token:

  • Cause: missing ProviderApi.Access role or client not allow-listed.
  • Fix: ensure app role assignment is complete and allow-list includes your client identity when enabled.

7. Production Handling Recommendations

  • Cache token until shortly before expiry instead of requesting one per API call.
  • Rotate client secret/certificate before expiration.
  • Store credentials only in secure secret management systems.
  • Never log full access tokens.

8. Provider Integration Template

Use this block as your runbook input per environment:

Environment: <ENV_NAME> Authority: Token endpoint: <TOKEN_ENDPOINT> Client ID: <CLIENT_ID> Client secret delivery: <SECURE_CHANNEL_REFERENCE> Scope: <PROVIDER_API_APP_ID_URI>/.default Expected audience (aud): <API_AUDIENCE> Required role: ProviderApi.Access

References

  • documentation/v2/api/12_PROVIDER_API_AUTHORIZATION_PROCESS.md
  • documentation/v2/api/09_PROVIDER_AUTH_ONBOARDING_GUIDE.md
  • openapi/provider-controls.openapi.yaml