Kunci API yang di-hardcode dalam kode sumber merupakan tanggung jawab keamanan. HashiCorp Vault memusatkan manajemen rahasia – milik AndaCaptchaAIKunci API disimpan terenkripsi, diambil saat runtime, dan setiap akses dicatat. Panduan ini menunjukkan cara mengintegrasikan Vault ke dalam alur penyelesaian CAPTCHA Anda.
Mengapa Vault untuk Kunci API CAPTCHA
| Tanpa Gudang | Dengan Gudang |
|---|---|
Kunci API dalam file atau kode .env |
Kunci disimpan terenkripsi di Vault |
| Kunci dibagikan melalui Slack atau email | Akses melalui API yang diautentikasi |
| Tidak ada jejak audit akses | Setiap pembacaan dicatat dengan identitas |
| Rotasi kunci manual | Dukungan rotasi otomatis |
| Kunci yang sama di seluruh lingkungan | Kunci per lingkungan dengan kebijakan |
Prasyarat
- Server HashiCorp Vault (dihosting sendiri atau HCP Vault)
- Akses Vault CLI atau API
- Kunci API CaptchaAI
- Python 3.8+ atau Node.js 18+
Simpan Kunci API di Vault
# Enable the KV secrets engine (if not already enabled)
vault secrets enable -path=secret kv-v2
# Store the CaptchaAI API key
vault kv put secret/captchaai api_key="YOUR_API_KEY"
# Verify
vault kv get secret/captchaai
Buat Kebijakan Vault
Batasi pekerja CAPTCHA untuk akses hanya baca:
# captcha-worker-policy.hcl
path "secret/data/captchaai" {
capabilities = ["read"]
}
path "secret/metadata/captchaai" {
capabilities = ["read"]
}
Terapkan kebijakan:
vault policy write captcha-worker captcha-worker-policy.hcl
Integrasi Python
# vault_solver.py
import os
import time
import hvac
import requests
# Connect to Vault
vault_client = hvac.Client(
url=os.environ.get("VAULT_ADDR", "http://127.0.0.1:8200"),
token=os.environ.get("VAULT_TOKEN"),
)
def get_api_key():
"""Retrieve CaptchaAI API key from Vault."""
secret = vault_client.secrets.kv.v2.read_secret_version(
path="captchaai",
mount_point="secret",
)
return secret["data"]["data"]["api_key"]
class CaptchaSolver:
"""CAPTCHA solver with Vault-managed credentials."""
def __init__(self):
self.api_key = get_api_key()
self.session = requests.Session()
self._key_fetched_at = time.time()
self._key_refresh_interval = 3600 # Re-fetch key hourly
def _refresh_key_if_needed(self):
"""Periodically refresh the key from Vault."""
if time.time() - self._key_fetched_at > self._key_refresh_interval:
self.api_key = get_api_key()
self._key_fetched_at = time.time()
def solve(self, sitekey, pageurl):
"""Solve reCAPTCHA v2 using Vault-managed key."""
self._refresh_key_if_needed()
# Submit
resp = self.session.get("https://ocr.captchaai.com/in.php", params={
"key": self.api_key,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
time.sleep(15)
for _ in range(25):
poll = self.session.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key,
"action": "get",
"id": task_id,
"json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Usage
solver = CaptchaSolver()
token = solver.solve(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Token: {token[:30]}...")
Integrasi JavaScript
// vault_solver.js
const axios = require('axios');
const VAULT_ADDR = process.env.VAULT_ADDR || 'http://127.0.0.1:8200';
const VAULT_TOKEN = process.env.VAULT_TOKEN;
async function getApiKey() {
const resp = await axios.get(
`${VAULT_ADDR}/v1/secret/data/captchaai`,
{ headers: { 'X-Vault-Token': VAULT_TOKEN } }
);
return resp.data.data.data.api_key;
}
class CaptchaSolver {
constructor() {
this.apiKey = null;
this.keyFetchedAt = 0;
this.refreshInterval = 3600000; // 1 hour
}
async init() {
this.apiKey = await getApiKey();
this.keyFetchedAt = Date.now();
}
async refreshKeyIfNeeded() {
if (Date.now() - this.keyFetchedAt > this.refreshInterval) {
this.apiKey = await getApiKey();
this.keyFetchedAt = Date.now();
}
}
async solve(sitekey, pageurl) {
await this.refreshKeyIfNeeded();
const submit = await axios.get('https://ocr.captchaai.com/in.php', {
params: {
key: this.apiKey, method: 'userrecaptcha',
googlekey: sitekey, pageurl, json: '1',
},
});
if (submit.data.status !== 1) throw new Error(submit.data.request);
const taskId = submit.data.request;
await new Promise(r => setTimeout(r, 15000));
for (let i = 0; i < 25; i++) {
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: this.apiKey, action: 'get', id: taskId, json: '1' },
});
if (poll.data.status === 1) return poll.data.request;
if (poll.data.request !== 'CAPCHA_NOT_READY') throw new Error(poll.data.request);
await new Promise(r => setTimeout(r, 5000));
}
throw new Error('Timeout');
}
}
(async () => {
const solver = new CaptchaSolver();
await solver.init();
const token = await solver.solve(
'6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'https://www.google.com/recaptcha/api2/demo'
);
console.log(`Token: ${token.slice(0, 30)}...`);
})();
Metode Otentikasi
Vault mendukung beberapa metode autentikasi untuk pekerja:
| Metode | Terbaik Untuk | Pengaturan |
|---|---|---|
| Tanda | Pengembangan, CI/CD | VAULT_TOKEN env var |
| Peran Aplikasi | Layanan produksi | ID Peran + ID Rahasia |
| Kubernet | beban kerja K8 | Akun layanan JWT |
| AWS IAM | Pekerja EC2/Lambda | Peran contoh |
Contoh AppRole (Direkomendasikan untuk Produksi)
# AppRole authentication — no static token needed
vault_client = hvac.Client(url=os.environ["VAULT_ADDR"])
vault_client.auth.approle.login(
role_id=os.environ["VAULT_ROLE_ID"],
secret_id=os.environ["VAULT_SECRET_ID"],
)
# Now read the secret
secret = vault_client.secrets.kv.v2.read_secret_version(path="captchaai")
api_key = secret["data"]["data"]["api_key"]
Alur Kerja Rotasi Kunci
- Hasilkan kunci API CaptchaAI baru di dashboard CaptchaAI
- Perbarui Gudang:
vault kv put secret/captchaai api_key="NEW_KEY" - Pekerja secara otomatis mengambil kunci baru pada siklus penyegaran berikutnya
- Cabut kunci lama di dashboard CaptchaAI setelah semua pekerja melakukan penyegaran
Tidak diperlukan perubahan atau penerapan kode.
Pemecahan masalah
| Masalah | Sebab | Perbaiki |
|---|---|---|
403 Forbidden dari Vault |
Kebijakan tidak mengizinkan membaca | Periksa jalur captcha-worker-policy.hcl |
VAULT_TOKEN expiry |
Token TTL terlampaui | Gunakan AppRole untuk token yang dapat diperpanjang secara otomatis |
| Kunci tidak menyegarkan | Interval penyegaran terlalu lama | Kurangi _key_refresh_interval |
| Gudang tidak tersedia | Masalah jaringan atau server | Kunci cache secara lokal dengan fallback |
Pertanyaan Umum
Apa yang terjadi jika Vault tidak aktif?
Simpan kunci API dalam cache di memori saat pertama kali diambil. Jika Vault tidak tersedia selama penyegaran, terus gunakan kunci cache dan catat kegagalannya.
Haruskah saya menyimpan satu kunci per lingkungan?
Ya. Gunakan jalur Vault terpisah: secret/captchaai/dev, secret/captchaai/staging, secret/captchaai/prod.
Bisakah saya menggunakan AWS Secrets Manager alih-alih Vault?
Ya. Polanya identik – mengambil rahasia saat runtime dari AWS Secrets Manager menggunakan boto3 Prinsip intinya (tanpa kunci hardcode, rotasi tanpa penerapan) tetap sama.
Artikel Terkait
- Captchaai Ip Memasukkan Keamanan Kunci Api
- Rotasi Kunci Captchaai Api
- Integrasi Captchaai Fungsi Google Cloud
Langkah Selanjutnya
Amankan kredensial CaptchaAI Anda dengan Vault —dapatkan kunci API Anda.
Panduan terkait:
- Rotasi Kunci API
- Mengamankan Kredensial di Env Vars
- Daftar Putih IP