Edge Runtime: Cloudflare Workers, Vercel Edge

Среды исполнения на базе Edge (Cloudflare Workers, Vercel Edge Runtime) принципиально отличаются от классического Node.js. Основное отличие заключается в том, что отсутствует доступ к большинству Node.js встроенных модулей (crypto, fs, net, stream в привычном виде). Вместо этого используется стандартизированная Web Platform API, включая WebCrypto API, Fetch API и Web Streams.

Библиотека jose изначально проектировалась с учётом этих ограничений. В отличие от многих JWT-библиотек старого поколения, она не полагается на Node.js crypto напрямую, а использует унифицированный слой криптографии через crypto.subtle.

Ключевая особенность:

  • поддержка WebCrypto как основного backend-а
  • отсутствие обязательных Node.js зависимостей
  • корректная работа в изолированных средах выполнения
  • совместимость с ESM-модулями

Это делает jose одной из стандартных библиотек для работы с JWT, JWS, JWE в Edge Runtime.


WebCrypto API как основа криптографии

Edge-окружения предоставляют объект crypto.subtle, который реализует низкоуровневые криптографические операции:

  • генерация ключей
  • подпись данных
  • верификация подписи
  • шифрование и расшифрование

jose полностью опирается на этот API.

Пример ключевых возможностей WebCrypto:

  • subtle.sign()
  • subtle.verify()
  • subtle.encrypt()
  • subtle.decrypt()
  • subtle.importKey()
  • subtle.exportKey()

Особенность Edge Runtime заключается в том, что все операции являются асинхронными и возвращают Promise.


Архитектура jose в Edge-средах

Внутри jose используется разделение на несколько уровней:

  • JWT слой (работа с токенами)
  • JWS слой (подпись и проверка подписи)
  • JWE слой (шифрование и дешифрование)
  • JWK слой (работа с ключами в JSON формате)

Каждый слой не зависит от Node.js специфики, а использует абстракции поверх WebCrypto.

В Edge Runtime отсутствует fallback на Node.js crypto, поэтому поведение становится более предсказуемым и унифицированным между платформами.


Cloudflare Workers: особенности интеграции

Cloudflare Workers предоставляют полностью Web-совместимую среду. Это означает, что jose работает без дополнительных адаптеров.

Типичная особенность:

  • импорт только ESM модулей
  • использование глобального crypto
  • строгая изоляция памяти
  • ограниченное время выполнения

Пример использования JWT в Cloudflare Workers:

import { jwtVerify, SignJWT } from 'jose'

const secret = new TextEncoder().encode('super-secret-key')

export default {
  async fetch(request) {
    const token = await new SignJWT({ userId: 123 })
      .setProtectedHeader({ alg: 'HS256' })
      .setIssuedAt()
      .setExpirationTime('2h')
      .sign(secret)

    const { payload } = await jwtVerify(token, secret)

    return new Response(JSON.stringify(payload), {
      headers: { 'Content-Type': 'application/json' }
    })
  }
}

Важный момент: отсутствует необходимость в polyfill-ах или дополнительных криптографических библиотеках.


Vercel Edge Runtime: особенности выполнения

Vercel Edge Runtime также построен на Web Standards API, но имеет свои ограничения:

  • отсутствует Node.js Buffer
  • запрещены некоторые синхронные API
  • обязательное использование ESM
  • строгая оптимизация размера бандла

jose полностью совместим с этим окружением, так как не требует Node-specific API.

Пример использования в Edge Function:

import { jwtVerify } from 'jose'

const secret = new TextEncoder().encode(process.env.JWT_SECRET)

export const config = {
  runtime: 'edge'
}

export default async function handler(req) {
  const token = req.headers.get('authorization')?.replace('Bearer ', '')

  if (!token) {
    return new Response('Unauthorized', { status: 401 })
  }

  const { payload } = await jwtVerify(token, secret)

  return new Response(JSON.stringify(payload), {
    headers: { 'Content-Type': 'application/json' }
  })
}

Работа с алгоритмами подписи

В Edge Runtime доступен набор алгоритмов, поддерживаемых WebCrypto. jose автоматически использует доступные реализации.

Наиболее распространённые алгоритмы:

  • HS256 / HS384 / HS512 (HMAC)
  • RS256 / RS384 / RS512 (RSA-PSS/RSASSA-PKCS1-v1_5)
  • ES256 / ES384 / ES512 (ECDSA)
  • EdDSA (Ed25519)

Пример генерации и проверки RSA JWT:

import { generateKeyPair, SignJWT, jwtVerify } from 'jose'

const { privateKey, publicKey } = await generateKeyPair('RS256')

const token = await new SignJWT({ role: 'admin' })
  .setProtectedHeader({ alg: 'RS256' })
  .setExpirationTime('1h')
  .sign(privateKey)

const verified = await jwtVerify(token, publicKey)

Работа с JWK (JSON Web Key)

Edge Runtime особенно эффективно работает с JWK, так как ключи можно сериализовать и передавать между сервисами без бинарных форматов.

import { importJWK, jwtVerify } from 'jose'

const jwk = {
  kty: 'oct',
  k: 'c2VjcmV0a2V5',
  alg: 'HS256'
}

const key = await importJWK(jwk, 'HS256')

const result = await jwtVerify(token, key)

Преимущество JWK в Edge-среде заключается в:

  • удобстве хранения в переменных окружения
  • совместимости с OAuth2/OpenID Connect
  • отсутствии необходимости в бинарных буферах

Производительность в Edge Runtime

Edge-среды оптимизированы для минимальной задержки. jose учитывает это за счёт:

  • отсутствия синхронных крипто-операций
  • ленивой инициализации ключей
  • минимизации преобразований данных
  • использования нативного WebCrypto без промежуточных слоёв

Однако есть особенности:

  • операции подписи RSA и ECDSA тяжелее HMAC
  • импорт ключей может быть дороже, чем повторное использование
  • JWK парсинг влияет на cold start

Особенности bundling и tree-shaking

В Edge Runtime критически важен размер бандла. jose спроектирован с поддержкой tree-shaking:

  • импортируются только используемые функции
  • JWE и JWS модули изолированы
  • нет обязательной загрузки всей криптографической поверхности

Пример корректного импорта:

import { SignJWT } from 'jose'

Вместо:

import * as jose from 'jose'

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


Ограничения Edge-сред

Несмотря на совместимость, существуют системные ограничения:

  • нет доступа к файловой системе
  • невозможность использования native addons
  • ограничение по времени выполнения
  • отсутствие потоковой Node.js криптографии
  • строгая изоляция памяти между запросами

jose адаптируется к этим условиям через:

  • чисто асинхронную модель
  • отсутствие глобального состояния
  • использование стандартов Web APIs

Потоковая обработка JWE

В Edge Runtime поддерживается потоковая работа с зашифрованными данными через Web Streams API.

Это позволяет обрабатывать большие payload без загрузки всего объекта в память.

import { compactDecrypt } from 'jose'

const { plaintext } = await compactDecrypt(jwe, privateKey)

Хотя операция возвращает результат целиком, внутренняя обработка может использовать потоковые механизмы платформы.


Совместимость между Cloudflare Workers и Vercel Edge

Обе платформы следуют стандартам Web Platform, но различия проявляются в деталях:

  • Cloudflare имеет более строгую изоляцию и собственную реализацию V8 isolate
  • Vercel Edge ближе к V8 Worker Threads модели
  • различия в переменных окружения и cold start поведении

jose абстрагирует эти различия, обеспечивая одинаковый API слой.


Практика безопасного хранения ключей

В Edge Runtime ключи обычно хранятся:

  • в environment variables
  • в secret storage платформы
  • в виде JWK JSON

HMAC пример:

const secret = new TextEncoder().encode(process.env.SECRET_KEY)

RSA пример через JWK:

const privateKey = await importJWK(JSON.parse(process.env.PRIVATE_JWK))

Использование в микросервисной архитектуре Edge

Edge Runtime часто применяется как слой:

  • авторизации
  • проверки JWT
  • проксирования запросов
  • валидации токенов перед обращением к backend API

jose становится стандартным инструментом для:

  • проверки access tokens
  • валидации ID tokens
  • дешифрования JWE payload

Это позволяет переносить часть security logic ближе к пользователю, снижая latency.