Protect application secrets

3 min read07 November 2026

A secret is a value that grants access: a database password, an API key, a bot token, a session key. It belongs neither in source code, nor in a file served by the web server, nor in a log. The basic rule fits in one sentence: configure secrets in the environment and revoke them as soon as they may have leaked.

1. Separate code from configuration

Code should run in several environments without modification. Read secrets from the environment and fail loudly when missing:

Python
import os

token = os.environ.get("API_TOKEN")
if not token:
    raise SystemExit("API_TOKEN missing")

Refusing to start is better than running with an empty value and failing later. On application hosting, variables are entered in the panel. Locally, use an explicitly loaded .env file listed in .gitignore, and commit only a .env.example with empty values.

2. Avoid leaks through logs

Logs are the most common leak because they are quiet. A connection exception may include the full URL with the password. log.info(os.environ) exposes everything. A token in a URL appears in access logs and browser history.

  • Never log a whole environment dictionary.
  • Redact sensitive values in error messages.
  • Put tokens in an Authorization header, not a query string.
  • Check that public error pages do not print tracebacks.

3. Reduce privileges

A secret should open as few doors as possible:

  • one database user per application, limited to its own database;
  • no GRANT option and no access to neighbouring databases;
  • minimal API scopes, not an administrator token;
  • distinct tokens per environment and per service;
  • a dedicated mailbox for automated mail.

If a component only needs to read, give it read-only access. That separation limits the impact of a compromise.

4. Rotate a secret

Rotation is a planned operation, not an emergency:

  1. Generate a new value with a password manager or openssl rand -base64 32.
  2. Update it in the panel or environment file.
  3. Restart the application and verify the connection.
  4. Revoke the old value at the issuing service.

If a secret was pushed to Git, revoke it immediately. Rewriting history with git filter-repo is not enough: clones, forks and caches may keep the old value.

5. Verify

  • git grep -nE "(TOKEN|SECRET|PASSWORD|API_KEY)=" returns nothing outside the example file.
  • .env, dumps and archives must not be reachable over HTTP: request the URL and expect 403 or 404.
  • Recent logs contain no token or connection string.
  • Every active secret has an owner, a creation date and a rotation procedure.

A secret shared between people or projects cannot be revoked cleanly: one account per use is also a matter of traceability.

Advertisement

Was this article helpful?

Read next