Menyimpan long-lived credentials seperti AWS_ACCESS_KEY_ID dan AWS_SECRET_ACCESS_KEY di dalam GitHub Secrets memiliki risiko keamanan tinggi. Jika terjadi supply chain attack via dependency berbahaya atau eksekusi kode berbahaya pada pull request, kredensial statis tersebut dapat dieksfiltrasi dan digunakan dari luar pipeline tanpa batas waktu.

Solusi standar industri untuk masalah ini adalah meniadakan secret statis dan beralih ke OpenID Connect (OIDC). Dengan OIDC, GitHub Actions bertindak sebagai identity provider yang menerbitkan JSON Web Token (JWT) berumur pendek (ephemeral) untuk ditukar dengan kredensial sementara melalui AWS Security Token Service (STS).

Statik Kredensial vs Ephemeral Token OIDC

Penggunaan token statis mengharuskan proses rotasi manual, sulit diaudit sumber panggilannya, dan tetap valid meskipun runner CI/CD sudah selesai mengeksekusi tugasnya. Sebaliknya, OIDC menawarkan mekanisme otentikasi berbasis identitas runtime:

  • Masa Berlaku Pendek: Kredensial AWS STS standar hanya aktif selama 1 jam secara default, meminimalkan jendela eksploitasi jika token bocor dari memori runner.
  • Validasi Konteks Ketat: AWS IAM memvalidasi klaim dalam payload JWT seperti nama repositori, branch, hingga trigger event sebelum memberikan izin akses.
  • Zero Secret Storage: Tidak ada kredensial cloud permanen yang tersimpan di GitHub Secrets repository settings.

Konfigurasi AWS IAM Identity Provider dan Trust Policy

Langkah awal adalah mendaftarkan GitHub sebagai OpenID Connect Identity Provider di AWS IAM. URL provider adalah https://token.actions.githubusercontent.com dengan Audience (aud) sts.amazonaws.com.

Setelah provider terdaftar, buat IAM Role khusus deployment. Batasi entitas yang boleh mengasumsikan role menggunakan Trust Policy berikut:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:organisasi-anda/nama-repo:ref:refs/heads/main"
        }
      }
    }
  ]
}
Penting: Selalu batasi klaim sub (Subject). Jangan gunakan wildcard penuh seperti repo:organisasi-anda/*:* untuk role produksi. Gunakan pola spesifik ke branch produksi (misalnya ref:refs/heads/main) atau environment tertentu agar cabang fitur (feature branches) atau PR dari fork tidak dapat mengasumsikan role tersebut.

Konfigurasi Workflow GitHub Actions Minimal

Agar runner GitHub Actions dapat meminta OIDC token dari OIDC provider GitHub, workflow harus diberi izin id-token: write. Jalankan prinsip least privilege dengan menerapkan izin tersebut hanya pada job yang membutuhkan akses cloud, bukan di tingkat global workflow.

name: Deploy to AWS

on:
  push:
    branches:
      - main

# Matikan izin default pada level workflow
permissions: {}

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read     # Izin membaca kode repositori
      id-token: write     # Wajib ada untuk OIDC JWT minting

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Configure AWS Credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy-role
          aws-region: ap-southeast-1
          audience: sts.amazonaws.com

      - name: Verify Identity
        run: |
          aws sts get-caller-identity

Analisis Struktur Claim JWT GitHub

Saat langkah aws-actions/configure-aws-credentials berjalan, runner meminta token JWT bertanda tangan dari auth service GitHub. Payload token berisi klaim-klaim kritis yang divalidasi AWS STS:

  • sub: Menunjukkan konteks repositori dan ref (misal: repo:org/app:ref:refs/heads/main atau repo:org/app:environment:production).
  • aud: Secara default bernilai URL STS atau identitas target penerima token.
  • repository_owner: Akun pengguna atau organisasi pemilik repositori.
  • job_workflow_ref: Jalur tepat workflow yang mengeksekusi job, berguna untuk mitigasi modifikasi workflow lokal.

Pencegahan Eksfiltrasi dan Praktik Terbaik

Menerapkan OIDC mengeliminasi risiko pencurian token jangka panjang, tetapi build compromised tetap dapat menyalahgunakan token STS selama masa berlakunya. Lakukan mitigasi tambahan berikut:

  1. Gunakan GitHub Environments: Ikat IAM Trust Policy dengan klaim environment (repo:org/app:environment:production) dan aktifkan Required Reviewers di GitHub repository settings agar deployment ke AWS membutuhkan approval manual.
  2. Terapkan Session Duration Minimal: Atur durasi role AWS sesingkat mungkin sesuai durasi build (misalnya 15-30 menit) menggunakan parameter role-duration-seconds pada action.
  3. Isolasi Step Kritis: Jangan menjalankan instalasi dependency yang tidak terverifikasi (seperti npm install script arbitrer) pada step yang sama setelah kredensial STS aktif. Pisahkan job build artifact dari job deployment yang memegang kredensial AWS.