Menguasai manajemen secret modern: Secrets Manager vs Parameter Store vs Vault, rotation otomatis, mencegah kebocoran dengan gitleaks dan pre-commit hook, serta migrasi CI/CD bebas kredensial statis memakai OIDC federation sehingga access key tidak lagi ada untuk dicuri

Setelah di episode 13 kita melihat secret di konteks serverless, sekarang kita angkat topiknya jadi utama — karena secret adalah jenis artefak yang paling sering menyebabkan breach, dan cara paling murah menyerang organisasi: cukup cari .env yang ter-commit, token CI di log, atau access key di dump public bucket.
Mengapa episode ini penting? Karena secret yang bocor memberi penyerang akses sah — firewall dan WAF tidak akan menolong. Dan sebaliknya, manajemen secret yang benar membuat pencurian menjadi sia-sia: kredensial pendek umur, terbatas scope, dan otomatis kedaluwarsa.
Sebelum bicara tool, samakan definisi. Secret yang dikelola baik punya empat sifat:
Access key statis gagal di semua empat poin. Itulah kenapa target akhir episode ini: nol access key statis di seluruh organisasi.
| Tool | Kekuatan | Cocok Untuk |
|---|---|---|
| AWS Secrets Manager | Rotation bawaan, integrasi native, audit KMS | Ekosistem AWS, database credentials |
| SSM Parameter Store (SecureString) | Murah (standard tier gratis), hierarki path | Konfigurasi + secret volume rendah |
| HashiCorp Vault/OpenBao | Multi-cloud, dynamic secrets, PKI, transit encryption | Organisasi multi-cloud & kebutuhan dynamic credential |
Prinsip pemilihan pragmatis: mulai dari layanan cloud yang sudah kalian bayar; naikkan ke Vault hanya saat butuh fiturnya (dynamic secrets per-session, broker PKI internal).
Contoh secret database dengan rotasi otomatis mingguan:
aws secretsmanager create-secret \
--name prod/orders/db \
--secret-string '{"username":"orders_app","password":"INITIAL"}'
aws secretsmanager create-secret \
--name prod/orders/db \
--rotation-lambda-arn arn:aws:lambda:ap-southeast-1:123456789012:function:SecretsManagerRDSPostgreSQLRotationSingleUser \
--description "rotated weekly by managed lambda"
aws secretsmanager rotate-secret --secret-id prod/orders/db \
--rotation-rules '{"ScheduleExpression":"rate(7 days)"}'Rotasi single-user sempat downtime mikro (password berganti); untuk database kritikal gunakan alternating users (dua user aktif bergantian) agar nol downtime.
Aplikasi tidak boleh fetch secret tiap request (latency + biaya + jejak audit berisik). Pola standar: fetch sekali di startup, cache in-memory, refresh saat rotasi terdeteksi.
import boto3, time
_cache = {"value": None, "ts": 0}
TTL_SECONDS = 300
_client = boto3.client("secretsmanager")
def get_secret(name: str) -> dict:
if _cache["value"] and time.time() - _cache["ts"] < TTL_SECONDS:
return _cache["value"]
resp = _client.get_secret_value(SecretId=name)
import json
_cache["value"] = json.loads(resp["SecretString"])
_cache["ts"] = time.time()
return _cache["value"]TTL lima menit berarti aplikasi mengikuti rotasi hampir seketika tanpa spam API. Untuk Kubernetes, pola yang sama diwakili External Secrets Operator (episode 12).
Secret bocor biasanya karena kelalaian mekanis, bukan niat jahat. Pasang tiga lapis penyaring:
#!/usr/bin/env bash
gitleaks protect --staged --redact -v || {
echo "COMMIT DITOLAK: terdeteksi kemungkinan secret."
echo "Jika false positive, tambahkan allowlist di .gitleaks.toml"
exit 1
}Aktifkan juga push protection di organisasi GitHub — ia memblokir push yang mengandung pattern token provider populer sebelum sampai ke remote.
Warning
Secret yang sudah ter-commit dianggap kompromi permanen: hapus dari riwayat Git (git filter-repo/BFG) dan rotasi nilainya. Menghapus file di commit baru tidak menghapusnya dari history — siapa pun yang punya clone lama masih memilikinya.
Inilah upgrade struktural terbesar. Alih-alih menyimpan access key di GitHub Actions secrets (yang tetap bisa dicuri dan tidak kedaluwarsa), workflow menukar token OIDC ephemeral dengan kredensial STS berumur menit.
Setup di sisi AWS: OIDC provider + role yang percaya pada repo tertentu.
{
"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",
"token.actions.githubusercontent.com:sub": "repo:acme/payments:ref:refs/heads/main"
}
}
}]
}Kondisi sub membatasi: hanya branch main dari repo acme/payments yang boleh mengambil role ini. Workflow-nya tinggal:
permissions:
id-token: write # minta token OIDC
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/deploy-ci
aws-region: ap-southeast-1
- run: aws sts get-caller-identityHasil akhirnya: tidak ada secret panjang di GitHub, kredensial hidup maksimal satu jam, scope dibatasi trust policy, dan pencurian runner tidak membawa apa pun pulang. Pola identik tersedia untuk GitLab CI, GCP Workload Identity Federation, dan Azure federated credentials.
Dua pekerjaan rutin yang menjaga sistem ini sehat:
aws iam generate-credential-report
aws iam get-credential-report --output text --query Content | base64 -d | csvcut -c user,password_last_used,access_key_1_active,access_key_1_last_used_date
aws secretsmanager list-secrets --query 'SecretList[?LastAccessedDate==null].Name'Key yang tidak dipakai lebih dari 90 hari → cabut. Secret yang tak pernah dibaca → evaluasi hapus. Posture secret adalah keadaan yang membusuk, sama seperti postur CSPM di episode 7.
Inti yang harus dibawa pulang:
Di episode 15 selanjutnya kita melebarkan cakupan lintas provider: multi-cloud security — perbedaan model IAM AWS/GCP/Azure, federation antar-cloud, sentralisasi log, dan baseline yang bisa dipertahankan tanpa tiga kali lipat effort. Sampai jumpa!