Scripting with API keys
Headless auth patterns for CI and automation - non-expiring keys, JSON output, exit codes.
For unattended automation - CI pipelines, cron jobs, integrations - authenticate
with an API key, not eddytor login. Login tokens
are short-lived (~15 min); API keys are built for machines.
The pattern
# 1. mint a key once (inside the server container), or a scoped key via the CLI
docker compose exec eddytor-server eddytoradm create-api-key --email ci@example.com
# -> edd_live_… (shown once)
# 2. in the pipeline, point the CLI at it (keep the key in a secret, not in code)
export EDDYTOR_API_KEY="$CI_SECRET"
eddytor config set-api-url "$EDDYTOR_API_URL"
eddytor config set-flight-url "$EDDYTOR_FLIGHT_URL"
eddytor config set-key "$EDDYTOR_API_KEY"
# 3. run with machine-readable output and check exit codes
eddytor get tables --json | jq '.[].name'Rules for robust scripts
- API key, never
loginin non-interactive environments - a login token will expire mid-job. --json+jqfor parsing; remember it's a no-op (warns) on side-effecting commands (insert/merge/config/login).- Check exit codes - non-zero = failure; errors go to stderr.
- Scope keys least-privilege - a read-only pipeline gets a read-scoped key; a key can never exceed its creator's role.
- Short-lived, labelled keys for automation:
eddytoradm create-api-key --name ci-pipeline --expires-in-minutes 10080(7 days), so they're easy to reason about and rotate. - Keep credentials in env/secrets, never in code or committed config.
REST & Flight from scripts
- REST -
Authorization: Bearer edd_live_…; branch on the error envelope'scode, logrequest_id, honor429 Retry-After. See REST API. - Bulk reads - Flight SQL with the same key.
- Writes - CLI
insert/merge, an SDK, or MCP tools (no REST DML).
Heads up
Rotating
EDDYTOR_API_KEY_SECRET invalidates all keys at
once - coordinate key rotation with a key
rotation window.