Защита API-ключей

API-ключ является основным механизмом аутентификации при работе с HERE Maps API. Любой запрос к картографическим сервисам, геокодированию, маршрутизации, поиску объектов или другим компонентам платформы выполняется от имени проекта, которому принадлежит данный ключ.

Компрометация ключа приводит к ряду рисков:

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

Защита API-ключей является обязательной частью архитектуры любого веб-приложения, использующего HERE Maps.


Как работает API-ключ HERE

После создания проекта в панели разработчика HERE выдается уникальный API Key.

Типичный пример подключения библиотеки:

<script src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>

Инициализация платформы:

const platform = new H.service.Platform({
    apikey: 'YOUR_API_KEY'
});

После этого ключ автоматически используется для взаимодействия с сервисами HERE.


Основная проблема клиентского JavaScript

В браузере невозможно полностью скрыть API-ключ.

Даже если код минифицирован:

const platform=new H.service.Platform({
    apikey:"abc123xyz"
});

ключ остается доступным:

  • через инструменты разработчика;
  • через просмотр исходного кода;
  • через вкладку Network;
  • через сохранение JavaScript-файлов.

Поэтому защита API-ключа строится не на полном сокрытии, а на минимизации возможного ущерба.


Ошибки хранения ключей

Жесткое встраивание ключа в код

Плохой пример:

const platform = new H.service.Platform({
    apikey: 'A1B2C3D4E5F6'
});

Недостатки:

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

Хранение ключа в публичном конфигурационном файле

Плохой пример:

{
    "apiKey": "A1B2C3D4E5F6"
}

Файл:

/public/config.json

будет доступен любому пользователю через браузер.


Размещение ключа в HTML

Плохой пример:

<meta name="here-api-key" content="A1B2C3D4E5F6">

Содержимое страницы легко просматривается через DevTools.


Использование переменных окружения

Наиболее распространенный способ управления конфигурацией — переменные окружения.

Пример для Vite:

VITE_HERE_API_KEY=YOUR_KEY

Использование:

const platform = new H.service.Platform({
    apikey: import.meta.env.VITE_HERE_API_KEY
});

Пример для Webpack:

HERE_API_KEY=YOUR_KEY
const platform = new H.service.Platform({
    apikey: process.env.HERE_API_KEY
});

Важно понимать, что после сборки приложения значение всё равно попадет в клиентский код.

Преимущество такого подхода заключается не в сокрытии ключа от пользователей, а в:

  • централизованном управлении конфигурацией;
  • исключении ключей из репозитория;
  • упрощении ротации;
  • разделении сред разработки и продакшена.

Исключение ключей из Git

Файл:

.env

не должен попадать в систему контроля версий.

Пример .gitignore:

.env
.env.local
.env.production
.env.development

Частая ошибка:

git add .
git commit -m "Initial commit"

после чего ключ навсегда сохраняется в истории Git.

Даже удаление файла позже не гарантирует удаление ключа из истории репозитория.


Разделение ключей по окружениям

Хорошей практикой считается использование отдельных ключей для разных сред.

Структура:

Development
Testing
Staging
Production

Пример:

VITE_HERE_API_KEY_DEV=...
VITE_HERE_API_KEY_STAGE=...
VITE_HERE_API_KEY_PROD=...

Преимущества:

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

Ограничение доменов

Одним из наиболее эффективных механизмов защиты является ограничение использования ключа определёнными доменами.

Пример разрешенных источников:

https://example.com
https://www.example.com
https://app.example.com

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

https://attacker-site.com

запросы будут отклоняться.

Подобная настройка значительно снижает вероятность успешного злоупотребления.


Использование серверного прокси

Наиболее безопасная архитектура предполагает перенос критически важных запросов на сервер.

Небезопасная схема

Browser
   |
   | API Key
   |
HERE API

Ключ доступен пользователю.


Более безопасная схема

Browser
   |
Backend
   |
HERE API

В этом случае:

  1. Браузер обращается к серверу.
  2. Сервер хранит ключ.
  3. Сервер выполняет запрос к HERE.
  4. Клиент получает только результат.

Пример на Node.js:

import express from 'express';
import fetch from 'node-fetch';

const app = express();

app.get('/api/geocode', async (req, res) => {
    const query = req.query.q;

    const response = await fetch(
        `https://geocode.search.hereapi.com/v1/geocode?q=${query}&apiKey=${process.env.HERE_API_KEY}`
    );

    const data = await response.json();

    res.json(data);
});

Ключ никогда не попадает в браузер.


Какие запросы стоит переносить на сервер

Особенно рекомендуется серверная обработка для:

  • геокодирования адресов;
  • обратного геокодирования;
  • расчёта маршрутов;
  • матриц расстояний;
  • пакетной обработки координат;
  • аналитических сервисов;
  • внутренних бизнес-операций.

Клиентская часть должна получать уже готовые данные.


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

Даже хорошо защищенный ключ необходимо периодически менять.

Причины ротации:

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

Процесс выглядит следующим образом:

  1. Создается новый ключ.
  2. Новый ключ внедряется в приложение.
  3. Проверяется работоспособность.
  4. Старый ключ удаляется.

Старая схема:

Application -> KEY_A

Переходный этап:

Application -> KEY_A
Application -> KEY_B

После завершения:

Application -> KEY_B

Мониторинг использования

Контроль активности API помогает выявлять утечки на ранних этапах.

Следует отслеживать:

  • количество запросов;
  • резкие скачки нагрузки;
  • необычные регионы использования;
  • изменение шаблонов запросов;
  • ошибки авторизации.

Подозрительными признаками являются:

Обычно: 10 000 запросов/сутки
Сегодня: 500 000 запросов/сутки

или

Приложение работает в Казахстане
Запросы идут из десятков стран одновременно

Такие события требуют немедленной проверки ключа.


Автоматическое обнаружение утечек

Современные CI/CD-процессы часто включают сканирование секретов.

Популярные инструменты:

GitLeaks
TruffleHog
GitGuardian
detect-secrets

Они анализируют:

  • коммиты;
  • pull request;
  • историю Git;
  • конфигурационные файлы;
  • исходный код.

Пример проверки:

gitleaks detect

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


Защита в CI/CD

Секреты не должны храниться в коде пайплайнов.

Плохой пример:

env:
  HERE_API_KEY: A1B2C3D4E5F6

Правильный подход:

env:
  HERE_API_KEY: ${{ secrets.HERE_API_KEY }}

Ключ хранится в защищенном хранилище платформы CI/CD.


Работа с Docker

Нежелательно встраивать ключ непосредственно в образ.

Плохой пример:

ENV HERE_API_KEY=A1B2C3D4E5F6

Безопаснее использовать переменные среды во время запуска контейнера:

docker run \
  -e HERE_API_KEY=YOUR_KEY \
  my-app

Или использовать менеджеры секретов.


Использование Secret Manager

В крупных проектах ключи обычно не хранятся в файлах .env.

Применяются специализированные системы:

AWS Secrets Manager
Google Secret Manager
Azure Key Vault
HashiCorp Vault

Преимущества:

  • централизованное хранение;
  • аудит доступа;
  • автоматическая ротация;
  • шифрование секретов;
  • контроль прав пользователей.

Что делать при утечке API-ключа

Типичный алгоритм реагирования:

  1. Зафиксировать инцидент.
  2. Проверить журналы использования.
  3. Создать новый ключ.
  4. Обновить конфигурацию приложения.
  5. Отозвать старый ключ.
  6. Проверить историю Git.
  7. Проверить публичные репозитории.
  8. Провести анализ причин утечки.

Пример экстренной замены:

const platform = new H.service.Platform({
    apikey: process.env.HERE_API_KEY_NEW
});

После подтверждения работоспособности старый ключ должен быть немедленно деактивирован.


Практический чек-лист безопасности

Обязательно

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

Желательно

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

Недопустимо

  • публиковать ключи в GitHub;
  • хранить ключи в HTML;
  • передавать ключи через публичные API;
  • использовать один ключ для всех сред;
  • оставлять скомпрометированные ключи активными;
  • встраивать секреты непосредственно в исходный код проекта.