Token Endpoint Hands-on
The Direct Access Grant (password grant)
Section titled “The Direct Access Grant (password grant)”The Direct Access Grant — also called the password grant — lets you exchange a username and password directly for tokens at the token endpoint, bypassing the browser redirect flow entirely.
This makes it convenient for:
- Testing your Keycloak configuration from a terminal
- CLI tools and shell scripts that need a token to call an API
- Development workflows where you want to quickly inspect a token
It should not be used in real user-facing applications. When you hand a user’s password directly to your app, the app sees the credentials — which defeats the purpose of delegating authentication to Keycloak. For browser and mobile apps, always use Authorization Code + PKCE.
To use this grant, the client must have Direct access grants enabled on the Capability config tab.
Getting a token
Section titled “Getting a token”Replace the placeholders with your values before running.
curl -X POST https://${KC_URL}/realms/${REALM}/protocol/openid-connect/token \
-d "grant_type=password" \
-d "client_id=${CLIENT_ID}" \
-d "username=${USERNAME}" \
-d "password=${PASSWORD}"For a confidential client, also add -d "client_secret=<your-secret>" to the command.
The token response
Section titled “The token response”A successful request returns a JSON object like this:
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "expires_in": 300, "refresh_expires_in": 1800, "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "session_state": "abc123", "scope": "openid profile email"}Key fields:
access_token— a JWT you send to your API asAuthorization: Bearer <token>.expires_in— the access token lifetime in seconds (300 = 5 minutes by default).refresh_token— use this to get a new access token without re-authenticating.id_token— a JWT that proves who the user is (OIDC only).token_type— alwaysBearerfor Keycloak.
Decoding the JWT
Section titled “Decoding the JWT”The access token is a Base64url-encoded JWT. You can decode the payload to inspect its claims.
echo ${ACCESS_TOKEN} | cut -d. -f2 | base64 -d | jq .On some systems use base64 --decode instead of base64 -d. Set the ACCESS_TOKEN environment variable to your token value first, or replace it inline.