Jawaban singkatnya: API key CaptchaAI tidak boleh berada di dalam file kode. Simpan di environment variable, baca lewat os.environ atau process.env, dan pastikan file .env sudah masuk .gitignore sebelum commit pertama. Sisa artikel ini menunjukkan pola yang sama untuk development lokal, Docker, dan pipeline CI/CD.
Polanya di lapangan hampir selalu sama: proyek scraping dikerjakan cepat untuk klien, key ditempel langsung di scraper.py supaya bisa jalan hari itu juga, lalu repo di-push ke GitHub sebagai portofolio. Key itu kini ada di riwayat commit, dan menghapus barisnya di commit berikutnya tidak menghapus apa pun.
Kenapa hardcode API key selalu berakhir mahal
Ada tiga jalur kebocoran yang sama-sama umum, dan ketiganya tertutup oleh satu kebiasaan yang sama:
- Kontrol versi. Key yang pernah masuk Git tetap terbaca dari riwayat, termasuk dari fork dan clone yang sudah tersebar ke mesin orang lain.
- Log dan pesan error.
print(config)atau traceback yang ikut membawa isi variabel akan mengirim key Anda ke agregator log, tempat aksesnya biasanya jauh lebih longgar daripada repo. - Image container. Key yang ditulis di
Dockerfileikut terpanggang ke dalam layer image; siapa pun yang bisa menarik image itu bisa membacanya kembali.
Environment variable memisahkan tanggung jawab: kode berisi logika, environment berisi rahasia.
Efek sampingnya praktis — Anda bisa memakai key berbeda untuk staging dan produksi tanpa mengubah satu baris kode pun.
Langkah 1: file .env untuk development lokal
Buat file .env di root proyek:
CAPTCHAAI_API_KEY=your_actual_api_key_here
Masukkan ke .gitignore sekarang juga, bukan nanti:
# .gitignore
.env
.env.local
.env.production
Python (python-dotenv)
pip install python-dotenv
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
# Use in API calls
import requests
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "6Le-SITEKEY",
"pageurl": "https://example.com",
"json": "1",
})
print(resp.json())
Perhatikan os.environ["CAPTCHAAI_API_KEY"] dengan tanda kurung siku: bentuk ini langsung melempar error ketika variabelnya tidak ada, jadi proses berhenti di awal alih-alih mengirim request tanpa key.
JavaScript (dotenv)
npm install dotenv
require('dotenv').config();
const API_KEY = process.env.CAPTCHAAI_API_KEY;
if (!API_KEY) {
console.error('CAPTCHAAI_API_KEY not set');
process.exit(1);
}
// Use in API calls
const axios = require('axios');
const resp = await axios.post('https://ocr.captchaai.com/in.php', null, {
params: {
key: API_KEY,
method: 'userrecaptcha',
googlekey: '6Le-SITEKEY',
pageurl: 'https://example.com',
json: 1,
},
});
console.log(resp.data);
Polanya sama untuk Node.js: baca sekali di titik masuk aplikasi, lalu hentikan proses jika nilainya kosong.
Langkah 2: environment variable di level sistem operasi
| Tempat kode berjalan | Cara menaruh key yang masuk akal |
|---|---|
| Laptop developer | File .env plus .gitignore |
| Server atau worker permanen | Variabel di level OS |
| Container dan pipeline CI/CD | Secret milik platform, di-inject saat runtime |
Linux/macOS
export CAPTCHAAI_API_KEY="your_actual_api_key_here"
# Persist across sessions — add to ~/.bashrc or ~/.zshrc
echo 'export CAPTCHAAI_API_KEY="your_actual_api_key_here"' >> ~/.bashrc
Windows (PowerShell)
$env:CAPTCHAAI_API_KEY = "your_actual_api_key_here"
# Persist permanently
[System.Environment]::SetEnvironmentVariable("CAPTCHAAI_API_KEY", "your_actual_api_key_here", "User")
Langkah 3: Docker, Docker Compose, dan Docker secrets
Mengirim variabel lewat docker run
docker run -e CAPTCHAAI_API_KEY="your_key" my-scraper
Docker Compose
# docker-compose.yml
services:
scraper:
image: my-scraper
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
${CAPTCHAAI_API_KEY}merujuk ke environment variable milik host, bukan ke nilai yang ditulis di file.- File compose boleh ikut masuk repo; key-nya tetap tinggal di mesin yang menjalankan
docker compose up.
Docker secrets (mode Swarm)
Untuk cluster, Docker secrets lebih rapat daripada environment variable biasa karena nilainya di-mount sebagai file dan tidak ikut muncul di docker inspect:
echo "your_actual_api_key_here" | docker secret create captchaai_key -
# docker-compose.yml (Swarm mode)
services:
scraper:
image: my-scraper
secrets:
- captchaai_key
secrets:
captchaai_key:
external: true
Baca dari dalam kode:
with open("/run/secrets/captchaai_key") as f:
API_KEY = f.read().strip()
Langkah 4: pipeline CI/CD
GitHub Actions
# .github/workflows/scrape.yml
jobs:
scrape:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: python scraper.py
env:
CAPTCHAAI_API_KEY: ${{ secrets.CAPTCHAAI_API_KEY }}
- Buka repo di GitHub, masuk ke Settings -> Secrets and variables -> Actions.
- Klik New repository secret, beri nama
CAPTCHAAI_API_KEY. - Tempel nilainya dan simpan; setelah itu nilainya tidak bisa dibaca lagi dari UI.
GitLab CI
# .gitlab-ci.yml
scrape:
script:
- python scraper.py
variables:
CAPTCHAAI_API_KEY: $CAPTCHAAI_API_KEY
- Tambahkan variabelnya di Settings -> CI/CD -> Variables.
- Aktifkan opsi "Masked" supaya nilainya tersamarkan di output job.
- Batasi ke branch terlindungi bila runner-nya dipakai bersama tim lain.
Langkah 5: validasi key saat startup
Kegagalan yang paling mahal adalah pipeline yang jalan setengah jam lalu berhenti karena key-nya salah.
Periksa keberadaan dan validitas key sebelum task pertama dikirim:
import os
import sys
import requests
API_KEY = os.environ.get("CAPTCHAAI_API_KEY")
if not API_KEY:
print("ERROR: CAPTCHAAI_API_KEY environment variable not set")
sys.exit(1)
# Verify key works
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "getbalance", "json": "1"
}).json()
if resp["status"] != 1:
print(f"ERROR: Invalid API key — {resp['request']}")
sys.exit(1)
print(f"API key valid — balance: ${float(resp['request']):.2f}")
- Pemanggilan
res.phpdenganaction=getbalancecukup ringan untuk dijalankan di awal setiap run. - Hasilnya sekaligus memberi tahu sisa saldo sebelum antrean task menumpuk.
Memakai beberapa key dalam satu proyek
Tim yang menangani beberapa klien sekaligus biasanya memisahkan key per proyek agar pemakaian mudah ditelusuri. Satu variabel berisi daftar key sudah cukup untuk itu:
CAPTCHAAI_KEYS=key1,key2,key3
keys = os.environ["CAPTCHAAI_KEYS"].split(",")
Pemisahan ini menyelamatkan Anda saat satu key harus dicabut: proyek lain tetap berjalan.
Kesalahan umum
| Kesalahan | Risiko | Perbaikan |
|---|---|---|
Commit .env ke Git |
Key terekspos di riwayat repo selamanya | Tambahkan .env ke .gitignore sebelum commit pertama |
| Mencetak API key ke log | Key terbaca siapa pun yang punya akses ke agregator log | Jangan pernah mencatat key utuh — samarkan atau hilangkan |
Menulis key di Dockerfile |
Key ikut terpanggang ke dalam layer image | Pakai ENV saat runtime, bukan di tahap build |
| Mengirim key lewat chat atau email | Key tersimpan di riwayat percakapan pihak lain | Pakai secrets manager atau kanal yang terenkripsi |
| Satu key dipakai staging dan produksi | Key sulit dicabut tanpa mematikan produksi | Pisahkan key per environment sejak awal |
Contoh penerapan: tim scraping kecil dengan dua environment
Bayangkan agensi kecil di Jakarta dengan tiga developer yang menjalankan monitoring harga untuk beberapa klien. Worker-nya berjalan sebagai container di region ap-southeast-1 (Singapura), pengujiannya di laptop masing-masing.
Susunan yang praktis: satu key staging di .env lokal setiap developer, dan satu key produksi yang hanya ada di secret manager penyedia cloud lalu di-inject ke container saat deploy. Repo cukup berisi .env.example dengan nama variabelnya saja, tanpa nilai.
Ketika seorang kontraktor freelance selesai bekerja, yang perlu dicabut hanya key staging — produksi tidak tersentuh.
Dua environment tidak berarti dua tagihan: paket CaptchaAI dihitung per thread yang berjalan bersamaan, bukan per CAPTCHA. Paket BASIC ($15/bulan, 5 thread) mencakup penyelesaian tanpa batas selama bulan berjalan, jadi yang direncanakan adalah jumlah thread serentak — rinciannya ada di halaman resmi CaptchaAI.
Catatan kepatuhan: UU Pelindungan Data Pribadi (UU 27/2022) menuntut standar penyimpanan yang sama untuk credential maupun data hasil pengambilan — proses hanya data yang Anda berwenang memprosesnya.
Pertanyaan umum
Di mana sebaiknya key disimpan setelah aplikasi masuk produksi?
Di secret manager milik platform Anda — AWS Secrets Manager, Google Secret Manager, atau Azure Key Vault — lalu di-inject sebagai environment variable saat container atau fungsi dijalankan.
File .env cocok untuk mesin developer, bukan untuk server produksi yang diakses banyak orang.
Bagaimana memastikan API key tidak bocor lewat log atau pesan error?
- Jangan pernah mengirim objek konfigurasi utuh ke dalam log.
- Bila butuh jejak untuk debugging, cetak empat karakter terakhir saja, misalnya
...a91f. - Periksa handler exception Anda: traceback yang memuat seluruh parameter request adalah jalur kebocoran yang paling sering terlewat.
Apakah satu API key bisa dipakai beberapa server sekaligus?
Bisa. Kapasitas Anda ditentukan oleh jumlah thread yang berjalan bersamaan, bukan oleh jumlah mesin, sehingga beberapa worker boleh memakai key yang sama selama total thread aktif masih di dalam batas paket. Untuk keperluan audit dan pencabutan, memisahkan key per environment tetap lebih rapi.
Environment variable saya kosong saat container berjalan — apa penyebabnya?
- File
.envtidak ikut ke dalam image — memang seharusnya tidak; pakai-eatau compose. - Nama variabel di host berbeda tipis dari yang dibaca kode.
- Variabel hanya disetel di shell interaktif dan tidak diteruskan ke proses anak.
Key saya sudah terlanjur ter-commit — apa langkah pertamanya?
Putar key dari dashboard CaptchaAI lebih dulu, baru bereskan riwayat repo. Urutannya penting: selama key lama masih aktif, membersihkan riwayat Git tidak membuat key tersebut berhenti bekerja bagi siapa pun yang sudah menyalinnya.
Amankan integrasi CaptchaAI Anda sejak commit pertama
Buat akun dan ambil API key Anda di captchaai.com.