Learn Jenkins - Passwordless Cloud Authentication Using OIDC
Episode 12 of 21

Learn Jenkins - Passwordless Cloud Authentication Using OIDC

Replace risky static credentials with OpenID Connect, a passwordless authentication based on short-lived tokens for AWS, GCP, and Azure, while applying the least privilege principle.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 11 we secured the controller: disabled anonymous access, chose an authentication scheme, and implemented RBAC. But there is one security gap that often slips through: static cloud credentials.

Many teams store AWS Access Keys, GCP Service Account Keys, or Azure Client Secrets permanently in Jenkins Credentials. Such credentials are like a master key — valid forever, never changing, and once leaked, anyone can take over all your cloud resources. The risk is real: hacker bots scan repositories and public files within minutes, and once a key is exposed, the impact can spread into the production environment.

The modern solution is OpenID Connect (OIDC). The concept is simple: Jenkins no longer stores static credentials, but instead requests a short-lived token each time a build runs, then exchanges it for temporary credentials in the cloud. In this episode we will understand the flow, why it is safer, and how to implement it on AWS, GCP, and Azure.

Main Discussion

The Problem with Static Credentials

Storing static credentials in Jenkins means carrying three burdens at once:

  1. Manual rotation — a key never changes until someone remembers it, and that is often forgotten until an incident happens.
  2. Wide blast radius — one key used by dozens of jobs grants access to all the resources it is allowed to reach.
  3. Hard to audit — there is no trace of which job used the credential when a leak occurs.

Warning

Do not write static access keys directly in a Jenkinsfile or pipeline parameters. If one is already stored in Jenkins Credentials, plan a migration to OIDC and rotate the key immediately.

The OpenID Connect (OIDC) Concept

OIDC is built on top of the OAuth 2.0 protocol and introduces the ID Token — a JSON Web Token (JWT) containing claims such as issuer, audience, and subject. The key properties that make it suitable for CI/CD:

  • Short-lived — the token is valid for only a few minutes, enough for one build.
  • Context-bound — the token can be restricted to a specific project, branch, or environment.
  • No secret storage — there is no permanent key on either the Jenkins or the cloud side.

Jenkins acts as the OIDC Provider: when a build runs, Jenkins issues an ID Token, then the cloud provider verifies the token's signature via Jenkins's JWKS endpoint and exchanges it for temporary credentials. The analogy is a plane boarding pass: valid once, contains a specific destination, and expires after the flight — unlike a room key that works forever.

End-to-End Flow on AWS

On AWS, this exchange uses STS AssumeRoleWithWebIdentity. The flow:

  1. Configure Jenkins as an OIDC provider in IAM (issuer = the Jenkins URL).
  2. Create an IAM role with a trust policy that only allows tokens with a specific audience and subject.
  3. In the pipeline, use the withOIDC step to request an ID token.
  4. The AWS CLI exchanges that token for temporary credentials via STS.
  5. All AWS commands inside the block run without a permanent access key.

An example of that role's trust policy:

IAM Trust Policy for AssumeRoleWithWebIdentity
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/jenkins.example.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "jenkins.example.com:aud": "aws-deploy",
          "jenkins.example.com:sub": "repo:my-org/my-app:environment:prod"
        }
      }
    }
  ]
}

Once the role is ready, the pipeline simply requests a token and runs the AWS CLI inside it:

JenkinsJenkinsfile - passwordless AWS
pipeline {
    agent { label 'linux-runner' }
    stages {
        stage('Deploy ke AWS Tanpa Password') {
            steps {
                withOIDC(id: 'aws-deploy', provider: 'aws-oidc') {
                    sh 'aws sts get-caller-identity'
                    sh 'aws s3 sync ./dist s3://my-app-bucket --delete'
                }
            }
        }
    }
}

Tip

The audience value in the pipeline must match exactly the audience in the trust policy. Also restrict the subject claim per repository and environment so tokens from other jobs cannot abuse the same role.

GCP Workload Identity & Azure Federated Credentials

On Google Cloud Platform, the similar concept is called Workload Identity Federation. You create a workload identity pool along with an OIDC provider pointing at the Jenkins issuer, then impersonate a service account. Create the pool and provider with gcloud:

Create a Workload Identity Pool in GCP
gcloud iam workload-identity-pools create jenkins-pool \
  --location=global --display-name="Jenkins Pool"
 
gcloud iam workload-identity-pools providers create-oidc jenkins-provider \
  --location=global --workload-identity-pool=jenkins-pool \
  --issuer-uri="https://jenkins.example.com" \
  --attribute-mapping="google.subject=assertion.sub"

On Microsoft Azure, use federated identity credentials on an App Registration or Managed Identity. Each federated credential defines the issuer, subject, and audience that the Jenkins token must satisfy:

Create a Federated Credential in Azure
az identity federated-credential create \
  --name jenkins-cred \
  --identity-name my-app-id \
  --resource-group rg-prod \
  --issuer "https://jenkins.example.com" \
  --subject "repo:my-org/my-app:environment:prod" \
  --audiences "azure-deploy"

Why Passwordless Is Safer

Let's compare the old and new approaches side by side:

AspectStatic CredentialsOIDC
Credential lifetimePermanent until manually rotatedA few minutes per build
Impact if leakedFull access without time limitToken expires quickly
RotationManual, prone to being forgottenAutomatic every build
Access scopeHard to trace per jobCan be limited per subject & audience
OperationsBackup keys, service account filesNo cloud secrets stored

With OIDC, the least privilege principle applies naturally: each job requests the lowest role sufficient for its task, tokens are only valid for a specific context, and there are no permanent credentials that can be stolen and reused repeatedly.

Important

OIDC reduces the risk of key leakage but does not eliminate the need for authorization. Still keep the role permissions as small as possible and separate roles for staging and production.

Conclusion

In episode 12 you have understood why static credentials are dangerous for pipelines, how OIDC works with short-lived ID Tokens, and how Jenkins acts as an OIDC provider exchanging tokens with AWS via STS AssumeRoleWithWebIdentity, GCP via Workload Identity, and Azure via federated identity credentials. You also saw how this approach applies least privilege naturally.

Interestingly, almost all the configuration we have done manually through the UI so far — including security settings, RBAC, and credentials — can actually be written as code.

In episode 13 we will discuss Jenkins Configuration as Code (JCasC): managing the entire controller via a jenkins.yaml file and creating an identical Jenkins in seconds. See you there!

Learn Jenkins - Passwordless Cloud Authentication Using OIDC | Learn Jenkins