Skip to main content
BlogDevOps

Secret Scanning dan Mencegah Kebocoran Kredensial di GitHub

Cara mencegah rahasia masuk ke riwayat git Anda — pre-commit hook, GitHub Secret Scanning, gitleaks, dan apa yang harus dilakukan ketika Anda sudah commit kredensial.

Matthews Wong

Software Engineer

Juni 202510 menit baca
DevOps

Pada tahun 2023, GitGuardian mendeteksi 10 juta rahasia yang bocor di repositori GitHub publik — peningkatan 67% dari tahun sebelumnya. Kunci API, kata sandi database, rahasia JWT, dan kredensial cloud yang berakhir di riwayat git adalah salah satu insiden keamanan paling umum dan paling dapat dicegah dalam pengembangan perangkat lunak. Saya telah menemukan rahasia yang di-commit dua kali dalam kodebase yang saya warisi untuk pemeliharaan — keduanya kali dengan menjalankan gitleaks terhadap riwayat git lengkap. Dalam satu kasus, kata sandi database produksi aktif telah ada di riwayat git selama 14 bulan.

Mengapa Rahasia Berakhir di Git

Developer melakukan commit rahasia bukan karena mereka ceroboh tetapi karena jalur hambatan terkecil mengarah ke sana. Kredensial hardcoded dalam file konfigurasi yang di-commit. Variabel lingkungan yang disimpan dalam file .env yang tidak ada di .gitignore. Kunci API yang ditempel dalam kode 'sementara'. Rahasia dalam file YAML Kubernetes yang di-commit ke repo infrastruktur. Penyebab akarnya adalah manajemen rahasia memerlukan langkah ekstra — membaca dari lingkungan, menyiapkan manajer rahasia, mengkonfigurasi CI secrets.

GitHub Secret Scanning

GitHub Secret Scanning secara otomatis memindai repositori publik untuk pola rahasia yang diketahui (kunci AWS, token GitHub, kunci Stripe, 200+ pola) dan memberi tahu pemilik repositori ketika ditemukan. Ketika GitHub mendeteksi rahasia, ia mengirim alert di tab Security dan memberi tahu penerbit kredensial (AWS, Stripe, dll.) yang dapat secara otomatis mencabut kredensial. Ini adalah pertahanan terakhir yang bagus, tetapi hanya menangkap rahasia setelah didorong.

# Install gitleaks
brew install gitleaks
# or: go install github.com/gitleaks/gitleaks/v8@latest

# Scan full git history (run once on every repo)
gitleaks detect --source=. --log-opts="--all" --verbose

# Scan only staged files (for pre-commit hook use)
gitleaks protect --staged

# Configure with pre-commit framework
# .pre-commit-config.yaml:
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.21.2
    hooks:
      - id: gitleaks

# Install pre-commit on developer machines
pip install pre-commit
pre-commit install  # installs hooks in .git/hooks/

# Custom gitleaks config to allowlist false positives
# .gitleaks.toml:
[allowlist]
description = "Test credentials and placeholders"
regexes = [
  '''YOUR_API_KEY_HERE''',
  '''test_key_[a-z0-9]{8}''',
  '''REPLACE_WITH_ACTUAL_KEY''',
]
paths = [
  '''tests/fixtures/''',
  '''docs/examples/''',
]

# GitHub Actions: block PRs with secrets
# .github/workflows/security.yml:
name: Secret Scanning
on: [push, pull_request]
jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # full history needed
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Dari pengalaman saya mengelola beberapa repositori: konfigurasikan gitleaks sebagai pre-commit hook di semua repositori menggunakan konfigurasi pre-commit seluruh perusahaan. Saya menggunakan framework pre-commit dengan hook gitleaks yang didefinisikan dalam .pre-commit-config.yaml bersama yang diwarisi semua proyek. Ini menangkap rahasia sebelum di-commit, bukan setelah didorong.

Pre-Commit Secret Scanning dengan gitleaks

Gitleaks adalah alat open-source yang memindai repositori git untuk rahasia menggunakan pola regex. Install sebagai pre-commit hook untuk memblokir commit yang berisi rahasia. Alat ini menangkap kunci akses AWS, kunci RSA privat, token GitHub, string koneksi database, rahasia JWT, dan 100+ pola lainnya.

Konfigurasi Gitleaks

Konfigurasikan gitleaks untuk memindai seluruh diff commit sebelum melakukan commit. Tambahkan ke konfigurasi framework pre-commit Anda. Untuk repositori dengan kredensial uji yang sah (kunci API uji yang sengaja ada dalam fixture), gunakan konfigurasi allowlist untuk memper-whitelist string atau pola file tertentu.

Jika rahasia sudah di-commit ke riwayat git: langkah 1, segera rotasi kredensial — asumsikan sudah dikompromikan bahkan jika repo bersifat privat. Rotasi tidak dapat dinegosiasikan. Langkah 2, hapus rahasia dari riwayat menggunakan git-filter-repo. Langkah 3, force push riwayat yang ditulis ulang dan beri tahu semua anggota tim untuk reclone. Langkah 4, periksa alert GitHub Secret Scanning. Langkah 5, audit log akses untuk kredensial yang bocor.

Manajemen Rahasia Infrastruktur dan CI/CD

Untuk pipeline CI/CD: jangan pernah hardcode rahasia dalam file workflow. Gunakan rahasia GitHub Actions (terenkripsi, tidak terlihat dalam log), atau manajer rahasia yang tepat. Untuk Kubernetes: gunakan Kubernetes Secrets, atau gunakan External Secrets Operator dengan Vault, AWS Secrets Manager, atau GCP Secret Manager sebagai backend. Untuk rahasia aplikasi dalam produksi: gunakan variabel lingkungan yang disuntikkan oleh platform deployment Anda.

# Remove a secret from git history using git-filter-repo
# Install: pip install git-filter-repo

# STEP 1: Rotate the credential FIRST — assume it's compromised
# (AWS, Stripe, GitHub, database — all of them)

# STEP 2: Remove the file from history
git filter-repo --path .env --invert-paths
# Or remove a specific string pattern:
git filter-repo --replace-text <(echo 'sk-abc123==>REDACTED')

# STEP 3: Force push rewritten history (coordinate with team first!)
git push origin --force --all
git push origin --force --tags

# STEP 4: Notify all team members to re-clone
# Old clones have the secret in their local history

# STEP 5: Verify on GitHub
# Check Security → Secret Scanning alerts — confirm no active alerts

# STEP 6: Check access logs for the leaked credential
# AWS: CloudTrail → filter by AccessKeyId
# Stripe: Dashboard → Developers → Logs → filter by API key
# Database: PostgreSQL log_connections + pg_audit for credential use

Memindai Riwayat Repositori yang Ada

Jalankan gitleaks pada riwayat lengkap setiap repositori yang ada sebagai audit satu kali: `gitleaks detect --source=. --log-opts='--all'`. Ini memindai semua commit, bukan hanya yang terbaru. Jalankan di setiap repo sebelum menambahkan pre-commit hook — Anda perlu mengetahui baseline Anda. Perlakukan temuan sebagai insiden: rotasi setiap kredensial yang ditemukan, terlepas dari seberapa lama commit tersebut.

Defense-in-Depth untuk Rahasia

Keamanan rahasia berlapis saya: (1) Workstation developer: pre-commit gitleaks hook menangkap rahasia sebelum commit. (2) Pipeline CI/CD: gitleaks berjalan sebagai pemeriksaan PR di GitHub Actions, memblokir merge jika rahasia terdeteksi. (3) Tingkat repositori: GitHub Secret Scanning diaktifkan di semua repo. (4) Infrastruktur: rahasia disimpan di Vault atau manajer rahasia cloud. (5) Kebijakan rotasi: semua rahasia memiliki kebijakan rotasi maksimum 90 hari. (6) Audit logging: semua akses rahasia dicatat.

Artikel Terkait

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Mengapa GitHub Secret Scanning hanya berfungsi sebagai pertahanan terakhir, dan apa yang sebaiknya digunakan tim sebagai gantinya?

GitHub Secret Scanning hanya mendeteksi rahasia setelah sudah didorong ke repositori, artinya kredensial sudah terekspos saat alert baru muncul. Post ini merekomendasikan penggunaan gitleaks sebagai pre-commit hook agar rahasia tertangkap sebelum masuk ke riwayat git. Pendekatan berlapis — pre-commit hook, pemeriksaan PR di CI/CD, dan Secret Scanning di tingkat repositori — memberikan perlindungan terkuat.

Apa langkah pertama yang harus dilakukan ketika rahasia sudah terlanjur di-commit ke riwayat git?

Langkah pertama adalah segera merotasi kredensial yang bocor, terlepas dari apakah repositori bersifat privat atau tidak. Post ini menegaskan bahwa rotasi tidak dapat dinegosiasikan dan kredensial harus dianggap sudah dikompromikan. Baru setelah rotasi, rahasia dihapus dari riwayat menggunakan git-filter-repo dan riwayat yang ditulis ulang di-force push.

Bagaimana gitleaks menangani kredensial uji yang memang sengaja ada dalam kodebase?

Gitleaks mendukung konfigurasi allowlist yang memungkinkan tim mem-whitelist string atau pola file tertentu, sehingga kunci API uji dalam fixture tidak memicu false positive. Pola bawaan alat ini sudah cukup spesifik sehingga nilai placeholder seperti 'YOUR_API_KEY_HERE' tidak ikut terflag. Pola kustom untuk format rahasia internal perusahaan juga bisa ditambahkan melalui file konfigurasi gitleaks.toml.

Bagaimana tim bisa mengaudit rahasia yang di-commit jauh sebelum pre-commit hook ditambahkan?

Post ini merekomendasikan menjalankan `gitleaks detect --source=. --log-opts='--all'` terhadap riwayat git lengkap setiap repositori yang ada sebagai audit satu kali sebelum pre-commit hook dipasang. Perintah ini memindai semua commit, bukan hanya yang terbaru, dan membangun baseline keamanan. Setiap kredensial yang ditemukan harus segera dirotasi karena kunci API lama sering kali masih aktif.

Apa pendekatan manajemen rahasia yang direkomendasikan untuk Kubernetes dan pipeline CI/CD?

Untuk pipeline CI/CD, rahasia harus disimpan sebagai GitHub Actions secrets yang terenkripsi dan tidak terlihat dalam log, bukan di-hardcode dalam file workflow. Untuk Kubernetes, post ini merekomendasikan External Secrets Operator dengan backend Vault, AWS Secrets Manager, atau GCP Secret Manager, karena Kubernetes Secrets berbasis base64 tidak terenkripsi secara default. Rahasia aplikasi di produksi sebaiknya disuntikkan sebagai variabel lingkungan oleh platform deployment.