Tutorials

Sichern von CaptchaAI-Anmeldeinformationen in Umgebungsvariablen

Der CaptchaAI-API-Schlüssel gehört in eine Umgebungsvariable – lokal in eine .env-Datei außerhalb der Versionskontrolle, im Betrieb in die Secret-Verwaltung der Plattform. Ein Schlüssel im Quellcode ist kein Konfigurationsdetail, sondern ein Vorfall mit Vorlaufzeit.

Das Muster kennt fast jedes Team: Ein Scraper läuft seit Monaten auf einem VPS bei Hetzner, das Repository wird für einen Freelancer-Auftrag öffentlich gestellt – und der Schlüssel aus Zeile 12 von solver.py gleich mit.

Vier Ebenen kommen in Frage: .env lokal, Systemvariablen auf dem Server, Docker Secrets im Container, maskierte Variablen in der CI. Dazu ein Startup-Check, der einen ungültigen Schlüssel meldet, bevor die erste Anfrage an in.php rausgeht.


Wo der API-Schlüssel je nach Umgebung liegen sollte

Umgebung Ablage Absicherung
Lokale Entwicklung .env im Projektstamm Eintrag in .gitignore
Server / VPS EnvironmentFile der systemd-Unit chmod 600, Service-Benutzer
Container Docker Secret kein Schlüssel im Image
CI/CD maskierte Variable keine Ausgabe im Job-Log
Mehrere Teams Cloud Secret Manager Rotation, Zugriffsprotokoll

Die Faustregel: Je mehr Personen Zugriff haben, desto weiter muss der Schlüssel vom Code wegwandern.

Hinweis: Art. 32 DSGVO verlangt angemessene technische Maßnahmen für Systeme, die personenbezogene Daten verarbeiten. Ein API-Schlüssel im Git-Verlauf jedes ehemaligen Projektbeteiligten ist schwer zu begründen.


.env-Datei für die lokale Entwicklung

Legen Sie im Projektstammverzeichnis eine .env-Datei an:

CAPTCHAAI_API_KEY=your_actual_api_key_here

Der Eintrag in .gitignore folgt sofort danach, nicht später:

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

Wichtig: .gitignore wirkt nur auf Dateien, die Git noch nicht verfolgt. Wurde die .env schon einmal committet, greift der Eintrag nicht mehr – dann hilft der Notfallplan weiter unten.

Ins Repository gehört stattdessen eine .env.example mit leeren Werten – als Referenz für neue Teammitglieder.

Python mit 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())

Zwei Details ersparen später Fehlersuche:

  • Der Zugriff über eckige Klammern bricht sofort ab, wenn die Variable fehlt; os.environ.get() liefert stattdessen None – der Fehler fällt später auf.
  • Ein leerer Schlüssel endet in ERROR_WRONG_USER_KEY – der Fehler steckt dann in der Konfiguration.

Node.js mit 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);

Dasselbe Prinzip in Node.js, mit zwei Stolpersteinen:

  • require('dotenv').config() muss vor jedem Modul stehen, das den Schlüssel beim Import liest.
  • Ohne process.exit(1) läuft der Worker mit leerem Schlüssel weiter.

Umgebungsvariablen auf Betriebssystemebene

Sobald der Code den Entwicklungsrechner verlässt, ist die .env-Datei nicht mehr die naheliegende Ablage: Auf einem Server mit einem einzigen Dienst gehört der Wert in die Prozessumgebung.

Linux und 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

Das Shell-Profil gilt aber nur für interaktive Sitzungen. Für Dienste auf einem Server bei Hetzner, IONOS oder netcup ist die systemd-Unit der bessere Ort:

  • EnvironmentFile=/etc/captchaai.env in der Unit eintragen.
  • Die Datei bekommt chmod 600 und den Service-Benutzer als Besitzer.
  • Kein anderes Konto auf dem System liest den Wert mit.

Windows und PowerShell

$env:CAPTCHAAI_API_KEY = "your_actual_api_key_here"

# Persist permanently
[System.Environment]::SetEnvironmentVariable("CAPTCHAAI_API_KEY", "your_actual_api_key_here", "User")

Die erste Zeile gilt nur für die laufende Sitzung, die zweite schreibt den Wert ins Benutzerprofil. Läuft die Automatisierung als Windows-Dienst unter einem eigenen Konto, setzen Sie die Variable im Kontext dieses Kontos – sonst startet der Dienst ohne Schlüssel.


Container: Docker, Compose und Docker Secrets

Schlüssel an docker run übergeben

docker run -e CAPTCHAAI_API_KEY="your_key" my-scraper

Für einen Test in Ordnung, für den Dauerbetrieb nicht: Der Wert landet in der Shell-History und ist über docker inspect lesbar.

Docker Compose

# docker-compose.yml
services:
  scraper:
    image: my-scraper
    environment:

      - CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}

${CAPTCHAAI_API_KEY} verweist auf die Umgebungsvariable des Hosts – der Schlüssel steht weder in der Compose-Datei noch im Image.

Docker Secrets im Swarm-Betrieb

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

Im Code lesen Sie den Wert aus dem eingehängten Pfad:

with open("/run/secrets/captchaai_key") as f:
    API_KEY = f.read().strip()

Hinweis: Secrets liegen im Container ausschließlich unter /run/secrets/. Sie erscheinen weder in docker inspect noch in einem versehentlich ausgegebenen Environment-Dump – das ist der Vorteil gegenüber der Umgebungsvariable.


CI/CD: maskierte Variablen statt Klartext

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

Hinterlegen Sie den Schlüssel unter Settings → Secrets and variables → Actions → New repository secret.

Hinweis: Die Maskierung greift nur bei exakten Treffern im Log. Sobald ein Skript den Schlüssel zerlegt oder kodiert, ist der Schutz weg – behandeln Sie Logs grundsätzlich als lesbar.

GitLab CI

# .gitlab-ci.yml
scrape:
  script:

    - python scraper.py
  variables:
    CAPTCHAAI_API_KEY: $CAPTCHAAI_API_KEY

In vielen deutschen Unternehmen läuft die Pipeline auf einer selbst gehosteten GitLab-Instanz. Die Variable legen Sie unter Settings → CI/CD → Variables an:

  • „Masked“ verhindert die Ausgabe im Job-Log; der Wert braucht dafür eine Mindestlänge und keine Zeilenumbrüche.
  • „Protected“ beschränkt Produktions-Schlüssel auf geschützte Branches.

API-Schlüssel beim Start validieren

Ein fehlender Schlüssel soll den Prozess sofort beenden – nicht nach 200 halb abgearbeiteten Aufgaben:

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

res.php mit action=getbalance beantwortet zwei Fragen auf einmal: Existiert der Schlüssel, und ist Guthaben vorhanden? ERROR_KEY_DOES_NOT_EXIST deutet auf einen Tippfehler oder eine nicht geladene .env-Datei hin.


Häufige Fehler und die bessere Praxis

Fehler Risiko Besser
.env eingecheckt bleibt im Repo-Verlauf vorher in .gitignore eintragen
Schlüssel geloggt landet im Log-Aggregator nur letzte Zeichen loggen
Hardcodierung im Dockerfile in der Image-Ebene eingebrannt ENV zur Laufzeit setzen
Weitergabe per Chat bleibt in fremden Verläufen Secret-Manager nutzen
Ein Schlüssel überall Leak in Staging trifft Produktion getrennte Schlüssel je Umgebung

Notfallplan: Der Schlüssel liegt bereits im Repository

Das Löschen der Datei hilft nicht – der alte Stand bleibt im Verlauf lesbar. Gehen Sie in dieser Reihenfolge vor:

  1. Schlüssel rotieren im CaptchaAI-Dashboard – der alte Wert verliert damit seinen Nutzen.
  2. Neuen Wert ausrollen: Server, Container, CI-Variablen, Entwicklungsrechner.
  3. Guthaben und Statistik prüfen – auf Aufgaben, die Sie nicht ausgelöst haben.
  4. Git-Verlauf bereinigen als Aufräumarbeit, nicht als Sicherheitsmaßnahme.
  5. Secret-Scan ergänzen, damit derselbe Fehler vor dem Push auffällt.

Mehrere Schlüssel und Umgebungen sauber trennen

Ein Schlüssel je Umgebung ist der Normalfall: Staging und Produktion sollten sich unabhängig rotieren lassen. Mehrere Werte legen Sie als kommaseparierte Liste ab:

CAPTCHAAI_KEYS=key1,key2,key3
keys = os.environ["CAPTCHAAI_KEYS"].split(",")

Am Durchsatz ändert das nichts: CaptchaAI rechnet pro gleichzeitigem Thread ab, nicht pro Schlüssel. Wer mehr parallele Abfragen braucht, wählt den passenden Plan – BASIC ab 15 $/Monat mit 5 Threads, STANDARD 30 $ mit 15 Threads.


FAQ

Reicht eine .env-Datei auch auf dem Produktionsserver?

Für einen einzelnen Dienst ja – sofern die Datei außerhalb des Webroots liegt, 600-Rechte hat und dem Service-Benutzer gehört. Bei mehreren Anwendungen oder Teams ist ein Secret-Manager (Azure Key Vault, HashiCorp Vault) tragfähiger.

Wie halte ich den Schlüssel aus Logs und Fehlerberichten heraus?

Protokollieren Sie ihn nie vollständig. Zwei Stellen werden oft übersehen:

  • Exception-Tracker, die im Fehlerfall die Prozessumgebung mitschicken.
  • Debug-Ausgaben von HTTP-Bibliotheken, die die Anfrage an in.php samt key-Parameter mitschreiben.

Warum findet mein Container die Umgebungsvariable nicht?

Fast immer, weil sie im falschen Kontext gesetzt wurde. Eine Variable in der Shell des Hosts wird nicht automatisch weitergereicht – sie muss über -e, env_file oder environment übergeben werden.

Brauche ich für jeden CAPTCHA-Typ einen eigenen Schlüssel?

Nein. Derselbe Schlüssel adressiert alle unterstützten Methoden – reCAPTCHA v2 und v3, Cloudflare Turnstile, GeeTest v3 sowie Bild- und Rasterbild-CAPTCHAs. Er ist an Ihr Konto gebunden, nicht an einen CAPTCHA-Typ.


Schützen Sie Ihre CaptchaAI-Integration ab dem ersten Commit

Holen Sie sich Ihren API-Schlüssel auf captchaai.com und hinterlegen Sie ihn gleich als Umgebungsvariable – das erspart Ihnen die Rotation unter Zeitdruck.


Verwandte Leitfäden

Kommentare sind für diesen Artikel deaktiviert.