Provider Access Token Acquisition (INT Test)
Audience: External provider teams testing token acquisition against the INT environment.
Scope: Token retrieval only (OAuth 2.0 client credentials).
INT Test Credentials and Endpoints
The following values are enabled for integration testing only:
export PROVIDER_TENANT_ID="c160f35c-f7f5-433e-a67d-8689de4f0193"
export PROVIDER_CLIENT_ID="9f441a84-9140-4690-9275-21e2cd4ac827"
export PROVIDER_CLIENT_SECRET="lJQ8QVAycaHnoZiMpqu5BRQhmY5HelDcemvbB-"
export PROVIDER_TOKEN_SCOPE="api://kontrolleplus-provider-api-dev/.default"
export PROVIDER_TOKEN_ENDPOINT="https://c160f35c-f7f5-433e-a67d-8689de4f0193.ciamlogin.com/c160f35c-f7f5-433e-a67d-8689de4f0193/oauth2/v2.0/token"
1. Export Variables (copy/paste)
Run this in your terminal before requesting the token:
export PROVIDER_TENANT_ID="c160f35c-f7f5-433e-a67d-8689de4f0193"
export PROVIDER_CLIENT_ID="9f441a84-9140-4690-9275-21e2cd4ac827"
export PROVIDER_CLIENT_SECRET="lJQ8Q~VAy~caHnoZiMpqu5BRQhmY5HelDcemvbB-"
export PROVIDER_TOKEN_SCOPE="api://kontrolleplus-provider-api-dev/.default"
export PROVIDER_TOKEN_ENDPOINT="https://c160f35c-f7f5-433e-a67d-8689de4f0193.ciamlogin.com/c160f35c-f7f5-433e-a67d-8689de4f0193/oauth2/v2.0/token"
2. Request Access Token (curl)
curl -sS -X POST "$PROVIDER_TOKEN_ENDPOINT" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=$PROVIDER_CLIENT_ID" \
--data-urlencode "client_secret=$PROVIDER_CLIENT_SECRET" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "scope=$PROVIDER_TOKEN_SCOPE"
Expected response fields:
- token_type = Bearer
- expires_in
- access_token
3. Request and Store Token in Variable
ACCESS_TOKEN=$(curl -sS -X POST "$PROVIDER_TOKEN_ENDPOINT" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=$PROVIDER_CLIENT_ID" \
--data-urlencode "client_secret=$PROVIDER_CLIENT_SECRET" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "scope=$PROVIDER_TOKEN_SCOPE" | jq -r '.access_token')
echo "$ACCESS_TOKEN"
4. Quick Decode of Token Payload
This decodes the JWT payload for quick visual checks (no signature verification):
echo "$ACCESS_TOKEN" | awk -F '.' '{print $2}' | tr '_-' '/+' | base64 -d 2>/dev/null
Check at minimum:
- aud is the expected API audience for INT runtime
- roles includes ProviderApi.Access
- exp is in the future
5. Optional: Use the Token Against Provider API
curl -X POST "https://kontrolleplus-dev-data.orangeglacier-1536cc06.switzerlandnorth.azurecontainerapps.io/api/provider/v1/controls" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d @provider-payload.json
6. Troubleshooting
400 invalid_client:
- Verify client_id and client_secret.
- Confirm secret is active and not expired.
400 invalid_scope:
- Scope must be exactly api://kontrolleplus-provider-api-dev/.default
401 from API:
- Token issuer or audience mismatch, or token expired.
403 from API:
- Token missing ProviderApi.Access role, or client ID not allow-listed (if allow-list is enabled).
Security Note
These credentials are for testing. Do not reuse in production. Rotate the test secret immediately if this file is ever shared outside authorized teams.