Где хранить API-ключи в PHP-проекте и чего точно не делать

API-ключи часто появляются в проекте незаметно: ключ CRM, токен маркетплейса, SMTP-пароль, webhook URL, доступ к платёжной системе. Сначала их кладут в config.php, потом копируют в тестовый скрипт, потом случайно коммитят в git, а через год никто не знает, где ключи используются.

Секреты нужно хранить так, чтобы их было удобно использовать приложению, но сложно случайно показать пользователю, записать в лог или отправить в репозиторий.

Не хранить ключи в шаблонах и контроллерах

Плохой вариант:

$token = 'abc123-secret-token';
$client = new ApiClient($token);

Такой токен легко попадает в git, архив проекта, debug-дамп или скриншот. Ключи не должны быть частью бизнес-логики.

.env вне публичной директории

Для многих PHP-проектов нормальный вариант — env-файл или переменные окружения. Но файл не должен лежать в директории, доступной из браузера.

/var/www/site.ru
    .env
    app/
    web/
        index.php

nginx должен смотреть в web, а не в корень проекта:

root /var/www/site.ru/web;

Если .env доступен по URL, это критическая ошибка.

gitignore

Файлы с секретами должны быть исключены из git.

.env
.env.local
config/secrets.php
runtime/
*.key

Если секрет уже попал в git, одного удаления файла недостаточно. Его нужно считать скомпрометированным и заменить.

Права на файлы

Секреты должны читаться пользователем приложения и не должны быть доступны всем пользователям сервера.

chown deploy:www-data .env
chmod 640 .env

Пользователи и группы зависят от сервера. Идея простая: не делать chmod 777 и не открывать конфиг всем.

Не писать секреты в логи

Иногда разработчик логирует весь запрос к API, включая headers. Так токен оказывается в app.log.

// плохо
Yii::info($requestHeaders, 'api');

// лучше
Yii::info([
    'method' => 'orders.create',
    'token_present' => !empty($token),
], 'api');

Если нужно логировать запрос, секретные поля нужно маскировать.

Технические пользователи

Для интеграций лучше использовать отдельного технического пользователя или отдельный API-ключ, а не личный доступ менеджера. Если сотрудник уволится, интеграция не должна остановиться из-за его аккаунта.

  • понятное имя технического пользователя;
  • минимально нужные права;
  • записано, где используется ключ;
  • есть процедура замены;
  • доступ не привязан к личной почте сотрудника.

Ротация ключей

Ключи нужно уметь менять. Если замена токена требует искать его по всему проекту, хранение уже организовано плохо.

Практичный порядок:

  1. Создать новый ключ во внешнем сервисе.
  2. Добавить его в env или секретное хранилище.
  3. Перезапустить приложение или очистить кэш настроек.
  4. Проверить интеграцию.
  5. Отключить старый ключ.

Проверка утечек

Полезно периодически искать секреты в проекте.

grep -R "api_key" -n .
grep -R "token" -n config app local
grep -R "password" -n config app local

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

Чек-лист

  1. Убрать ключи из кода и шаблонов.
  2. Хранить секреты вне web root.
  3. Добавить env-файлы в .gitignore.
  4. Проверить права на файлы с секретами.
  5. Не писать токены и пароли в логи.
  6. Использовать технических пользователей для интеграций.
  7. Документировать, где используется каждый ключ.
  8. Иметь понятный порядок ротации.

Хранение API-ключей — это не только вопрос безопасности. Это ещё и вопрос поддержки. Когда понятно, где лежит ключ, кто им пользуется и как его заменить, интеграция перестаёт зависеть от случайных файлов и личных аккаунтов.

Комментарии (0)

Пока нет комментариев. Будьте первым!