Назад в блог

Начало работыИнструкция

Как хранить API-ключ: переменная окружения, .gitignore, утечка

Уберите ключ CheapTokens из кода и git: переменная окружения, .env в .gitignore и что делать в первую очередь, если ключ утёк.

Автор: CheapTokens TeamОпубликовано 5 мин чтения

Терминал с экспортом переменной окружения и строкой .gitignore для API-ключа
Содержание
  1. Почему ключ не место в коде
  2. Шаг 1: положите ключ в переменную окружения
  3. Шаг 2: файл .env, который не попадёт в коммит
  4. Если ключ утёк: что делать и в каком порядке
  5. Проверьте себя

Держите ключ в переменной окружения, а не в коде, а файл .env не пускайте в git строкой в .gitignore. Если ключ уже оказался на виду, сначала займитесь самим ключом, а порядок наводите потом: чистить историю git, пока ключ всё ещё лежит в коде и инструментах, бессмысленно.

Вот и вся идея. Это практическая версия, а основы — в статье Что такое API-ключ. Дальше: три команды, один рабочий запрос и короткий план на случай плохого дня.

Почему ключ не место в коде#

API-ключ — это пароль, который тратит ваши деньги. У кого он есть, тот отправляет запросы с вашего баланса, и сервис не отличит его от вас.

Ошибка обычно скучная. Вы вставили ключ в скрипт, чтобы заработал первый запрос, всё сработало, вы сделали git push — а репозиторий публичный. Или отправили коллеге конфиг. Или сфотографировали ошибку, где в углу виден ключ. Результат один и тот же.

GitHub хорошо знает этот сценарий. Его secret scanning (документация GitHub, проверено 29 октября 2026) просматривает всю историю Git на всех ветках в поисках жёстко прописанных ключей и токенов, а ещё issues, pull request'ы, обсуждения, вики и секретные gist'ы, и при находке создаёт оповещение. Поэтому удалить строку в следующем коммите мало: в старом коммите она осталась.

Вот тот же скрипт до и после.

Сравнение

Тот же скрипт, ключ вынесен из кода

Ключ в коде

python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key="<your-key>",  # вставлен сюда: попадёт в git
)

Ключ из окружения

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

Вторую версию можно спокойно выложить на GitHub, отправить в чат или на ревью. Ключ остаётся на вашем компьютере, вне файла.

Шаг 1: положите ключ в переменную окружения#

Переменная окружения — это именованное значение, которое терминал передаёт каждой запущенной программе. Скрипт просит CHEAPTOKENS_API_KEY по имени и не знает, откуда оно взялось.

macOS и Linux:

bash
export CHEAPTOKENS_API_KEY="<your-key>"

Windows PowerShell:

powershell
setx CHEAPTOKENS_API_KEY "<your-key>"

На двух мелочах спотыкаются чаще всего. export действует только в этом окне терминала, поэтому чтобы значение осталось, добавьте строку в профиль оболочки (~/.zshrc или ~/.bashrc). А setx не меняет окно, где вы его набрали: перед проверкой откройте новый терминал.

Теперь полный запрос. Он идёт на OpenAI-совместимый адрес https://api.cheaptokens.dev/v1 и использует DeepSeek-V4-Flash с полным id (deepseek-ai/DeepSeek-V4-Flash-0731; id берите из документации CheapTokens — у разных провайдеров имена отличаются):

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Say hi in five words."}],
)
print(resp.choices[0].message.content)
print(resp.usage)

Короткое приветствие — это примерно 20 токенов на входе и 20 на выходе, по текущим ценам $0.0000023 (полный список — на странице цен). Если первого запроса у вас ещё не было, начните со статьи Первый запрос к API CheapTokens.

Ответ модели приходит в choices[0].message.content, а usage показывает, сколько токенов она насчитала. Ключа в файле нет.

Терминал с командами для .env и .gitignore
Три команды, которые держат ключ вне git

Шаг 2: файл .env, который не попадёт в коммит#

Набирать export в каждом новом окне быстро надоедает. Файл .env хранит значение в одном месте, рядом с проектом:

text
CHEAPTOKENS_API_KEY=<your-key>

Python читает его через python-dotenv (pip install python-dotenv):

python
from dotenv import load_dotenv
load_dotenv()  # заполняет os.environ из .env

Файл безопасен, только если git его не видит. Добавьте его в .gitignore до первого коммита:

bash
echo ".env" >> .gitignore
git check-ignore -v .env

Если всё верно, вторая команда выведет что-то вроде .gitignore:1:.env .env: git сам называет правило, которое скрывает файл. Если вывода нет, правило не работает. В Windows создайте .gitignore в редакторе со строкой .env или используйте Add-Content .gitignore .env: >> в PowerShell может записать UTF-16, и git такой файл может не прочитать.

Одна ловушка: .gitignore действует только на файлы, которые git ещё не отслеживает. Если .env когда-то уже попал в коммит, выполните git rm --cached .env, чтобы git перестал его отслеживать, а ключ внутри считайте раскрытым (об этом ниже). Хорошая привычка — коммитить .env.example с именем переменной и заглушкой вместо значения: коллега поймёт, что ему задать.

Если ключ утёк: что делать и в каком порядке#

Может быть, ключ ушёл в публичный репозиторий, мелькнул на скриншоте или вы вставили весь конфиг в тему на форуме. Порядок важнее скорости любого отдельного шага.

Рекомендация самого GitHub (та же страница, проверено 29 октября 2026): сразу заменить секрет; переписывать историю Git необязательно и часто не нужно, если секрет уже отозван. Люди обычно делают наоборот: час чистят историю, пока ключ всё ещё работает. Не делайте так.

Выберите свой случай

Что случилось с ключом? Выберите ближайший случай

Ключ был в коммите, который стал публичным

Сначала уберите ключ из кода, перейдите на переменную окружения, добавьте .env в .gitignore и посмотрите на баланс: нет ли запросов, которых вы не отправляли. Чистка истории — приятное дополнение, а не срочное дело.

Ключ попал на скриншот или в отправленный файл

Тот же порядок: перестаньте использовать этот ключ в инструментах и перейдите на переменную окружения, потом удалите пост или файл, если можете. Удалённый скриншот мог успеть скопироваться, так что на одно удаление не рассчитывайте.

Один ключ используется в нескольких инструментах

Пройдите по всем местам, где лежал ключ: профиль оболочки, файлы .env, редактор и терминальные инструменты, и направьте каждое на переменную окружения — менять придётся в одном месте. Если инструмент не прочитал переменную, как выглядит ошибка, показано в разборе 401/404.

Три шага после утечки: убрать ключ из кода, обновить все инструменты, отправить тестовый запрос
Сначала ключ из кода, потом все инструменты, потом проверка

Когда порядок наведён, отправьте один небольшой запрос, как в шаге 1, и посмотрите на баланс. Ответил, а баланс и запросы выглядят обычно — уборка закончена; ещё несколько дней поглядывайте на баланс. Ключ, который был на виду, считайте раскрытым, даже когда убрали его из кода: следите за балансом и числом запросов, нет ли чужих, и не используйте этот ключ в новых местах. А где ключи обычно прячутся, подскажет статья Куда подключить свой API-ключ.

Проверьте себя#

Попробуйте самиПопробуйте: уберите переменную и запустите скрипт. Что вы увидите?Показать ответ

Python остановится с KeyError: 'CHEAPTOKENS_API_KEY' ещё до того, как запрос уйдёт с вашего компьютера. Это хороший сбой: скрипт отказывается работать без ключа, а не берёт молча вставленный. Если вместо этого пришла ошибка 401, переменная задана, но ключ неверный; сверьте ключ и адрес по разбору 401/404.