Manajemen Secret dengan Claude Code: dari .env sampai rotasi produksi
Panduan menjaga .env, secret CI/CD, key cloud, log redacted, dan batas izin Claude Code.
API key, URL database, OAuth client secret, dan kredensial deploy cloud dibutuhkan oleh aplikasi nyata. Nilai-nilai yang sama juga mudah tertinggal di Git history, log CI, screenshot, tiket, README, atau draf artikel setelah satu kali copy-paste yang ceroboh. Saat memakai Claude Code untuk debugging, migrasi, deployment, atau dokumentasi, aturan pertama harus jelas: Claude Code boleh membantu membangun sistem yang aman, tetapi tidak boleh melihat, mencetak, menyimpan, atau memakai ulang nilai secret asli.
Manajemen secret bukan hanya menyimpan password di brankas. Ini adalah cara operasi untuk memisahkan konfigurasi dari kode, membedakan local, development, staging, dan production, menerapkan least privilege, memvalidasi konfigurasi saat startup, meredaksi log, dan menyiapkan rotasi sebelum terjadi insiden. Prinsip config dari The Twelve-Factor App masih tepat: konfigurasi berasal dari environment, bukan hard-code di repository. Dalam praktik, Anda juga memerlukan .gitignore, .env.example, config loader dengan validasi, CI/CD secrets, secret store cloud, dan checklist rotasi.
flowchart LR
Dev["Local .env"] --> Loader["Validated config loader"]
CI["CI/CD secrets"] --> Deploy["Deployment runtime"]
Store["AWS / GCP / Azure secret store"] --> Deploy
Deploy --> App["Application process"]
App --> Logs["Redacted logs"]
1. Tentukan apa yang disimpan di mana
Kesalahan pemula adalah memperlakukan semua environment variable dengan level risiko yang sama. Ujiannya sederhana: jika sebuah nilai bocor dan orang lain bisa menghabiskan uang, mengirim email, membaca data, menulis data, deploy kode, atau menyamar sebagai user, perlakukan sebagai secret. Public base URL, nama feature flag, dan OAuth client ID biasanya kurang sensitif karena tidak memberi izin sendirian.
| Use case | Contoh | Local development | Production |
|---|---|---|---|
| Email dan integrasi API | SendGrid API key, Stripe secret key, GitHub token | Pakai key test atau sandbox di .env | Inject dari CI/CD secrets atau secret store |
| Database | DATABASE_URL, user, password | User lokal atau khusus dev | Pisahkan read/write dan rotasi password |
| Deploy cloud | Kredensial AWS/GCP/Azure | Hindari key lokal jangka panjang | Pakai OIDC atau role khusus deploy |
| OAuth dan webhook | OAUTH_CLIENT_SECRET, webhook signing secret | Buat app lokal terpisah | Secret prod di luar repo |
Pemisahan environment adalah inti. Jangan pakai ulang Stripe production key di lokal. Jangan taruh GitHub token pribadi dengan akses organisasi luas di CI. Jangan beri hak administrator pada credential yang hanya perlu deploy. Least privilege berarti memberi scope minimum, di environment yang tepat, dan sebisa mungkin dengan masa berlaku terbatas.
2. Commit bentuknya, bukan nilainya
.env berguna untuk kerja lokal, tetapi tidak boleh masuk Git. Repository sebaiknya menyimpan .env.example, berisi nama variable, format, sumber, dan tujuan. Untuk onboarding, gabungkan dengan panduan environment management agar developer baru tidak perlu bertanya satu per satu.
# Local secrets
.env
.env.*
!.env.example
!.env.test.example
# Logs and generated output that may contain tokens
npm-debug.log*
yarn-debug.log*
coverage/
dist/
# .env.example - placeholders only, never real values
NODE_ENV=development
APP_BASE_URL=http://localhost:3000
# Use a local database user, not production credentials.
DATABASE_URL=postgres://app_user:replace-me@localhost:5432/app_dev
# Use test/sandbox keys for local development.
SENDGRID_API_KEY=SG.xxxxxx
STRIPE_SECRET_KEY=sk_test_xxxxxx
GITHUB_TOKEN=ghp_xxxxxx
# OAuth secrets must be separated by environment.
OAUTH_CLIENT_ID=local-client-id
OAUTH_CLIENT_SECRET=replace-me
# Deployment reads these from CI or a cloud secret store.
AWS_REGION=ap-northeast-1
DEPLOY_ROLE_ARN=arn:aws:iam::123456789012:role/app-deploy-dev
Saat melibatkan Claude Code, tulis batasnya secara eksplisit. Ia boleh membaca .env.example, manifest deploy, package scripts, dan nama variable; ia tidak boleh membuka .env, menyalin nilai asli ke chat, atau menulis credential ke dokumentasi. Jika implementasi membutuhkan nilai asli, Anda yang mengatur di lokal, CI, atau secret store. Claude Code cukup tahu nama variablenya.
3. Validasi saat startup dan redaksi log
Aplikasi sebaiknya gagal cepat jika secret wajib hilang atau formatnya salah. Aplikasi juga harus mencegah token tercetak saat debugging. Loader Node.js berikut memakai dotenv dan envalid untuk validasi, serta menyediakan redactConfig untuk log, health check, dan output support.
import { config as loadDotenv } from "dotenv";
import { cleanEnv, str, url } from "envalid";
const envFile = process.env.NODE_ENV === "test" ? ".env.test" : ".env";
loadDotenv({ path: envFile });
const secretKeyPattern = /(KEY|TOKEN|SECRET|PASSWORD|DATABASE_URL|PRIVATE)/i;
const env = cleanEnv(process.env, {
NODE_ENV: str({
choices: ["development", "test", "staging", "production"],
default: "development",
}),
APP_BASE_URL: url({ default: "http://localhost:3000" }),
DATABASE_URL: url(),
SENDGRID_API_KEY: str(),
STRIPE_SECRET_KEY: str(),
GITHUB_TOKEN: str(),
OAUTH_CLIENT_ID: str(),
OAUTH_CLIENT_SECRET: str(),
AWS_REGION: str({ default: "ap-northeast-1" }),
DEPLOY_ROLE_ARN: str(),
});
export function appConfig() {
return Object.freeze({
nodeEnv: env.NODE_ENV,
appBaseUrl: env.APP_BASE_URL,
databaseUrl: env.DATABASE_URL,
sendgridApiKey: env.SENDGRID_API_KEY,
stripeSecretKey: env.STRIPE_SECRET_KEY,
githubToken: env.GITHUB_TOKEN,
oauthClientId: env.OAUTH_CLIENT_ID,
oauthClientSecret: env.OAUTH_CLIENT_SECRET,
awsRegion: env.AWS_REGION,
deployRoleArn: env.DEPLOY_ROLE_ARN,
});
}
export function redactValue(key, value) {
if (!secretKeyPattern.test(key)) return value;
if (!value) return "<empty>";
const text = String(value);
if (text.length <= 8) return "<redacted>";
return `${text.slice(0, 4)}...${text.slice(-4)}`;
}
export function redactConfig(config) {
return Object.fromEntries(
Object.entries(config).map(([key, value]) => [key, redactValue(key, value)]),
);
}
if (process.argv[1] === new URL(import.meta.url).pathname) {
console.log(redactConfig(appConfig()));
}
Kegagalan yang sering terjadi adalah menambahkan console.log(process.env) saat insiden lalu menempelkan log CI ke tiket atau chat. Jika Claude Code diminta merangkum log mentah itu, secret bisa muncul lagi di test, docs, atau artikel. Redaksi dulu, baru minta bantuan. Screenshot juga harus dipotong atau diblur sebelum diunggah.
4. Beri batas izin yang jelas untuk Claude Code
Claude Code hampir tidak pernah membutuhkan nilai asli. Ia membutuhkan nama, format, error yang sudah disamarkan, dan tujuan permission. Tempelkan boundary prompt berikut di awal tugas security, deploy, atau debugging.
You may inspect .env.example, package.json, deployment manifests, and secret names.
Do not open, print, summarize, store, or copy .env, CI/CD secret values, cloud credentials, production dumps, or screenshots containing tokens.
When you need a value, ask me to set it outside chat and confirm only the variable name.
If a secret appears in command output, stop, redact it, and report which file or command exposed it.
Before changing permissions, explain the least-privilege scope and ask for approval.
Do not paste real secrets into prompts, logs, documentation, code comments, tests, tickets, or articles.
Batasi perintah juga. printenv, cat .env, CLI cloud yang menampilkan credential, dump log CI lengkap, dan screenshot harus memerlukan konfirmasi. Dengan .env.example, type, error yang sudah diredaksi, dan dokumentasi resmi, Claude Code bisa menyelesaikan sebagian besar perbaikan tanpa melihat nilai asli.
5. Gunakan CI/CD secrets dan secret store cloud dengan sadar
Pembagian yang praktis: .env untuk lokal, CI/CD secrets untuk pipeline, dan secret store cloud untuk runtime produksi. Di AWS, gunakan AWS Secrets Manager. Di Google Cloud, Secret Manager. Di Azure, Key Vault. Untuk repository GitHub, aktifkan secret scanning agar token bocor cepat terdeteksi.
name: deploy
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
env:
NODE_ENV: production
AWS_REGION: ap-northeast-1
steps:
- uses: actions/checkout@v4
- name: Validate required secret names
run: test -n "${{ secrets.DEPLOY_ROLE_ARN }}" && test -n "${{ secrets.DATABASE_URL }}"
- name: Deploy without echoing secrets
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DEPLOY_ROLE_ARN: ${{ secrets.DEPLOY_ROLE_ARN }}
run: npm run deploy
Jebakan CI adalah “echo dulu untuk cek”. GitHub Actions memang menyamarkan banyak nilai secret yang cocok persis, tetapi tidak selalu melindungi string turunan, URL yang di-encode, JSON, screenshot, atau nilai yang tidak terdaftar sebagai secret. Minta Claude Code menampilkan nama variable dan langkah validasi, bukan nilainya. Jika ia menyarankan permission luas, minta alasan dan perkecil scope.
6. Rotasi sebelum terpaksa
Rotasi harus menjadi maintenance rutin, bukan hanya respons insiden. SendGrid, Stripe, GitHub token, password database, OAuth client secret, webhook signing secret, dan cloud trust policy perlu owner, environment, daftar consumer, tanggal rotasi terakhir, dan tanggal review berikutnya.
## Secret rotation checklist
- [ ] Identify owner, environment, consumers, and business impact.
- [ ] Create a new secret with the smallest required scope.
- [ ] Store it in CI/CD secrets or the cloud secret store.
- [ ] Deploy one service or job with the new value.
- [ ] Confirm logs and metrics without printing the secret.
- [ ] Revoke the old secret.
- [ ] Scan Git history, tickets, docs, screenshots, and chat snippets.
- [ ] Record the rotation date and next review date.
Claude Code berguna untuk mengubah daftar ini menjadi issue template, runbook, atau rencana migrasi. Jangan berikan key lama atau key baru. Minta seperti ini: “Cari semua referensi SENDGRID_API_KEY dan buat rencana rollout aman untuk key v2.”
7. Cek failure case sebelum publish
Hentikan publish atau deploy jika salah satu ini terjadi:
.envatau.env.productionpernah di-commit dan key yang bocor belum dicabut.- Screenshot, log CI, error report, atau contoh artikel berisi token, DB URL, atau OAuth secret.
- Key cloud punya izin administrator padahal deploy-only cukup.
- Credential produksi Stripe, SendGrid, database, atau GitHub dipakai ulang di lokal.
- OAuth client secret atau webhook signing secret tidak punya owner dan runbook rotasi.
- AI diberi nilai asli lalu menulisnya lagi di README, test, tiket, atau draf.
Insiden security sering muncul dari celah proses. Gunakan security audit checklist, pelajari security failure cases, hubungkan dengan API development guide, dan untuk SendGrid atau email transaksional baca artikel email automation.
8. Rollout ke tim secara bertahap
Jangan mulai dengan memindahkan semua service ke secret store dalam satu minggu. Pilih satu aplikasi dan buat jalur lengkap: .gitignore, .env.example, loader tervalidasi, log redacted, CI/CD secrets, secret store produksi, dan catatan rotasi. Setelah itu migrasikan tipe yang sering muncul: SendGrid, Stripe, GitHub token, DATABASE_URL, OAuth client secret, dan credential deploy.
Training dan consulting ClaudeCodeLab memakai bentuk repository Anda yang sebenarnya, tetapi tidak menerima nilai secret asli. Kami memetakan file mana yang boleh dilihat Claude Code, merancang batas CI/CD secrets, mengaktifkan GitHub secret scanning, merencanakan secret store AWS/GCP/Azure, dan meninggalkan prompt serta runbook yang bisa dipakai ulang. Tim bisa langsung menggunakannya di code review hari berikutnya.
Ringkasnya, manajemen secret bukan sekadar menyembunyikan string. Ini tentang memisahkan nilai dari kode, mengisolasi environment, validasi saat startup, meredaksi log, memperkecil permission, dan melatih rotasi. Claude Code dapat membantu membangun dan mereview sistem itu, tetapi tidak boleh menjadi tempat baru untuk menyalin secret.
Saat diuji di aplikasi Node.js contoh milik Masa, config loader menemukan nilai yang hilang, redactConfig menjaga URL database dan API key tetap keluar dari log CI, dan workflow deploy tidak lagi membutuhkan permission write yang luas. Temuan yang mengejutkan adalah screenshot lama yang masih menampilkan Stripe test key, sehingga key diterbitkan ulang sebelum publikasi. Pelajarannya jelas: review log, gambar, dan draf dengan kecurigaan yang sama seperti source code.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission safety ladder Claude Code: perluas akses tanpa kehilangan kontrol
Naik dari read-only ke edit terbatas, command bukti, dan cek deploy dengan kontrol yang jelas.
Claude Code Small PR Proof Pack: perubahan kecil yang mudah direview
Paket bukti untuk PR Claude Code: diff, check, URL publik, jalur CTA, dan rollback.
Review gate Claude Code sebelum commit: diff, test, URL publik, dan CTA
Cara memakai Claude Code sebelum commit: diff scope, build, URL publik, link Gumroad, CTA konsultasi, missing test, dan file tidak terkait.