Tokens and Claims
Obtaining a Token
The Kubauth companion CLI application kc provides an embedded OIDC client. Beyond testing the installation, its primary purpose is to fetch access tokens or ID tokens for use in any application.
Launch the following command after adjusting the issuer URL:
Or, if you want to test the private client defined in previous chapter:
kc token --issuerURL https://kubauth.mycluster.mycompany.com --clientId private --clientSecret secret1
Adjust the
issuerURLto the value set previously in Kubauth configuration
Tip
If you encounter an error like tls: failed to verify certificate: x509:..., the CA associated with your ClusterIssuer is not recognized on your local workstation.
- Add the
--insecureSkipVerifyoption to thekc tokencommand. You will also need to configure your browser to accept the certificate. - Add the CA as a trusted certificate on your local workstation. You can extract it with:
- Add the
--caFile ./ca.crtoption to thekc tokencommand.
Your browser should open to the Kubauth login page:

Log in using jim/jim123. You should land on a page similar to the following:

From this page, you can copy the provided tokens.
These tokens are also displayed in the CLI response:
Access token: ory_at_xLUfAhEGpFVWpMLdNEDZAj94hHFrHWjgOYB5g0Leh_k.0rgIzRGFOiIeGsMKnIZ74QL4Ve5vVOuEZyhA0402u8Y
Refresh token: ory_rt_nU9NBZs4NtKTxVYVko1aqlJkAMF5MLBYjfiZbhVt9aE.THwsnTlqzIsWo5O1NAf1EbDhz7HdaqVHHwSTkWxrkqY
ID token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImY0Y2NkNDU0LWYzYTgtNDQ3Zi1hN2MzLTY3ZmY5MzUxMzZiMSIsInR5cCI6IkpXVCJ9.eyJhdF9oYXNoIjoiaGNBY2dtdmdBekJlSGgyODlkWHF3USIsImF1ZCI6WyJwdWJsaWMiXSwiYXV0aF90aW1lIjoxNzYxMzI2MDg2LCJhenAiOiJwdWJsaWMiLCJleHAiOjE3NjEzMjk2ODYsImlhdCI6MTc2MTMyNjA4NiwiaXNzIjoiaHR0cHM6Ly9rdWJhdXRoLmluZ3Jlc3Mua3VibzYubWJwIiwianRpIjoiZDZhYjkwODMtYTEzMi00YTNiLTlmMWItMzM2NWFhOTQ5MjQ2IiwicmF0IjoxNzYxMzI2MDg2LCJzdWIiOiJqaW0ifQ.Q8ZkF33jsUJDqLH98uqRgrFa2nwioRP1TO9n6QjX9XFr-1WmsKk9nEeHGAiASb1brQ3cSAmK8ta7fX3lBLBlszxmeVZRzq5Qvg0N8nqvlV3C4CAiv6lEl6_-y6wBoQOWN9OhNhYU6wFjpNNDTx_RW0329i9TYVxaygw58wJGCX_1F5-PY0NG74n_1sdZxYop7s5GnZ0_9S9-DEI-LNR2MMx-oVH4lpGjV5dhGRvZS0l4tMm2C7J6Yx_JoTQoZfWwPI0GGf2smZZ-C2ieB5Wj0b19fgrafuexHW9yeejI51j6WZs_eDqUwvCIf52_yAvokA4SiW4PW8Eod9fX-JuwJQ
Expire in: 59m59s
Let's try another variant of the command:
kc token --issuerURL https://kubauth.mycluster.mycompany.com --clientId public --onlyIdToken | kc jwt
- The
--onlyIdTokenoption instructs the command to output only the base64-encoded ID token, useful for batch processing. - The
kc jwtcommand decodes the JWT token.
The response should look like:
JWT Header:
{
"alg": "RS256",
"kid": "f4ccd454-f3a8-447f-a7c3-67ff935136b1",
"typ": "JWT"
}
JWT Payload:
{
"at_hash": "_GWrC20juEb4Zh39S0ly5w",
"aud": [
"public"
],
"auth_time": 1761564624,
"auth_time_human": "2025-10-27 11:30:24 UTC",
"azp": "public",
"exp": 1761568224,
"exp_human": "2025-10-27 12:30:24 UTC",
"iat": 1761564624,
"iat_human": "2025-10-27 11:30:24 UTC",
"iss": "https://kubauth.mycluster.mycompany.com",
"jti": "be30eeb2-153f-4dec-97b8-c75d23035f81",
"rat": 1761564624,
"rat_human": "2025-10-27 11:30:24 UTC",
"sub": "jim"
}
Note
The auth_time_human, exp_human, iat_human, and rat_human fields are not actual claims but human-readable values added by the decoder to aid interpretation of the corresponding timestamp values.
There is also a shortcut (-d) for this command:
Note: This option skips the JWT header.
Claims
A set of 'system' claims are provided by the OIDC server. You can find a description of most standard claims here.
An important claim is sub, which stands for 'subject' and represents the user's login.
Now, run the previous command again, but use john/john123 when prompted for login:
JWT Payload:
{
"at_hash": "fdg2po7ht7lBaFFvgXg14A",
"aud": [
"public"
],
"auth_time": 1761575699,
"auth_time_human": "2025-10-27 14:34:59 UTC",
"azp": "public",
"email": "johnd@mycompany.com",
"emails": [
"johnd@mycompany.com"
],
"exp": 1761579299,
"exp_human": "2025-10-27 15:34:59 UTC",
"iat": 1761575699,
"iat_human": "2025-10-27 14:34:59 UTC",
"iss": "https://kubauth.mycluster.mycompany.com",
"jti": "822ed082-e615-4153-ad7e-d623df491253",
"name": "John DOE",
"office": "208G",
"rat": 1761575699,
"rat_human": "2025-10-27 14:34:59 UTC",
"sub": "john"
}
Kubauth has added several new claims derived from the User resource definition:
name: Thespec.nameproperty, containing the user's full name.emails: Thespec.emailslist.email: The first email from the emails list.office: Content from thespec.claimsproperty, which can contain any valid map values.
The resulting claim set is the result of merging:
- An initial set of system claims (
aud,azp,exp,iss, ...) - Claims added by Kubauth from the user CRD definition:
namefromspec.nameemailsfromspec.emailsgroupsdescribed in a following chapter
- The contents of the user's
spec.claims
Warning
In the current version, claims are not filtered by scope. In other words, all user claims are included in the ID token.
JWT Access Token
In OAuth 2.0, the Access Token grants access to a protected resource. However, the specification does not prescribe a specific format for it. This flexibility allows two main architectural styles: Opaque tokens and JWT (JSON Web Token).
This "Access Token" is different from the OIDC JWT token we just described above.
Opaque Tokens
An opaque token is a random string that carries no information on its own and is meaningless to anyone who inspects it.
When an application receives an opaque token, it has no knowledge of the user's identity or permissions. It must send the token back to the OAuth server (Kubauth) to validate it.
Advantages:
- Privacy: No user data is embedded in the token string.
- Instant Revocation: Deleting the token from the server invalidates it immediately on the next validation check.
- Security: Since the token contains no data, there is nothing for an attacker to decode.
JWT Access Token
A JWT Access Token is a self-contained, structured string. Like an OIDC ID token, it contains claims and is digitally signed by the OAuth server (Kubauth).
The resource server can validate the token locally by checking its digital signature against a public key. If the signature is valid and the token has not expired, the application trusts the embedded data without contacting Kubauth.
Advantages:
- Performance: No additional network call (introspection) is required, resulting in faster API responses.
- Scalability: The authorization server does not need to validate every request, eliminating it as a potential bottleneck.
- Standardization: JWTs follow a well-defined structure, making them easy to use across different programming languages and frameworks.
Configuration
By default, Kubauth is configured to generate Opaque Access Tokens.
This can be changed by setting a Helm chart configuration value:
values.yaml
Redeploy Kubauth:
helm -n kubauth upgrade -i kubauth --values ./values.yaml oci://quay.io/kubauth/charts/kubauth --version 0.2.1 --create-namespace --wait
You can now test, still using the public client:
Log in using jim/jim123.

Notice that the Access Token is significantly longer than an opaque token.
The same applies to the CLI response:
Access token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk1ODhlNWIyLTIwY2QtNGM3Mi04MGIwLTU0OGJjZDdjNDg0OCIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicHVibGljIl0sImF6cCI6InB1YmxpYyIsImV4cCI6MTc3Mzg1NDQyMSwiaWF0IjoxNzczODUwODIxLCJpc3MiOiJodHRwczovL2t1YmF1dGguaW5ncmVzcy5rdWJvMi5tYnAiLCJqdGkiOiJhNjk2ZDdlMC1iYmJkLTRkNDQtOTY2Ny04NWI4NThmY2I1ZWYiLCJzY3AiOlsib3BlbmlkIiwicHJvZmlsZSIsIm9mZmxpbmUiLCJncm91cHMiXSwic3ViIjoiamltIn0.mQ0Z_aQhAqkdA3fQTo8yNSyl1WLNbpPfJZOUT0J-zyU2BRkaAT_7hcD5TOAmHRH088HGrjWWSOhh8oO1fAzJ_lY50-uLGBGOvtFCFqWspcVLohzsJbbf5Uj0ir4IuOAVMdbW-G341FrCJzD7DiFFw4xHHJ_yc0GDS9JMZUlWgdUbxPtNF-Dt90j_SaOj6dsnZMJ8W08JwKKcTlOGgeQzze_hkPBWbb1HR9f6PShfAVGd1UVmT7fvZDwLs_3RthMR7ui3rX5P7kCR3ZxgKHoQjlbkARfcJ8ggxPxl_tHC7wp570MRslABA25x-c_zTuG5stTkzL3oEgcl8TPxr---Qw
Refresh token: ory_rt_jvYjlVuq4zRnsXwl3LFXj8pZ1HTj4C7qOZ0ZO-l1UbQ.lawnhz9iMrxQ4dVhwl0JqjSxplbFqr-EVJYWu_TJCgM
ID token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk1ODhlNWIyLTIwY2QtNGM3Mi04MGIwLTU0OGJjZDdjNDg0OCIsInR5cCI6IkpXVCJ9.eyJhdF9oYXNoIjoiM1NfTnRXWVVCRHhjN3JaeHBwTnBtUSIsImF1ZCI6WyJwdWJsaWMiXSwiYXV0aF90aW1lIjoxNzczODUwODIxLCJhenAiOiJwdWJsaWMiLCJleHAiOjE3NzM4NTQ0MjEsImlhdCI6MTc3Mzg1MDgyMSwiaXNzIjoiaHR0cHM6Ly9rdWJhdXRoLmluZ3Jlc3Mua3VibzIubWJwIiwianRpIjoiZjM1NDhkNmItYmU5OC00ZWI1LTk3NzktMDAzMmRmYjllYjNiIiwicmF0IjoxNzczODUwODIxLCJzdWIiOiJqaW0ifQ.U-j8bDWbprqTZW1OlLwjo7Y_RlXxJr3tazYukHO5uQ3xMFHKnBNxqJ3GyWrUpsY3NvBD_5xQIX1M67Nz54pV5Mhel2AqTNk1mm8GQcrdTUfCRZd6U3hmJ3LtpeyU5qCh2d2zbf0eZFGh-NtTVFj4zxoaiUWMzMEPD1VY0YV4ByH0oR6VZ22HKCgD3Ehqxdktwy5x9eckoVL1_b5K6hpfFc2O144PiU_c0qb0SCx9NGkHMEbS9Q9YdrkeMBPDt8ytB1L7GAMTS3Ij_Gtjc6wpFCH6AqYCahS_e9541coNOI07jZzsy5lCAGRVHYnfGa5-Ivbus5XkYd9UnI1wIlQpPQ
Expire in: 59m59s
Now, try the following:
kc token --issuerURL https://kubauth.mycluster.mycompany.com --clientId public --onlyAccessToken | kc jwt
- The
--onlyAccessTokenoption instructs the command to output only the Access Token, useful for piping to other commands. - The
kc jwtcommand decodes the JWT Access Token.
The response should look like:
Token: JWT Header:
{
"alg": "RS256",
"kid": "9588e5b2-20cd-4c72-80b0-548bcd7c4848",
"typ": "JWT"
}
Token: JWT Payload:
{
"aud": [
"public"
],
"azp": "public",
"exp": 1773854789,
"exp_human": "2026-03-18 17:26:29 UTC",
"iat": 1773851189,
"iat_human": "2026-03-18 16:26:29 UTC",
"iss": "https://kubauth.mycluster.mycompany.com",
"jti": "3b7cf9b9-f70a-42bc-9c98-f113a03b104a",
"scp": [
"openid",
"profile",
"offline",
"groups"
],
"sub": "jim"
}
There is also a shortcut for decoding the Access Token: