Belajar GitLab CI/CD - Passwordless Cloud Authentication Menggunakan OIDC (OpenID Connect)
Episode 13 of 21

Belajar GitLab CI/CD - Passwordless Cloud Authentication Menggunakan OIDC (OpenID Connect)

Kredensial cloud yang disimpan permanen di CI/CD variables adalah bom waktu yang menunggu meledak. Episode ini menjelaskan cara menggantinya dengan OpenID Connect — pipeline meminta token berumur pendek langsung dari GitLab untuk mengotentikasi diri ke AWS, GCP, dan Azure tanpa menyimpan satu pun secret jangka panjang.

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

Pendahuluan

Di episode 12 sebelumnya kita membahas DevSecOps native — termasuk Secret Detection yang menangkap kredensial yang bocor ke repository. Tapi ada satu sumber kredensial yang tidak terlihat di repository: variabel CI/CD yang menyimpan access key cloud secara permanen. Di episode 5 kita membahas cara menyimpan variable dengan flag Masked dan Protected — namun itu hanya memperlambat pencurian, bukan mencegahnya.

Pola lama untuk autentikasi ke cloud dari pipeline selalu berakhir seperti ini: seseorang membuat user IAM khusus, membiarkan access key-nya terpasang di pengaturan CI/CD, dan key itu hidup selama berbulan-bulan. Satu key seperti itu cukup untuk diinginkan oleh penyerang — dan ketika bocor, seluruh akun cloud jadi taruhannya. Ini persis seperti memberikan satu kunci rumah yang berlaku seumur hidup kepada semua orang yang lewat: nyaman, tapi sekali hilang, semua pintu terbuka.

Episode ini memperkenalkan pendekatan yang jauh lebih aman: passwordless cloud authentication menggunakan OIDC (OpenID Connect). Pipeline tidak lagi menyimpan kredensial permanen — ia meminta token berumur pendek langsung dari GitLab untuk setiap pipeline, dan token itu hanya valid dalam hitungan menit. Mari kita bedah.

Pembahasan Utama

Risiko Long-Lived Keys di CI/CD Variables

Sebelum membahas solusi, mari jujur soal masalahnya. Menyimpan AWS_ACCESS_KEY_ID dan AWS_SECRET_ACCESS_KEY sebagai variabel CI/CD permanen membawa tiga risiko utama:

  1. Jendela ekspos sangat panjang. Key berlaku berminggu-minggu hingga berbulan-bulan. Siapa pun yang mendapat akses sekali — melalui log, eksfiltrasi, atau kontributor jahat — bisa memakai key itu selama berbulan-bulan tanpa terdeteksi.
  2. Tidak ada konteks. Key IAM tidak membawa informasi tentang pipeline mana yang memakainya. Tidak ada jejak audit yang menghubungkan sebuah API call ke job atau commit tertentu.
  3. Revocation itu mahal. Mencabut key yang tersebar di banyak project berarti mengedit semua project satu per satu — dan kemungkinan besar salah satu terlewat.

Warning

Jangan pernah menyimpan long-lived cloud credentials — terutama AWS Secret Access Key — sebagai variabel CI/CD permanen. Masking hanya menyembunyikan nilai di log; ia tidak mencegah pencurian dari dalam runner atau dari akses yang sudah terlanjur bocor. OIDC menghapus kebutuhan akan kredensial permanen tersebut sepenuhnya.

Bagaimana OIDC Bekerja di GitLab

OIDC adalah protokol yang sudah ada di mana-mana — kalian menggunakannya setiap kali login ke sebuah situs dengan "Sign in with Google". Dalam konteks CI/CD, alurnya seperti ini:

  1. Kalian mendefinisikan id_tokens di sebuah job.
  2. Saat job dijalankan, GitLab server menerbitkan JWT (JSON Web Token) yang berisi klaim tentang job tersebut — project path, branch, commit SHA, dan nilai aud yang kalian set.
  3. Job mengirim JWT ini ke cloud provider (AWS, GCP, atau Azure).
  4. Cloud provider memverifikasi tanda tangan JWT terhadap public keys GitLab (JWKS) dan memeriksa klaim seperti aud dan project path.
  5. Jika valid, provider mengembalikan kredensial sementara yang hanya hidup beberapa menit hingga beberapa jam.

Kuncinya ada pada JWT: token ini berumur pendek, terikat pada konteks pipeline tertentu, dan tidak pernah disimpan di mana pun. GitLab bertindak sebagai identity provider — sama seperti Google atau Okta, tapi khusus untuk pipeline.

Konfigurasi id_tokens di .gitlab-ci.yml

Konfigurasinya cukup dengan blok id_tokens pada level job, pipeline, atau default. Nilai yang penting adalah audaudience yang harus cocok dengan yang dikonfigurasi di cloud provider.

Mendefinisikan OIDC token di job
deploy-to-aws:
  stage: deploy
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - echo "JWT tersedia di GITLAB_OIDC_TOKEN"
    - echo "${#GITLAB_OIDC_TOKEN} karakter token"

Setelah didefinisikan, JWT bisa diakses sebagai variabel shell GITLAB_OIDC_TOKEN di dalam job — tersedia hanya untuk job yang mendefinisikannya. Inilah yang dikirim ke cloud provider untuk ditukar dengan kredensial sementara. Catatan: jika nama variabel diakhiri _FILE (misal GITLAB_OIDC_TOKEN_FILE), GitLab menulis token ke file dan variabel tersebut memuat path-nya — berguna untuk alat yang butuh token berbentuk file.

Tip

Nilai aud bersifat bebas, tapi pastikan konsisten antara GitLab dan cloud provider. Banyak tim memakai https://gitlab.com untuk GitLab.com atau URL instance self-hosted mereka. Beberapa provider menggunakan aud untuk membedakan pipeline mana yang boleh memakai role mana.

Integrasi dengan AWS: STS AssumeRoleWithWebIdentity

Di AWS, alurnya memakai IAM Role + layanan Security Token Service (STS). Kalian membuat role IAM, mengonfigurasi GitLab sebagai web identity provider di IAM, lalu pipeline menukar JWT dengan kredensial role tersebut.

Trust policy role di AWS (disarikan) memastikan hanya token dari project GitLab yang benar yang bisa memakai role:

Trust policy IAM untuk GitLab OIDC
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/gitlab.com"
      },
      "Action": "sts:TagSession",
      "Condition": {
        "StringEquals": {
          "gitlab.com:aud": "https://gitlab.com"
        }
      }
    }
  ]
}

Di dalam job, pipeline menukar JWT dengan kredensial role menggunakan AWS CLI:

Job deploy dengan AWS STS
deploy:
  image: amazon/aws-cli:latest
  stage: deploy
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - aws sts assume-role-with-web-identity \
        --role-arn arn:aws:iam::123456789012:role/gitlab-deployer \
        --role-session-name gitlab-pipeline \
        --web-identity-token "$GITLAB_OIDC_TOKEN" \
        --duration-seconds 3600

Kredensial sementara hasil assume-role ini bisa di-export ke environment dan dipakai perintah AWS berikutnya, lalu mati sendiri setelah 1 jam. Tidak ada access key permanen yang tersimpan di GitLab.

Integrasi dengan GCP: Workload Identity Federation

Google Cloud menggunakan Workload Identity Federation untuk tujuan yang sama. Konsepnya: kalian membuat workload identity pool dan provider yang mempercayai GitLab sebagai identity provider, lalu menghubungkannya dengan sebuah service account. Karena GCP membutuhkan token dalam bentuk file, job-nya memakai konvensi variabel id_tokens yang diakhiri _FILE — GitLab menulis JWT ke sebuah file, dan variabelnya memuat path file tersebut.

Membuat kredensial sementara dari JWT
gcloud iam workload-identity-pools create-cred-config \
  projects/123456789/locations/global/workloadIdentityPools/ci-pool/providers/gitlab-provider \
  --service-account=gitlab-deployer@my-project.iam.gserviceaccount.com \
  --subject-token-type=urn:ietf:params:oauth:token-type:jwt \
  --credential-source-file="$GITLAB_OIDC_TOKEN_FILE" \
  --output-file="$CI_PROJECT_DIR/gcp-credential.json"
 
gcloud auth login --cred-file="$CI_PROJECT_DIR/gcp-credential.json"

Alur yang umum: gcloud ... create-cred-config menghasilkan file kredensial sementara dari JWT, lalu gcloud auth login --cred-file memakainya. Hasilnya — akses ke GCP tanpa ada service account key yang tersimpan.

Integrasi dengan Azure: Federated Identity Credentials

Azure memakai federated identity credentials di Azure AD. Kalian membuat app registration atau user-assigned managed identity, menambahkan credential federasi yang mempercayai GitLab, lalu pipeline login dengan token JWT tersebut:

Login ke Azure dengan token federasi
az login \
  --service-principal \
  --username "$AZURE_CLIENT_ID" \
  --tenant "$AZURE_TENANT_ID" \
  --federated-token "$GITLAB_OIDC_TOKEN"
ProviderMekanismeKredensial yang disimpan
AWSIAM Role + STS AssumeRoleWithWebIdentityTidak ada
GCPWorkload Identity FederationTidak ada
AzureFederated Identity CredentialsTidak ada

Pola yang sama, bahasa yang berbeda: definisikan id_tokens di GitLab, lalu tukar JWT-nya dengan kredensial sementara dari provider masing-masing.

Kesalahan Umum dalam OIDC

KesalahanGejalaSolusi
Lupa membatasi klaim di trust policyProject lain bisa memakai rolePerketat aud, project path, dan branch di condition
Menggunakan $CI_JOB_JWT yang deprecatedToken kedaluwarsa tak terdugaGunakan id_tokens dengan aud eksplisit
Masih menyimpan access key sebagai fallbackLong-lived key tetap adaHapus key dan gunakan OIDC penuh
Token terlalu permisifAkses lebih luas dari yang dibutuhkanGunakan role/scope minimal sesuai job
Tidak menguji rotasiDeployment tiba-tiba gagal saat key dirotasiOIDC tidak punya key statis; verifikasi berkala

Important

OIDC menghilangkan kredensial statis, tapi bukan berarti tanpa konfigurasi. Keamanan akhir berada di trust policy — batasi provider mempercayai hanya project, branch, dan environment yang benar. Token yang valid tetap tidak berguna jika kondisi di trust policy sudah dipersempit dengan benar.

Penutup

Pada episode ini kita telah membahas risiko menyimpan long-lived cloud credentials di CI/CD variables — jendela ekspos yang panjang, tanpa konteks, dan mahal saat di-revoke; cara kerja OIDC di GitLab dengan id_tokens yang menerbitkan JWT berumur pendek; serta integrasi dengan tiga cloud provider besar — AWS melalui STS AssumeRoleWithWebIdentity, GCP melalui Workload Identity Federation, dan Azure melalui federated identity credentials — semuanya tanpa menyimpan satu pun secret permanen.

Inti dari episode ini: kredensial yang tidak pernah disimpan tidak bisa dicuri. Dengan OIDC, pipeline membuktikan identitasnya lewat token sekali jalan yang berumur pendek dan terikat konteks, menggantikan kunci permanen yang selama ini menjadi titik lemah terbesar.

Di episode 14 selanjutnya kita akan mengelola apa yang dideploy ke cloud tersebut: Environments, Deployments & Manual Approval Gates — deklarasi environment, riwayat deployment di UI GitLab, approval gate manual untuk produksi, protected environments, dan Review Apps. Sampai jumpa!

Belajar GitLab CI/CD - Passwordless Cloud Authentication Menggunakan OIDC (OpenID Connect) | Belajar GitLab CI/CD