Credentials

Wildbox ships with no default credentials. Every secret, and the first administrator’s password, is generated on your machine when you create .env. If a guide, a blog post or an old version of this page gives you a literal password or API key for Wildbox, it is wrong.


Where Credentials Come From

scripts/generate_secrets.py (make generate-secrets) reads .env.template, replaces every secret it owns with a cryptographically random value and writes .env with mode 0600. scripts/validate_secrets.py (make validate-secrets) refuses a .env in which a placeholder survived. The authoritative list of generated values is secrets_map in scripts/generate_secrets.py; the main ones are:

Variable Used for
INITIAL_ADMIN_PASSWORD Password of the first administrator
JWT_SECRET_KEY Signs the JWTs issued by the identity service
API_KEY_HASH_SECRET Keys the HMAC of stored API-key digests
GATEWAY_INTERNAL_SECRET Proves to identity and to every backend service that a request came through the gateway; identity also presents it to the gateway’s purge endpoint and to guardian
POSTGRES_PASSWORD PostgreSQL superuser password
REDIS_PASSWORD Redis password
GUARDIAN_SECRET_KEY, CSPM_SECRET_KEY, DATA_SECRET_KEY Per-service secret keys
GUARDIAN_CONTACTS_SECRET Authenticates guardian’s worker to the identity service, to learn who may be e-mailed about a team. Optional, and never the value of GATEWAY_INTERNAL_SECRET
CSPM_CREDENTIAL_KEY Encrypts cloud credentials stored by CSPM (cloud security posture management)
SENSOR_API_KEY Authenticates the sensor’s local API
FLOWER_PASSWORD Celery Flower for the tools workers
API_KEY Required by the tools API, its workers and Flower to start (at least 32 characters). Not a request credential: the tools service accepts only requests the gateway forwards

Values in .env are placeholders in this documentation, for example INITIAL_ADMIN_PASSWORD=<generated by scripts/generate_secrets.py>. Never copy a value from documentation into .env.

You choose one value yourself: INITIAL_ADMIN_EMAIL, the login of the first administrator.

Two are API keys that Wildbox issues once it is running, so .env starts with them empty: SENSOR_DATA_LAKE_API_KEY, the key the sensor sends telemetry with (scope data:ingest, see the deployment guide), and AUTOMATIONS_WILDBOX_API_KEY, the key of the optional automations workflows.


The First Administrator

On start-up the identity service creates a superuser from INITIAL_ADMIN_EMAIL and INITIAL_ADMIN_PASSWORD if no account with that email exists (CREATE_INITIAL_ADMIN=true, the default). It does not change an existing account, so editing .env after the first start does not change the password.

Read the generated password from .env, log in, and change it:

sed -n 's/^INITIAL_ADMIN_PASSWORD=//p' .env

Change it from the dashboard, or through the gateway with POST /api/v1/identity/admin/me/change-password and the body {"current_password": "<generated password>", "new_password": "<new password>"}. The new password must meet the password policy. The change ends every session of the account and the answer carries a new access_token for the caller. PATCH /auth/users/me does not change a password: it answers 400 and names this route. The Authentication guide lists the other password routes; all of them hash with Argon2id.


Authentication Reference

How login, tokens, logout and revocation, and the failed-login lockout work is described in one place: the Authentication and sessions guide.


Rotating Secrets

scripts/rotate_secrets.sh rotates one secret at a time and knows which ones depend on each other. For example, it refuses to rotate JWT_SECRET_KEY unless identity receives a separate API_KEY_HASH_SECRET, checked in the compose configuration and in the running container, because API-key digests would otherwise still be keyed by the JWT key:

make rotate-secrets                                   # list rotatable secrets
./scripts/rotate_secrets.sh --secret GATEWAY_INTERNAL_SECRET

A deployment that predates this check seeds API_KEY_HASH_SECRET from JWT_SECRET_KEY once, with make init-api-key-hash, so the API keys it has issued keep working; see UPGRADING.md.

The procedure and the reasoning behind it are in SECURITY_SECRETS_ROTATION.md.


Good Practice

  • Keep .env out of version control (it is in .gitignore) and readable only by the account that runs Docker.
  • Use a different .env for every environment; do not copy one between them.
  • Keep the backend ports bound to 127.0.0.1 and reach the services through the gateway; see Service ports.
  • Report a suspected credential leak as described in SECURITY.md.

Troubleshooting

  • Login returns 400: wrong email or password. If the account was created with an earlier .env, the password is the one from that file.
  • Login returns 429 with Retry-After: the account is locked for 15 minutes after 5 failed logins, even for the right password; see Failed-login lockout.
  • make validate-secrets fails: a placeholder is still in .env; run make generate-secrets again (it backs up the old file first).
  • An API key stopped working after a rotation: ./scripts/rotate_secrets.sh --list explains what rotating each secret invalidates.
  • identity exits naming API_KEY_HASH_SECRET: it is required unless ENVIRONMENT is development. On an existing deployment run make init-api-key-hash; on a fresh one, make generate-secrets.