Authenticating to the AI Workbench API with Keycloak#
The AMD AI Workbench management API is protected by Keycloak using standard OAuth2/OpenID Connect (OIDC). External developers who want to call the management API (to create projects, deploy workloads, manage secrets, and related resources) must obtain a Keycloak-issued bearer token and present it on every request.
This page shows you how to get a token and call the API as an external developer.
When to Use Keycloak vs API Keys#
The AI Workbench supports two distinct authentication mechanisms, and they are not interchangeable:
API Keys — use for inference endpoints on deployed models. API keys are scoped to a project and (optionally) to specific deployments. See API Keys for Programmatic Access.
Keycloak/OAuth2 bearer tokens — use for the management API: projects, workloads, workspaces, secrets, datasets, models, AIMs, charts, overlays, and related resources. These endpoints require a user identity issued by Keycloak.
If you are integrating an application that calls deployed models, you want API keys. If you are automating Workbench lifecycle operations (creating projects, deploying or tearing down workloads, managing secrets), you want Keycloak.
Note
Some endpoints are accessible with either credential type, but the management surface is Keycloak-only. When in doubt, start with Keycloak. Your platform administrator can confirm which mechanism your use case requires.
What You Need from Your Platform Administrator#
Keycloak deployment details are environment-specific. Before you can authenticate, ask your platform administrator for:
Keycloak base URL — for example,
https://kc.<your-domain>Realm name — typically
airmOAuth2 client ID — the public client your application or script will identify as (deployment-specific)
Whether the client requires a client secret — confidential clients require one; public clients do not
Your user credentials, or details of the SSO provider (Google, Entra ID, Okta, etc.) that backs your Keycloak account
The AI Workbench API base URL — for example,
https://workbench.<your-domain>
Note
The client ID, realm, and Keycloak base URL vary per deployment. Do not assume the values shown in examples on this page will work as-is — obtain them from your administrator.
Token Endpoint#
Keycloak exposes a standard OIDC token endpoint at:
https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token
For most AI Workbench deployments the realm is airm, so the endpoint looks like:
https://<keycloak-host>/realms/airm/protocol/openid-connect/token
The host varies per deployment.
Supported Grant Types#
Keycloak supports several OAuth2 grant types. The two most relevant for AI Workbench API access are:
Authorization Code with PKCE — the recommended flow for any interactive application that hosts a real user (web apps, CLIs that launch a browser, and the Swagger UI). This flow avoids exposing user credentials to the application.
Resource Owner Password Credentials (a.k.a. the password grant) — convenient for scripts,
curlone-liners, and CI jobs that already hold credentials. It is easy to use, but it should not be used in production user-facing applications because the application must handle the user’s password directly.
Which grants are enabled depends on how your administrator has configured the client.
Quick Start: Get a Token with curl (Password Grant)#
The fastest way to try the API is the password grant. Replace the placeholder values with the ones from your administrator:
curl -X POST "https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=<your-client-id>" \
-d "username=<your-username>" \
-d "password=<your-password>" \
-d "scope=openid"
A successful response looks like:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR...",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR...",
"token_type": "Bearer",
"scope": "openid profile email"
}
Actual values, scopes, and lifetimes vary by deployment.
To capture the access token directly into a shell variable for further requests:
ACCESS_TOKEN=$(curl -s -X POST \
"https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=<your-client-id>" \
-d "username=<your-username>" \
-d "password=<your-password>" \
-d "scope=openid" \
| jq -r .access_token)
Warning
The password grant requires your application to handle the user’s password in plaintext. Do not embed user passwords in shared scripts or commit them to version control. Avoid passing passwords on the command line, where they can leak into shell history.
Calling the API#
Present the access token in the Authorization header as a bearer token on every API request:
curl -X GET "https://<workbench-host>/v1/projects" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json"
Any AI Workbench management endpoint accepts the same header.
Python Example#
The following example uses requests to fetch a token and then call the projects endpoint:
import requests
KEYCLOAK_BASE_URL = "https://<keycloak-host>"
REALM = "<realm>"
CLIENT_ID = "<your-client-id>"
USERNAME = "<your-username>"
PASSWORD = "<your-password>"
WORKBENCH_BASE_URL = "https://<workbench-host>"
token_url = f"{KEYCLOAK_BASE_URL}/realms/{REALM}/protocol/openid-connect/token"
token_response = requests.post(
token_url,
data={
"grant_type": "password",
"client_id": CLIENT_ID,
"username": USERNAME,
"password": PASSWORD,
"scope": "openid",
},
)
token_response.raise_for_status()
access_token = token_response.json()["access_token"]
api_response = requests.get(
f"{WORKBENCH_BASE_URL}/v1/projects",
headers={"Authorization": f"Bearer {access_token}"},
)
api_response.raise_for_status()
print(api_response.json())
If the client is confidential, include "client_secret": CLIENT_SECRET in the data dictionary alongside client_id.
Token Lifetime and Refresh#
Access tokens are short-lived (often a few minutes). The token response includes a longer-lived refresh_token, which you can exchange for a new access token at the same token endpoint. The refresh request requires grant_type=refresh_token, the refresh token value, and your client_id (plus client_secret for confidential clients). See Session Lifetime for detailed refresh and token lifetime guidance.
Troubleshooting#
400 invalid_grant
The username or password is wrong, the user account is disabled, or the password grant is not enabled for this client. Verify your credentials and confirm with your administrator that the password grant is allowed.
400 invalid_client
The client ID is wrong, or the client is configured as confidential and you did not send a client_secret. Confirm the client ID and whether a secret is required.
400 unauthorized_client
The requested grant type (for example, password) is not enabled for this client. Contact your administrator to either enable the grant on the client or to provide a different client ID that supports it.
401 Unauthorized from the AI Workbench API
The access token is missing, malformed, or expired. Refresh the token and ensure the Authorization: Bearer <token> header is present.
Token validation errors related to time Ensure the calling machine’s clock is synchronized (for example, via NTP). Keycloak rejects tokens whose validity windows do not overlap the current time.