Tutorials

Sécurisation des informations d'identification CaptchaAI dans les variables d'environnement

Une clé API CaptchaAI se manipule comme un mot de passe : elle vit dans une variable d'environnement, que le programme lit au démarrage, jamais dans le code source. Restent quatre endroits où la déclarer, plus un contrôle au lancement :

  1. le poste de développement, avec un fichier .env ignoré par Git ;
  2. le serveur, avec les variables système ;
  3. le conteneur, avec docker run, Compose ou un secret Swarm ;
  4. le pipeline CI/CD, avec les secrets GitHub Actions ou GitLab CI.

Pourquoi la clé ne doit jamais figurer dans le code

Une clé écrite en dur dans un fichier .py ou .js ne disparaît pas quand vous l'effacez : elle reste dans l'historique Git, dans les forks et dans les sauvegardes. Deux conséquences concrètes, et la parade :

  • Votre solde part avec la clé. Un tiers qui la récupère consomme vos threads ; vos tâches attendent en file d'attente.
  • La révocation coûte cher. Une clé figée oblige à redéployer, un par un, tous les services qui l'embarquent.
  • La variable d'environnement règle les deux. Une source de vérité unique, une valeur par environnement.

Six erreurs qui exposent une clé API

Erreur Risque Correctif
Commiter .env sur Git Clé exposée dans tout l'historique .env dans .gitignore avant le premier commit
Afficher la clé dans les logs Clé visible dans les agrégateurs Masquez-la ou omettez-la
Clé en dur dans le Dockerfile Clé figée dans les couches de l'image ENV à l'exécution, jamais au build
Partager la clé par chat ou e-mail Clé conservée indéfiniment ailleurs Passez par un gestionnaire de secrets
Même clé en staging et en production Origine d'une fuite impossible à isoler Une clé par environnement
Clé dans un build front-end (VITE_, NEXT_PUBLIC_) Clé livrée dans le bundle public Lecture côté serveur uniquement

Le fichier .env en développement local

Étape 1 : créez le fichier .env à la racine du projet

CAPTCHAAI_API_KEY=your_actual_api_key_here

Étape 2 : ajoutez-le à .gitignore avant le premier commit

# .gitignore
.env
.env.local
.env.production

Python : charger la clé avec 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())

os.environ["CAPTCHAAI_API_KEY"] lève une exception si la variable manque : mieux vaut un arrêt immédiat qu'une requête à clé vide.

Node.js : charger la clé avec 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);

Le contrôle est explicite : variable absente, le processus sort avec un code non nul, que PM2 ou systemd sait interpréter.


Définir la variable au niveau du système

Sur un serveur, .env ajoute un fichier lisible de plus, souvent recopié par mégarde lors d'un déploiement. Les variables système évitent ce détour.

Linux et 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")
  • la première ligne ne vaut que pour la session en cours ;
  • la seconde inscrit la variable dans le profil utilisateur, donc dans les sessions suivantes.

Docker : transmettre la clé sans l'inscrire dans l'image

Passer la variable au moment du 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} renvoie à la variable de l'hôte : la clé n'entre jamais dans le fichier de composition, que vous pouvez donc versionner.

Secrets Docker en mode Swarm

Sur un cluster, les secrets Docker montent la valeur dans un fichier en mémoire, hors de l'environnement du conteneur : /proc/<pid>/environ ne révèle rien. Créez le secret, référencez-le dans le service, puis lisez le fichier monté :

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
with open("/run/secrets/captchaai_key") as f:
    API_KEY = f.read().strip()

CI/CD : GitHub Actions et GitLab CI

Le pipeline est l'endroit où les clés fuient le plus discrètement : les logs de build sont souvent publics, ou largement lisibles en interne.

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 }}
  1. Ouvrez Paramètres → Secrets et variables → Actions.
  2. Créez le secret de dépôt CAPTCHAAI_API_KEY.
  3. Vérifiez qu'un build l'affiche en *** : GitHub masque la valeur, même si un script l'imprime.

GitLab CI

# .gitlab-ci.yml
scrape:
  script:

    - python scraper.py
  variables:
    CAPTCHAAI_API_KEY: $CAPTCHAAI_API_KEY
  1. Ajoutez la variable dans Paramètres → CI/CD → Variables.
  2. Activez « Masqué » pour la retirer des logs.
  3. Activez « Protégé » si seules les branches de production y accèdent.

Vérifier la clé au démarrage du pipeline

Avant de lancer un lot de résolutions, vérifiez que la variable existe et que la clé répond. Un appel à res.php avec action=getbalance suffit et renvoie le solde :

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}")

Ce contrôle transforme une panne silencieuse en message clair. Placez-le dans le point d'entrée du worker, pas dans un script annexe.


Exemple : un worker déployé sur OVHcloud ou Scaleway

Sur une instance OVHcloud ou Scaleway, le plus propre reste le service systemd : placez la clé dans /etc/captchaai.env (droits 600, propriétaire root), puis référencez ce fichier depuis l'unité avec EnvironmentFile=. La clé n'est alors ni dans le dépôt, ni dans l'historique du shell. Prévoyez ensuite une valeur par environnement :

  • une clé pour la staging, une autre pour la production ;
  • un plan BASIC ($15/mois, 5 threads) pour les tests d'intégration, la production sur un plan dimensionné à son volume ;
  • une facturation en dollars US, au thread simultané, résolutions illimitées par thread.

Journalisation : masquer plutôt que supprimer

Une clé complète dans un agrégateur de logs équivaut à une clé publiée. Ne journalisez jamais la valeur brute : pour tracer quelle clé a servi, écrivez ses quatre derniers caractères (…a91f). Traitez aussi les logs de scraping comme des données à durée de vie limitée : dès qu'ils touchent des données personnelles, la logique RGPD vaut pour les traces.


FAQ

Comment stocker la clé sur un serveur sans passer par un fichier .env ?

  • systemd : la directive EnvironmentFile=, sur un fichier en droits 600 ;
  • Kubernetes : un Secret monté en volume ou injecté dans le conteneur ;
  • cloud : AWS Secrets Manager ou Azure Key Vault, lu au démarrage du worker.

Peut-on gérer plusieurs clés dans une même configuration ?

Oui. Séparez les valeurs par des virgules ou numérotez les variables :

CAPTCHAAI_KEYS=key1,key2,key3
keys = os.environ["CAPTCHAAI_KEYS"].split(",")
  • répartissez les tâches selon les threads de chaque clé ;
  • gardez-en une prête à prendre le relais pendant une rotation.

Faut-il vraiment une clé différente pour la staging et la production ?

Oui, dès qu'une deuxième personne accède au projet : vous révoquez un environnement compromis sans interrompre l'autre, et vous suivez les consommations séparément dans le tableau de bord.

La rotation d'une clé interrompt-elle les résolutions en cours ?

Non, si vous respectez l'ordre : générez la nouvelle clé, déployez-la dans la variable d'environnement, laissez les tâches en cours se terminer, puis désactivez l'ancienne.

Les variables d'environnement suffisent-elles pour un audit de sécurité ?

  • Le risque principal est couvert : la clé sort du code et du dépôt.
  • Un auditeur regardera ensuite qui peut lire la variable sur la machine.
  • Puis la traçabilité des rotations et le masquage dans les logs.

Sécurisez votre intégration CaptchaAI dès le premier jour

Obtenez votre clé API sur captchaai.com.


Guides associés

Les commentaires sont désactivés pour cet article.