{"id":52596,"date":"2025-09-10T07:22:43","date_gmt":"2025-09-10T07:22:43","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=52596"},"modified":"2025-09-10T07:22:43","modified_gmt":"2025-09-10T07:22:43","slug":"complete-tutorial-jwt-json-web-token-oidc-openid-connect","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/complete-tutorial-jwt-json-web-token-oidc-openid-connect\/","title":{"rendered":"Complete Tutorial: JWT (JSON Web Token) &amp; OIDC (OpenID Connect)"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. \ud83d\udd0e What is JWT?<\/h2>\n\n\n\n<p><strong>Definition<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JWT (JSON Web Token)<\/strong> is a compact, URL-safe token format that encodes claims as a JSON object, digitally signed (JWS) or encrypted (JWE).<\/li>\n\n\n\n<li>Structure: <code>header.payload.signature<\/code> (Base64URL encoded).<\/li>\n<\/ul>\n\n\n\n<p><strong>Structure<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Header<\/strong> \u2192 Algorithm &amp; token type (e.g., <code>{\"alg\":\"RS256\",\"typ\":\"JWT\"}<\/code>).<\/li>\n\n\n\n<li><strong>Payload<\/strong> \u2192 Claims: identity data &amp; metadata (e.g., <code>sub<\/code>, <code>exp<\/code>, <code>aud<\/code>).<\/li>\n\n\n\n<li><strong>Signature<\/strong> \u2192 Verifies integrity &amp; authenticity using a secret (HMAC) or key pair (RSA\/ECDSA).<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. \ud83d\udd0e What is OIDC?<\/h2>\n\n\n\n<p><strong>Definition<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>OpenID Connect (OIDC)<\/strong> is an <strong>authentication protocol<\/strong> built on <strong>OAuth 2.0<\/strong>.<\/li>\n\n\n\n<li>It adds a standard <strong>ID Token (JWT)<\/strong> that represents the <strong>user\u2019s identity<\/strong>.<\/li>\n\n\n\n<li>Provides user authentication, profile info, and single sign-on (SSO).<\/li>\n<\/ul>\n\n\n\n<p><strong>Key OIDC Tokens<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ID Token (JWT)<\/strong> \u2192 proves <em>who the user is<\/em>.<\/li>\n\n\n\n<li><strong>Access Token (JWT or opaque)<\/strong> \u2192 proves <em>what the client can access<\/em>.<\/li>\n\n\n\n<li><strong>Refresh Token<\/strong> \u2192 gets new access tokens without re-login.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. \u2753 Why do we need them?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">JWT<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Standardized, interoperable way to carry claims.<\/li>\n\n\n\n<li>Self-contained \u2192 no DB lookup needed for validation.<\/li>\n\n\n\n<li>Compact \u2192 good for APIs, mobile, web.<\/li>\n\n\n\n<li>Works across trust boundaries (issuer \u2192 consumer).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">OIDC<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Standardized login flows (web, mobile, APIs).<\/li>\n\n\n\n<li>Federated identity \u2192 login with Google, Facebook, enterprise IdPs.<\/li>\n\n\n\n<li>Simplifies SSO across apps &amp; organizations.<\/li>\n\n\n\n<li>Adds identity layer missing from OAuth 2.0.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. \u2699\ufe0f How each works<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">A. JWT Lifecycle<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Issuer creates token<\/strong> \u2192 signs claims with private key.<\/li>\n\n\n\n<li><strong>Client receives token<\/strong> \u2192 attaches to <code>Authorization: Bearer &lt;token><\/code>.<\/li>\n\n\n\n<li><strong>Resource server validates<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Decode Base64.<\/li>\n\n\n\n<li>Verify signature (with shared secret or public key via JWKS).<\/li>\n\n\n\n<li>Validate claims (<code>exp<\/code>, <code>iss<\/code>, <code>aud<\/code>).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Grant or deny access<\/strong>.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">B. OIDC Flow (Authorization Code Grant \u2013 most common)<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>User \u2192 Client App<\/strong> (e.g., SPA, mobile).<\/li>\n\n\n\n<li><strong>Client redirects to IdP (OIDC provider)<\/strong> \u2192 login page.<\/li>\n\n\n\n<li><strong>User authenticates<\/strong> \u2192 IdP issues authorization code.<\/li>\n\n\n\n<li><strong>Client exchanges code at IdP\u2019s Token Endpoint<\/strong> \u2192 receives:\n<ul class=\"wp-block-list\">\n<li><strong>ID Token (JWT)<\/strong> = who user is.<\/li>\n\n\n\n<li><strong>Access Token<\/strong> = what user can do.<\/li>\n\n\n\n<li><strong>Refresh Token<\/strong> (optional).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Client calls backend APIs with access token<\/strong>.<\/li>\n\n\n\n<li><strong>APIs validate token signature &amp; claims via JWKS<\/strong>.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. \ud83d\udd28 Use Cases<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">JWT<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Service-to-service authentication<\/strong> (microservices).<\/li>\n\n\n\n<li><strong>API authorization<\/strong> (validate tokens at API gateway).<\/li>\n\n\n\n<li><strong>Stateless sessions<\/strong> (store user claims in token instead of DB).<\/li>\n\n\n\n<li><strong>Delegated authorization<\/strong> (OAuth2 access tokens in JWT form).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">OIDC<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>User login for apps<\/strong> (web, mobile).<\/li>\n\n\n\n<li><strong>SSO across multiple apps\/domains<\/strong>.<\/li>\n\n\n\n<li><strong>Federated identity<\/strong> (Google, Facebook, Azure AD).<\/li>\n\n\n\n<li><strong>Enterprise IAM<\/strong> (Okta, Auth0, Keycloak, Cognito, etc.).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. \ud83e\udde0 Advanced Concepts<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JWT Signing Algorithms<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Symmetric (HMAC: HS256).<\/li>\n\n\n\n<li>Asymmetric (RSA\/ECDSA: RS256\/ES256).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>JWT Expiration &amp; Rotation<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Use short-lived access tokens + long-lived refresh tokens.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Token Introspection<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Sometimes you need central validation (introspection endpoint).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>JWE (Encrypted JWTs)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Secure confidentiality, not just integrity.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Scopes &amp; Claims<\/strong>:\n<ul class=\"wp-block-list\">\n<li>OIDC adds standard claims (<code>sub<\/code>, <code>email<\/code>, <code>profile<\/code>).<\/li>\n\n\n\n<li>Custom claims supported in JWT payload.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Delegation<\/strong>:\n<ul class=\"wp-block-list\">\n<li>JWTs used in OAuth2 delegation &amp; consent scenarios.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. \ud83d\udeab Limitations &amp; Risks<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JWT Risks<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>Replay attacks<\/strong> if tokens aren\u2019t short-lived.<\/li>\n\n\n\n<li><strong>Revocation is hard<\/strong> (since tokens are self-contained).<\/li>\n\n\n\n<li><strong>Bloat<\/strong> if too many claims.<\/li>\n\n\n\n<li><strong>&#8220;alg:none&#8221; attack<\/strong> (misconfigured libraries).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>OIDC Risks<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Complexity (many flows, tokens).<\/li>\n\n\n\n<li>Misconfigured redirect URIs \u2192 open redirect attacks.<\/li>\n\n\n\n<li>Token leakage in browser history (if using implicit flow).<\/li>\n\n\n\n<li>Reliance on IdP availability.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">8. \u2601\ufe0f Cloud Provider Support<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd37 AWS<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JWT<\/strong>\n<ul class=\"wp-block-list\">\n<li>API Gateway HTTP APIs \u2192 JWT Authorizer (validate Firebase\/Okta\/Keycloak\/\u2026).<\/li>\n\n\n\n<li>Cognito issues JWT access &amp; ID tokens.<\/li>\n\n\n\n<li>IAM roles for service-to-service often delivered as JWT (STS, OIDC federation).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>OIDC<\/strong>\n<ul class=\"wp-block-list\">\n<li>ALB <code>authenticate-oidc<\/code> action with Cognito or external OIDC IdP.<\/li>\n\n\n\n<li>EKS uses OIDC for IRSA (IAM Roles for Service Accounts).<\/li>\n\n\n\n<li>Cognito User Pools = OIDC provider.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd37 Google Cloud<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JWT<\/strong>\n<ul class=\"wp-block-list\">\n<li>Cloud Endpoints &amp; API Gateway validate JWTs.<\/li>\n\n\n\n<li>Cloud Run IAM uses Google-signed JWT ID tokens.<\/li>\n\n\n\n<li>Firebase Auth issues JWT ID tokens.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>OIDC<\/strong>\n<ul class=\"wp-block-list\">\n<li>API Gateway validates OIDC tokens from Firebase\/Auth0\/etc.<\/li>\n\n\n\n<li>Workload Identity Federation uses OIDC for IAM roles.<\/li>\n\n\n\n<li>Identity Platform = full OIDC provider.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd37 Azure<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JWT<\/strong>\n<ul class=\"wp-block-list\">\n<li>Azure AD issues JWT access &amp; ID tokens.<\/li>\n\n\n\n<li>API Management (APIM) validates JWTs.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>OIDC<\/strong>\n<ul class=\"wp-block-list\">\n<li>Azure AD is an OIDC provider.<\/li>\n\n\n\n<li>Azure App Service Authentication integrates with OIDC IdPs.<\/li>\n\n\n\n<li>AKS workload identity uses OIDC for federated access.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">9. \ud83c\udfaf Practical Patterns<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Users (humans)<\/strong>\n<ul class=\"wp-block-list\">\n<li>OIDC login \u2192 ID Token (JWT) \u2192 proves identity.<\/li>\n\n\n\n<li>Access token (JWT) \u2192 proves authorization.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Services (machines)<\/strong>\n<ul class=\"wp-block-list\">\n<li>JWT via OAuth2 client credentials or workload identity federation.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Hybrid<\/strong>\n<ul class=\"wp-block-list\">\n<li>Human logs in \u2192 gets token \u2192 service uses token to call another API.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">10. \ud83d\udccc Quick Comparison Table<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>JWT<\/th><th>OIDC<\/th><\/tr><\/thead><tbody><tr><td><strong>Type<\/strong><\/td><td>Token format<\/td><td>Authentication protocol<\/td><\/tr><tr><td><strong>Who issues<\/strong><\/td><td>Any IdP or app<\/td><td>OIDC-compliant IdP<\/td><\/tr><tr><td><strong>Who uses<\/strong><\/td><td>Apps, APIs, services<\/td><td>Apps authenticating human users<\/td><\/tr><tr><td><strong>Scope<\/strong><\/td><td>Authorization, service identity<\/td><td>Authentication + identity + SSO<\/td><\/tr><tr><td><strong>Token<\/strong><\/td><td>Access token (JWT)<\/td><td>ID token (JWT) + access token<\/td><\/tr><tr><td><strong>Cloud use<\/strong><\/td><td>API Gateway, STS, workload ID<\/td><td>Cognito, Firebase, Azure AD, Keycloak<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u2705 <strong>In short<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JWT<\/strong> = a token <em>format<\/em> for carrying claims, widely used in APIs &amp; services.<\/li>\n\n\n\n<li><strong>OIDC<\/strong> = a <em>protocol<\/em> for authenticating users, which issues JWTs (ID tokens).<\/li>\n\n\n\n<li>Both are essential for modern cloud-native identity &amp; access control.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. \ud83d\udd0e What is JWT? Definition Structure 2. \ud83d\udd0e What is OIDC? Definition Key OIDC Tokens 3. \u2753 Why do we need them? JWT OIDC 4. \u2699\ufe0f How each works&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-52596","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/52596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=52596"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/52596\/revisions"}],"predecessor-version":[{"id":52597,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/52596\/revisions\/52597"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=52596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=52596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=52596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}