[NIEAKTYWNE — WAHA zdecommissioned 2026-06-30] WAHA zastąpiona przez whatsup-android-chat-puller. Ten dokument zachowany jako archiwum historyczne. Patrz: issue #2007

Playbook: WAHA health check fails with HTTP 401 — GH secret WAHA_API_KEY drift

Trigger

The Infrastructure Health Check workflow reports:

✗ WAHA: FAIL (server=401, session=?) — server reachable but unhealthy

i.e. the WAHA Check WAHA step gets HTTP 401 from https://waha2.vps-h1.infra.zintegrowana.online/api/server/status.

Discovered: 2026-06-29 (#1983).

Root cause

WAHA on vps-h1 is healthy and reachable (TLS/Traefik up — this is not the HTTP 000 / Traefik-down case, see waha-traefik-down-ports-80-443.md). The 401 means the GitHub Actions repo secret WAHA_API_KEY sent by the health check no longer matches the live WAHA key.

The canonical key lives in secrets/vps-h1.env.sops (deployed to vps-h1 /root/.env). When that key is rotated but the GitHub Actions secret is not re-set, every workflow that authenticates to WAHA via secrets.WAHA_API_KEY breaks — including health-check.yml and waha-session-restart.yml. So fix the secret before trying any session restart.

secrets-sync.yml syncs SOPS → server .env files. It does not push to GitHub Actions secrets, so a SOPS rotation does not auto-update WAHA_API_KEY in GH. That step is manual.

Confirm

# 1. Live WAHA with the canonical SOPS key — expect HTTP 200 (key is valid, server healthy):
export SOPS_AGE_KEY_FILE=<worker age key, e.g. ~/.age/p24-infra-keys.txt>
WK=$(sops -d --input-type dotenv --output-type dotenv secrets/vps-h1.env.sops \
  | grep '^WAHA_API_KEY=' | cut -d= -f2- | tr -d '"')
curl -s -o /dev/null -w '%{http_code}\n' -H "X-Api-Key: $WK" \
  https://waha2.vps-h1.infra.zintegrowana.online/api/server/status   # expect: 200
unset WK

If the SOPS key returns 200 but the health check returns 401, the GH secret has drifted → resync it.

Fix — resync the GH Actions secret from SOPS (never print the value)

export SOPS_AGE_KEY_FILE=<worker age key>
WK=$(sops -d --input-type dotenv --output-type dotenv secrets/vps-h1.env.sops \
  | grep '^WAHA_API_KEY=' | cut -d= -f2- | tr -d '"')
printf '%s' "$WK" | gh secret set WAHA_API_KEY --repo radieu/p24-infra   # value via stdin only
unset WK

gh secret set reads the value from stdin (never echo it, never pass via argv). Requires repo admin.

Verify resolution

gh workflow run health-check.yml --repo radieu/p24-infra
# Wait ~30s, then check the WAHA step → should no longer be 401.

Note: a healthy key gets the check past the 401, but WAHA also has to report session=WORKING. If the default session is STOPPED/FAILED, the check still fails on the session — that is a separate problem; see waha-session-stopped-after-reboot.md and dispatch waha-session-restart.yml (which itself needs the now-fixed WAHA_API_KEY secret).

  • docs/playbooks/waha-traefik-down-ports-80-443.md — HTTP 000 (proxy/ports down)
  • docs/playbooks/waha-session-stopped-after-reboot.md — session not WORKING
  • docs/playbooks/static-api-key-incident-rotation.md — full key-rotation distribution
  • .github/workflows/waha-session-restart.yml — sanctioned remote session restart

Audit Log — Log to infra_operations

After this operation completes, log it to the infra_operations audit table.

Python (Linux server — bms-4, vps-i1, vps-h1, or similar):

import sys
sys.path.insert(0, '/opt/p24-infra')
from scripts.lib.log_op import log_op
 
log_op(
    actor="claude",  # "radieu" for manual human ops, "claude" for agent
    op_type="credential_rotation",
    resource="WAHA_CONTROL_TOKEN",
    result="success",  # "success" | "failed" | "skipped"
    detail="Credential drift fix — WAHA_CONTROL_TOKEN resynced from SOPS to GH Secret and live env",
    env="vps-h1",
    gh_issue=2730,
)

PowerShell (Windows dev machine):

$env:SUPABASE_URL = (Get-Content "C:\code_2026\p24-infra\.env.local" | Select-String "^SUPABASE_URL=").ToString().Split("=",2)[1].Trim()
$env:SUPABASE_SERVICE_KEY = (Get-Content "C:\code_2026\p24-infra\.env.local" | Select-String "^SUPABASE_SERVICE_KEY=").ToString().Split("=",2)[1].Trim()
python -c "
import os, sys
sys.path.insert(0, 'C:/code_2026/p24-infra')
from scripts.lib.log_op import log_op
log_op('claude', 'credential_rotation', 'WAHA_CONTROL_TOKEN', 'success', 'Credential drift fix — WAHA_CONTROL_TOKEN resynced from SOPS to GH Secret and live env', 'vps-h1')
"
$env:SUPABASE_URL = ''; $env:SUPABASE_SERVICE_KEY = ''