Integraciones

Integración de Vault para la gestión de claves API CaptchaAI

Las claves API codificadas en el código fuente son una responsabilidad de seguridad. HashiCorp Vault centraliza la gestión de secretos: suCaptchaAILa clave API se almacena cifrada, se recupera en tiempo de ejecución y se registra cada acceso. Esta guía muestra cómo integrar Vault en su proceso de resolución de CAPTCHA.

Por qué Vault para claves API CAPTCHA

Sin bóveda Con bóveda
Clave API en el archivo o código .env Clave almacenada cifrada en Vault
Clave compartida a través de Slack o correo electrónico Acceso a través de API autenticada
Sin pista de auditoría de acceso Cada lectura registrada con identidad
Rotación manual de llaves Soporte de rotación automatizado
La misma clave en todos los entornos Claves por entorno con políticas

Requisitos previos

  • Servidor HashiCorp Vault (autohospedado o HCP Vault)
  • Acceso a Vault CLI o API
  • Clave API CaptchaAI
  • Python 3.8+ o Node.js 18+

Almacene la clave API en 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

Crear una política de bóveda

Restrinja a los trabajadores de CAPTCHA al acceso de solo lectura:

# captcha-worker-policy.hcl
path "secret/data/captchaai" {
  capabilities = ["read"]
}

path "secret/metadata/captchaai" {
  capabilities = ["read"]
}

Aplicar la política:

vault policy write captcha-worker captcha-worker-policy.hcl

Integración de 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]}...")

Integración de 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)}...`);
})();

Métodos de autenticación

Vault admite múltiples métodos de autenticación para trabajadores:

Método Mejor para Configuración
ficha Desarrollo, CI/CD VAULT_TOKEN var env
Función de aplicación Servicios de producción ID de rol + ID secreto
Kubernetes Cargas de trabajo de K8 Cuenta de servicio JWT
AWSIAM Trabajadores EC2/Lambda Rol de instancia

Ejemplo de AppRole (recomendado para producción)

# 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"]

Flujo de trabajo de rotación de claves

  1. Genere una nueva clave API CaptchaAI en el panel CaptchaAI
  2. Actualizar bóveda: vault kv put secret/captchaai api_key="NEW_KEY"
  3. Los trabajadores recogen automáticamente la nueva clave en su próximo ciclo de actualización
  4. Revocar la clave anterior en el panel CaptchaAI después de que todos los trabajadores se hayan actualizado

No se requieren cambios de código ni implementaciones.

Solución de problemas

Problema causa Solución
403 Forbidden de la bóveda La política no permite la lectura. Verifique la ruta captcha-worker-policy.hcl
VAULT_TOKEN caducado Se superó el TTL del token Utilice AppRole para tokens renovables automáticamente
Clave no refrescante Intervalo de actualización demasiado largo Reducir _key_refresh_interval
Bóveda no disponible Problema de red o servidor Clave de caché local con respaldo

Preguntas frecuentes

¿Qué sucede si Vault no funciona?

Almacene en caché la clave API en la memoria cuando se recupere por primera vez. Si Vault no está disponible durante una actualización, continúe usando la clave almacenada en caché y registre el error.

¿Debo almacenar una clave por entorno?

Sí. Utilice rutas de Bóveda independientes: secret/captchaai/dev, secret/captchaai/staging, secret/captchaai/prod.

¿Puedo utilizar AWS Secrets Manager en lugar de Vault?

Sí. El patrón es idéntico: recuperar el secreto en tiempo de ejecución de AWS Secrets Manager usando boto3. El principio básico (sin claves codificadas, rotación sin implementaciones) sigue siendo el mismo.

Artículos relacionados

  • Seguridad de clave API de lista blanca de IP Captchaai
  • Rotación de clave Captchaai Api
  • Integración de Captchaai de funciones de Google Cloud

Próximos pasos

Proteja sus credenciales CaptchaAI con Vault:obtenga su clave API.

Guías relacionadas:

  • Rotación de claves API
  • Protección de credenciales en Env Vars
  • Lista blanca de IP
Los comentarios están deshabilitados para este artículo.