Password database, kunci API payment gateway, dan token layanan cloud adalah kunci yang membuka aset berharga — namun kebiasaan pemula justru menuliskannya langsung di dalam kode. Secret yang tertanam di source code tidak pernah benar-benar terhapus: sistem version control seperti Git menyimpan riwayat penuh, dan satu repo yang bocor membocorkan seluruh kuncinya. Chapter ini membahas cara menyimpan dan membaca secrets dengan benar di Python.
Kode Sumber Itu Bocor #
Risikonya nyata: repository di-push ke layanan publik, laptop dicuri, backup tersebar, atau mantan kontraktor menyimpan salinan. Menghapus secret pada commit berikutnya tidak menolong — commit lama tetap menyimpan nilai tersebut, dan siapa pun yang pernah menarik repo ikut menyimpannya.
Environment Variables #
Lokasi penyimpanan paling sederhana adalah environment variable: nilai hidup di proses, bukan di file kode. Module os menyediakan dua cara membacanya, dan cara kita menangani kunci yang hilang menentukan keamanan aplikasi:
import os
api_key = os.environ.get("PAYMENT_API_KEY")
if api_key is None:
print("PAYMENT_API_KEY belum diatur - aplikasi menolak berjalan")
os.environ["PAYMENT_API_KEY"] = "YOUR_API_TOKEN"
api_key = os.environ["PAYMENT_API_KEY"]
tersembunyi = "*" * (len(api_key) - 4) + api_key[-4:]
print("Token terbaca (disamarkan):", tersembunyi)Output yang Dihasilkan:
PAYMENT_API_KEY belum diatur - aplikasi menolak berjalan
Token terbaca (disamarkan): **********OKENMari kita bedah kode di atas:
- Baris 3 (
os.environ.get("PAYMENT_API_KEY")): methodget()mengembalikanNonesaat kunci tidak ada — tidak ada exception, sehingga kita wajib memeriksanya sendiri. - Baris 4-5 (
if api_key is None:): prinsip fail securely diterapkan — secret yang hilang menghentikan aplikasi, bukan membuatnya berjalan tanpa autentikasi. - Baris 9-10 (penyamaran): log tidak pernah mencetak token utuh; hanya empat karakter terakhir yang tampil agar operasional tetap bisa memverifikasi kunci mana yang aktif.
Perbedaan os.environ["KEY"] dan os.environ.get("KEY") penting: indeks langsung memunculkan KeyError saat kunci hilang, sedangkan get() membiarkan kita memilih kebijakan penanganan sendiri.
File .env dengan python-dotenv #
Mengetik puluhan environment variable di setiap sesi terminal melelahkan, sehingga timbiasa memakai package python-dotenv. File .env menyimpan pasangan kunci-nilai untuk mesin pengembang, lalu diubah menjadi environment variable saat program dijalankan:
DATABASE_URL=postgresql://budi:YOUR_DATABASE_PASSWORD@localhost/toko
PAYMENT_API_KEY=YOUR_API_TOKENFile tersebut dibaca oleh fungsi load_dotenv():
import os
from dotenv import load_dotenv
with open(".env", "w") as f: # simulasi file .env milik Anda
f.write(
"DATABASE_URL=postgresql://budi:YOUR_DATABASE_PASSWORD@localhost/toko\n"
"PAYMENT_API_KEY=YOUR_API_TOKEN\n"
)
os.environ.pop("DATABASE_URL", None)
load_dotenv()
print("DATABASE_URL :", os.environ.get("DATABASE_URL"))
print("PAYMENT_API_KEY:", os.environ.get("PAYMENT_API_KEY"))
os.remove(".env")Output yang Dihasilkan:
DATABASE_URL : postgresql://budi:YOUR_DATABASE_PASSWORD@localhost/toko
PAYMENT_API_KEY: YOUR_API_TOKENFungsi load_dotenv() membaca file .env lalu mengisi os.environ, sehingga kode aplikasi tetap membaca dari environment — tidak ada perubahan cara akses. File .env sendiri wajib masuk daftar .gitignore:
# .gitignore
.env
.env.*Dengan begitu Git tidak pernah menyimpan file tersebut. Konvensi yang lazim: komit satu file .env.example berisi nama kunci tanpa nilai, sebagai dokumentasi bagi anggota tim baru.
Token di URL Itu Bocor #
Cara pengiriman secret menentukan nasibnya juga. Token yang ditempatkan di query string ikut tercatat di access log web server, log proxy, dan riwayat browser:
def catat_akses(method, path):
# simulasi satu baris access log milik web server
print(f'192.0.2.10 - - [15/Jun/2025:10:30:00 +0700] "{method} {path}" 200')
# Token di query string ikut terekam di log server dan proxy
catat_akses("GET", "/api/orders?token=YOUR_API_TOKEN")
# Header Authorization TIDAK tercatat di access log standar
catat_akses("GET", "/api/orders (token dikirim lewat header Authorization)")Output yang Dihasilkan:
192.0.2.10 - - [15/Jun/2025:10:30:00 +0700] "GET /api/orders?token=YOUR_API_TOKEN" 200
192.0.2.10 - - [15/Jun/2025:10:30:00 +0700] "GET /api/orders (token dikirim lewat header Authorization)" 200Baris log pertama menyimpan token apa adanya; siapa pun yang bisa membaca log — operator, tool analitik, penyimpanan log pihak ketiga — ikut memegang kuncinya. Kirim kredensial lewat header Authorization, bukan query string.
Secret Manager dan Rotasi #
Untuk server produksi, environment variable punya kelemahan: nilainya terlihat oleh siapa pun yang bisa membaca proses, dan menggantinya berarti memulai ulang aplikasi. Secret manager mengatasi keduanya:
| Layanan | Bentuk | Kelebihan |
|---|---|---|
| HashiCorp Vault | Server sendiri atau SaaS | Audit trail dan dynamic secrets per aplikasi |
| AWS Systems Manager Parameter Store | Layanan AWS | Integrasi IAM dan enkripsi bawaan |
| Google Cloud Secret Manager | Layanan GCP | Versioning secret bawaan |
| Azure Key Vault | Layanan Azure | Kebijakan akses terpadu dengan Active Directory |
Dua kebiasaan menutup chapter ini. Pertama, rotasi: ganti secret secara berkala, karena umur kunci yang panjang memperpanjang masa berlaku kebocoran yang tidak kita sadari. Kedua, satu secret per kegunaan — token untuk layanan pengiriman email dan token untuk database harus berbeda, agar pencabutan satu tidak melumpuhkan yang lain. Selanjutnya kita bahas rahasia milik pengguna: password, dan mengapa menyimpannya butuh perlakuan khusus.