Bayangkan tim automation kecil di Jakarta yang tanpa sengaja mengunggah API key CaptchaAI ke repository GitHub publik. Dalam hitungan jam, saldo mereka terkuras oleh permintaan solve yang bukan berasal dari server mereka sendiri, dan mereka baru sadar setelah dashboard menunjukkan saldo mendekati nol. Skenario ini jauh lebih umum daripada yang dibayangkan kebanyakan developer, dan penyebabnya nyaris selalu sama: API key disimpan atau dikirim di tempat yang salah.
Panduan ini membahas cara menyimpan, merotasi, memvalidasi, dan membatasi akses API key CaptchaAI Anda — termasuk mengaktifkan IP whitelist untuk server production.
Kenapa API Key CaptchaAI Rawan Bocor
API key adalah satu-satunya kredensial yang dicek CaptchaAI sebelum menerima permintaan solve. Siapa pun yang memegangnya bisa memakai saldo Anda, dan di hampir semua tim key bocor lewat jalur yang sama:
Exposed API key:
├── Leaked in Git repository
├── Hardcoded in client-side code
├── Shared in documentation
└── Visible in logs
Impact:
├── Balance drained by unauthorized users
├── Usage spikes from abuse
└── Key disabled by service provider
Dampaknya terasa cepat: saldo terkuras oleh pemakaian yang bukan milik Anda, lonjakan traffic yang sulit dilacak sumbernya, sampai key dinonaktifkan otomatis karena polanya dianggap mencurigakan.
Simpan API Key di Tempat yang Aman
Aturan paling dasar: API key tidak boleh pernah menyentuh source code yang berpotensi ter-commit ke Git.
Jangan Hardcode API Key ke Source Code
Hardcode terasa praktis saat development, tapi begitu file itu ter-commit, key sudah tercatat permanen di riwayat Git — bahkan setelah dihapus dari commit terbaru. Muat key dari environment variable:
# BAD — key in source code
API_KEY = "abc123def456" # DO NOT DO THIS
# GOOD — environment variable
import os
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
# GOOD — .env file (not committed to Git)
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
Simpan Konfigurasi di File .env
File .env memisahkan rahasia dari kode, tapi hanya aman kalau file ini tidak pernah ikut ter-commit:
# .env (add to .gitignore!)
CAPTCHAAI_API_KEY=your_api_key_here
Pastikan .gitignore Menutup Semua Varian .env
Satu baris .gitignore yang terlewat cukup untuk membuat key bocor ke publik. Cakup semua varian file environment sejak awal proyek:
# Always ignore .env files
.env
.env.local
.env.production
Muat Konfigurasi CaptchaAI dari Environment Variable
Daripada memanggil os.environ di banyak tempat berbeda, kumpulkan logic pengambilan dan validasi key dalam satu class kecil yang langsung mengecek key lewat action=getbalance di res.php:
import os
class CaptchaConfig:
"""Load CaptchaAI config from environment."""
def __init__(self):
self.api_key = os.environ.get("CAPTCHAAI_API_KEY")
if not self.api_key:
raise EnvironmentError(
"CAPTCHAAI_API_KEY not set. "
"Set it in your environment or .env file."
)
self.base_url = os.environ.get(
"CAPTCHAAI_URL", "https://ocr.captchaai.com"
)
def validate(self):
"""Verify the API key works."""
import requests
resp = requests.get(f"{self.base_url}/res.php", params={
"key": self.api_key,
"action": "getbalance",
"json": 1,
}, timeout=10)
data = resp.json()
if data.get("status") != 1:
raise RuntimeError(f"Invalid API key: {data.get('request')}")
return float(data["request"])
# Usage
config = CaptchaConfig()
balance = config.validate()
print(f"Key valid, balance: ${balance:.2f}")
Kalau CAPTCHAAI_API_KEY belum di-set, aplikasi langsung gagal saat start-up — bukan baru ketahuan di tengah proses solve.
Jadwalkan Rotasi API Key Secara Berkala
Semakin lama sebuah key hidup, semakin banyak tempat ia sempat tersimpan — laptop lama, log CI, screenshot dokumentasi internal. Rotasi key secara berkala, dan siapkan key kedua sebagai fallback:
import os
import datetime
class KeyManager:
"""Manage API key rotation."""
def __init__(self):
self.primary_key = os.environ.get("CAPTCHAAI_API_KEY")
self.secondary_key = os.environ.get("CAPTCHAAI_API_KEY_BACKUP")
self.active_key = self.primary_key
def get_key(self):
return self.active_key
def rotate(self):
"""Switch to secondary key."""
if self.secondary_key:
self.active_key = self.secondary_key
print("Rotated to secondary key")
else:
print("No secondary key configured")
def test_key(self, key):
"""Verify a key is valid."""
import requests
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": key, "action": "getbalance", "json": 1,
}, timeout=10)
return resp.json().get("status") == 1
# Usage
keys = KeyManager()
# If primary fails, rotate to secondary
if not keys.test_key(keys.get_key()):
keys.rotate()
Pola yang sama berlaku untuk pemisahan lingkungan: pakai key berbeda untuk development, staging, dan production, supaya key dev yang bocor tidak pernah menyentuh traffic production.
Validasi Parameter Sebelum Mengirim Request
Validasi input sebelum request dikirim mencegah kesalahan konfigurasi yang sering memicu debugging panjang dan percobaan ulang sia-sia:
import requests
import logging
logger = logging.getLogger(__name__)
class SecureSolver:
"""Solver with security best practices."""
def __init__(self, api_key):
self.api_key = api_key
self.base = "https://ocr.captchaai.com"
def solve(self, method, **params):
# Validate inputs
self._validate_params(method, params)
data = {"key": self.api_key, "method": method, "json": 1}
data.update(params)
# Log without exposing key
logger.info(
"Submitting %s solve for %s",
method, params.get("pageurl", "unknown"),
)
resp = requests.post(
f"{self.base}/in.php", data=data, timeout=30,
)
return resp.json()
def _validate_params(self, method, params):
"""Prevent common security mistakes."""
# Ensure pageurl is a valid URL
pageurl = params.get("pageurl", "")
if pageurl and not pageurl.startswith(("http://", "https://")):
raise ValueError(f"Invalid pageurl: {pageurl}")
# Ensure method is valid
valid_methods = {
"userrecaptcha", "turnstile", "geetest",
"base64", "post", "bls", "cloudflare_challenge",
}
if method not in valid_methods:
raise ValueError(f"Unknown method: {method}")
Redact API Key Secara Otomatis dari Log
Log sering jadi jalur kebocoran yang tidak disadari — key ikut tercetak begitu saja saat developer menambahkan baris debug seperti logger.info(f"key: {api_key}"). Redact otomatis dengan regex jauh lebih andal daripada mengandalkan disiplin manual:
import logging
import re
logger = logging.getLogger(__name__)
class SafeFormatter(logging.Formatter):
"""Redact API keys from log messages."""
KEY_PATTERN = re.compile(r'[a-f0-9]{32}', re.IGNORECASE)
def format(self, record):
msg = super().format(record)
return self.KEY_PATTERN.sub("[REDACTED]", msg)
# Configure safe logging
handler = logging.StreamHandler()
handler.setFormatter(SafeFormatter("%(levelname)s: %(message)s"))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
# Key is automatically redacted in logs
logger.info(f"Using key: abc123def456ghi789jkl012mno345pq")
# Output: INFO: Using key: [REDACTED]
Amankan API Key di Docker
API key tidak boleh ikut masuk ke image container — baik lewat instruksi ENV di Dockerfile maupun ter-copy dari file .env yang lupa di-exclude. Suntikkan key lewat environment variable saat container jalan, atau pakai Docker secrets:
# Dockerfile — DO NOT embed keys here
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install requests
CMD ["python", "solver.py"]
# docker-compose.yml
services:
solver:
build: .
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
# Or use Docker secrets:
secrets:
- captchaai_key
secrets:
captchaai_key:
file: ./secrets/captchaai_key.txt
Keamanan API Key di Pipeline CI/CD
GitHub Actions
Simpan API key sebagai encrypted secret di repository settings, bukan sebagai environment variable biasa di file YAML:
# .github/workflows/test.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
env:
CAPTCHAAI_API_KEY: ${{ secrets.CAPTCHAAI_API_KEY }}
run: python test_solver.py
Jangan pernah mencatat atau meng-echo rahasia dalam output CI — banyak platform menyimpan log build berbulan-bulan, dan siapa pun dengan akses read ke repository bisa membacanya.
Menyiapkan IP Whitelist untuk Server Anda
IP whitelist menambah lapisan pertahanan kedua: bahkan kalau key bocor, permintaan dari luar daftar IP yang diizinkan tetap ditolak. Cek pengaturan pembatasan IP di dashboard CaptchaAI Anda — kalau tersedia, whitelist hanya IP keluar (egress IP) server yang menjalankan proses solve, bukan IP laptop development.
Sebelum mengaktifkan whitelist:
- Pastikan IP server statis. Instance cloud biasanya dapat IP publik yang berubah tiap restart, kecuali Anda pakai Elastic IP (AWS), IP statis (GCP), atau NAT gateway dengan IP tetap.
- Catat semua region yang dipakai. Tim automation Indonesia umumnya deploy ke region terdekat — AWS
ap-southeast-1(Singapura) atauap-southeast-3(Jakarta), maupun GCPasia-southeast2(Jakarta). Tiap region punya rentang egress IP sendiri. - Pisahkan whitelist per environment, sejalan dengan pemisahan key di bagian rotasi.
- Update whitelist sebelum migrasi infrastruktur, bukan sesudahnya — server baru dengan IP yang belum ter-whitelist langsung ditolak.
Kalau IP publik tim Anda sering berubah — umum di setup development lokal — pembatasan yang terlalu ketat justru bisa memblokir trafik sah. Untuk kondisi ini, andalkan rotasi key dan monitoring saldo sebagai lapisan utama, dan aktifkan whitelist khusus untuk server production yang IP-nya stabil.
Kesalahan Umum dan Solusinya
| Masalah | Penyebab | Solusi |
|---|---|---|
ERROR_WRONG_USER_KEY |
Key salah atau kedaluwarsa | Verifikasi key dari dashboard CaptchaAI |
| Saldo terkuras tak terduga | Key bocor atau dibagikan | Rotasi key segera, audit akses |
| Key berfungsi lokal tapi gagal di CI | Environment variable belum di-set | Tambahkan ke secrets CI/CD |
| Key tercatat dalam history Git | File .env sempat ter-commit |
Rotasi key, tambahkan .env ke .gitignore, bersihkan history dengan git filter-branch |
| Request ditolak walau key benar, whitelist aktif | Egress IP server berubah, beda dari IP yang di-whitelist | Cek IP publik server saat ini, update whitelist, atau pakai IP statis |
Daftar Periksa Keamanan API Key
| Praktik | Status |
|---|---|
| API key di environment variable, bukan hardcode | ☐ |
.env sudah masuk .gitignore |
☐ |
| Tidak ada key tertulis di source code | ☐ |
| Key di-redact otomatis dari log | ☐ |
| CI/CD memakai secret manager | ☐ |
| Jadwal rotasi key ditetapkan | ☐ |
| Key development terpisah dari production | ☐ |
| Monitoring saldo aktif | ☐ |
| IP whitelist diaktifkan untuk production (kalau tersedia) | ☐ |
Pertanyaan yang Sering Diajukan
Apa yang harus segera dilakukan kalau API key CaptchaAI bocor?
Buat key baru dari dashboard CaptchaAI, perbarui semua aplikasi yang masih memakai key lama, lalu periksa riwayat saldo untuk memastikan tidak ada pemakaian tidak sah yang lolos sebelum key diganti.
Bagaimana cara kerja pembatasan API key berdasarkan IP?
Cek dashboard CaptchaAI Anda untuk pengaturan pembatasan IP — kalau tersedia dan diaktifkan, CaptchaAI hanya memproses permintaan dari IP di daftar whitelist; permintaan dengan key valid pun ditolak kalau berasal dari IP di luar daftar itu.
Seberapa sering sebaiknya API key CaptchaAI dirotasi?
Tidak ada angka mutlak, tapi jadwal rutin per kuartal adalah titik awal yang wajar. Rotasi lebih sering masuk akal untuk key yang dipegang banyak orang atau dipakai di banyak environment.
Amankah menyimpan API key di secret manager seperti AWS Secrets Manager atau HashiCorp Vault?
Ya — ini praktik yang direkomendasikan untuk production. Simpan key di secret manager pilihan tim Anda, lalu muat sebagai environment variable saat runtime, seperti pola os.environ di contoh sebelumnya.
Panduan Terkait
Jangan tunggu sampai saldo terkuras — amankan API key CaptchaAI Anda sekarang.