Edge Functions модель безопасности
Правила, которые сохраняют конфиденциальность ваших функций, их кода и секретов, а также места, где вы несете ответственность.
1. Ключи и роли
| Роль | Ключ | Могу сделать |
|---|---|---|
anon | Открытый ключ, безопасный в браузере | Вызов функции |
authenticated | Открытый ключ плюс JWT вошедшего пользователя. | Вызов функции с идентификатором пользователя |
service_role | Секретный ключ, только сервер | Все: развертывание, чтение кода и секретов, задания, cron, оповещения. |
admin | Консольный сеанс в Студии | Всё из студии |
Роль определяется ключом и токеном, которые проверяет платформа. Клиент не может его выбрать: вызов с открытым ключом и заголовком x-aura-role: service_role все равно достигает вашей функции как anon.
Каждый маршрут и его роль перечислены в справочнике HTTP API .
2. Почему публично доступен только вызов
Открытый ключ публикуется в вашем веб-приложении или мобильном приложении, поэтому его может прочитать любой. Все, что разрешено, разрешено каждому. Вызов функции — это единственная операция, предназначенная для этого: ваш код решает, что может сделать вызывающая сторона.
Чтение определения функции происходит по-другому. Он содержит исходный код и переменные среды, которые часто содержат секреты. В списке вакансий и оповещений отображаются ваши данные. Постановка задания в очередь запускает ваш код в соответствии с вашей квотой. Ни один из них не может быть общедоступным, и платформа отклоняет их с помощью 403 для любого ключа, кроме service_role.
Такой же раскол существует и в других местах. Supabase проверяет JWT пользователя перед запуском пограничной функции по умолчанию (verify_jwt = true) и развертывает функции через интерфейс командной строки и платформу (docs). Firebase ставит задачи из среды доверенного сервера через Admin SDK с разрешением IAM (docs). Cloudflare позволяет только работнику отправлять в очередь через привязку (docs).
Более ранние версии сервиса отвечали GET /v1/functions и GET /v1/functions/{name} на любую клавишу. Если ваш проект выполнялся в развертывании, предшествующем этому исправлению, рассматривайте код и переменные ваших функций как открытые и меняйте содержащиеся в них секреты. См. обновление до версии 0.6.
3. Личность нельзя подделать
Ваша функция считывает вызывающего абонента из x-aura-role, x-aura-user-id и x-aura-project-id. Платформа устанавливает их после проверки ключа и токена.
- Вызывающий абонент не может их предоставить. Платформа отбрасывает
authorization,apikey,x-request-idи любой заголовокx-aura-*, отправленный вheadersвызова, независимо от их случая. В реальном тесте вызов сx-aura-role: service_roleи поддельнымauthorizationдостиг функцииrole: "anon"безauthorization. - Другие пользовательские заголовки остаются нетронутыми. Рассматривайте их как пользовательский ввод.
- Задания и запуск cron достигают вашей функции без идентификационных заголовков. Они запускаются платформой, а не пользователем.
Поэтому авторизуйте x-aura-role и x-aura-user-id, а не значение из тела:
4. Песочница
Что дает вам платформа:
- Каждый вызов выполняется в отдельной версии V8 со своим лимитом памяти и тайм-аутом настенных часов. Сбой или бесконечный цикл в одном вызове не влияет на другой.
- Переменные среды хоста невидимы:
Deno.env.get('PATH')вернулundefinedпри реальном запуске. Присутствуют только переменные вашей функции и переменныеAURABASE_*платформы. - Код одного проекта не может быть прочитан другим: сервису, который его обслуживает, требуется внутренний токен.
- Ответы, которые могут запускать сценарии, обрабатываются с помощью политики безопасности содержимого изолированной программной среды, а заголовки
Set-Cookieи CORS из функции удаляются. См. ответы .
Что дает вам , а не:
- Исходящая сеть открыта, пока вы её не ограничите. Если
permissions.allow_netперечисляет хотя бы один хост, среда выполнения отклоняетfetchк любому другому хосту (Requires net access to "host:443"). Пустой список, значение по умолчанию, ничего не ограничивает. Перечислите каждый хост, который нужен функции, включая URL вашего проекта, если она обращается к платформе. Даже со списком проверяйте любой URL, полученный из пользовательского ввода. - Никакой защиты ваших секретов в журналах. Все, что ваша функция записывает с помощью
console.log, попадает в журналы среды выполнения. - Нет ограничений на пользователя. Ограничение частоты вызовов установлено для каждого IP-адреса клиента. Добавьте собственную проверку, если один пользователь не должен вызывать функцию более нескольких раз.
5. Контрольный список
- Ключ
service_roleсуществует только на ваших серверах и в ваших секретах CI. - Пакет браузера содержит только открытый ключ. SDK по умолчанию отклоняет ключ
service_roleв браузере. - Каждая функция проверяет
x-aura-role, прежде чем сделать что-то важное. - Секреты — это переменные функции, а не
index.ts. - Функции, вызывающие внешние URL-адреса, проверяют место назначения.
- Вы меняете ключ, создавая новый в Studio, развертывая его как секретный, а затем отзывая старый.