Programming with AI
ENRU
5.7

Secrets

tokens not in the code, not in git, not in the chat

What it is

A secret is something that grants access: a bot token, an API key, a database password. A leak costs money and data, and it cannot be undone: a published token is considered compromised forever and can only be revoked.

The three places secrets end up most often are the code, git and the chat with the AI. All three are closed by one technique.

What it looks like in code

Not allowed

BOT_TOKEN = "7123456789:AAE-abcdefghijklmnop"

It goes into git and stays in the history forever — even if you delete the line later. The history keeps every version.

Allowed

The secrets live in a .env file that is not in the repository:

measured
BOT_TOKEN=7123456789:AAE-abcdefghijklmnop
DB_PATH=data/bot.db

The code reads them from the environment:

import os


def require(name: str) -> str:
    value = os.environ.get(name)
    if not value:
        raise RuntimeError(f"environment variable {name} is not set")
    return value


BOT_TOKEN = require("BOT_TOKEN")
DB_PATH = os.environ.get("DB_PATH", "bot.db")

Starting without the variable fails immediately and clearly:

measured
RuntimeError: environment variable BOT_TOKEN is not set

That matters more than it seems. Without the require function a missing token would be None, the program would get as far as the API request and fail there — a long way from the cause.

The mandatory line

measured
.env

in .gitignore. To check that it worked:

git status --short

If .env is in the output it is not being ignored yet, and the next git add -A will send it to the repository.

The difference between .env and .env.example

What goes into the repository is an example with no values:

measured
BOT_TOKEN=
DB_PATH=data/bot.db

It shows which variables are needed and reveals nothing.

Secrets and the AI

A separate case, and one people rarely think about.

Don't paste files with secrets into a chat. Not .env, not a config with passwords, not a log that may contain a token (article 4.2).

Look over code with your own eyes before sending it. Especially when copying a whole file: a token on line twenty is easy to miss.

With a terminal agent it reads the files itself — including .env, unless told otherwise:

Prompt
Don't read the .env file and don't include its contents in
your replies. If you need the variable names, take them from
.env.example.

A request like this helps, but it is a request, not a lock: the agent may forget it by the end of a long session or read the file through a command. It is more reliable to close access in the tool's own settings — agents have lists of forbidden files and allowed commands. And keep real production keys out of the folder the agent works in altogether: a test token is enough there.

If a secret has already been sent — revoke it. That takes five minutes and is the only action that actually solves the problem.

What to tell the AI

Prompt
The token must come from the BOT_TOKEN environment variable.
It must not appear in the code. If the variable isn't set,
fail at startup with a clear message.
Prompt
Check this file: is there anything in it that must not be
committed to a public repository?

What to look for

A token in example code. The AI often writes TOKEN = "your-token-here" — that is fine, but the line is easy to forget to replace with a read from the environment.

.env without .gitignore. The first thing worth checking in a new project.

A secret in an error message. raise ValueError(f"key {key} was rejected") — and the key is in the logs.

A secret in a screenshot. A terminal showing environment variables, sent into a chat with "look at this error".

A database in the repository. *.db belongs in .gitignore — those usually hold user data.

Cheat sheet

  • Secrets come from environment variables only; they are not in the code.

  • .env in .gitignore, .env.example without values in the repository.

  • No variable — fail at startup with a clear message.

  • Got into git — deleting the line isn't enough, revoke the token.

  • Don't paste .env, configs or logs into a chat unexamined.

  • Tell an agent outright: do not read .env — and, more reliably, forbid it in the tool's settings.