Многоуровневые токены

Многоуровневые токены представляют собой механизм создания вложенных или производных ключей на основе одного исходного секрета. В контексте библиотеки Iron это достигается через последовательное применение криптографических операций: шифрования, подписи и деривации ключей. Основная цель — разграничение доступа и повышение безопасности без необходимости хранения множества независимых секретов.

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


Базовый уровень: мастер-токен

Мастер-токен — это первичный зашифрованный объект, созданный с использованием основного пароля или ключа. В Iron он формируется с помощью функции seal, которая объединяет:

  • сериализацию данных
  • симметричное шифрование (обычно AES)
  • HMAC-подпись для проверки целостности
const Iron = require('@hapi/iron');

const masterToken = await Iron.seal(
  { userId: 123, role: 'admin' },
  password,
  Iron.defaults
);

Особенности мастер-токена:

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

Второй уровень: производные токены

Производные токены создаются на основе уже существующего токена или его расшифрованного содержимого. Они используются для делегирования ограниченных прав.

Процесс:

  1. Расшифровка мастер-токена (unseal)
  2. Извлечение нужных данных
  3. Формирование нового объекта с урезанными правами
  4. Повторное шифрование
const data = await Iron.unseal(masterToken, password, Iron.defaults);

const limitedToken = await Iron.seal(
  { userId: data.userId, scope: 'read-only' },
  password,
  { ...Iron.defaults, ttl: 60000 }
);

Назначение:

  • ограничение доступа (например, только чтение)
  • временные токены для API
  • токены для сторонних сервисов

Третий уровень: одноразовые и контекстные токены

На этом уровне токены становятся максимально специализированными. Они могут включать:

  • одноразовые идентификаторы (nonce)
  • привязку к IP или устройству
  • минимальное время жизни (несколько секунд)
const ephemeralToken = await Iron.seal(
  {
    action: 'download',
    fileId: 456,
    nonce: crypto.randomUUID()
  },
  password,
  { ...Iron.defaults, ttl: 5000 }
);

Ключевые свойства:

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

Деривация ключей между уровнями

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

const crypto = require('crypto');

function deriveKey(baseKey, context) {
  return crypto
    .createHmac('sha256', baseKey)
    .update(context)
    .digest('hex');
}

const level1Key = deriveKey(masterPassword, 'level1');
const level2Key = deriveKey(masterPassword, 'level2');

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

  • компрометация одного уровня не затрагивает другие
  • изоляция контекстов (например, API vs UI)
  • гибкое управление безопасностью

Контроль времени жизни (TTL)

Каждый уровень токена может иметь собственный TTL:

  • мастер-токен: часы или дни
  • производный: минуты
  • одноразовый: секунды

Iron автоматически встраивает метку времени и проверяет её при unseal.

const options = {
  ...Iron.defaults,
  ttl: 30000 // 30 секунд
};

При попытке расшифровки просроченного токена будет выброшена ошибка.


Вложенные токены

Возможна ситуация, когда один токен содержит другой:

const nestedToken = await Iron.seal(
  { session: masterToken, permissions: limitedToken },
  password,
  Iron.defaults
);

Сценарии применения:

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

Проверка целостности на каждом уровне

Каждый токен в Iron содержит:

  • зашифрованные данные
  • соль
  • HMAC-подпись

Это означает, что изменение любого уровня вложенности приводит к ошибке при расшифровке.


Разграничение доступа через структуру данных

Многоуровневость можно реализовать не только через разные токены, но и через структуру внутри одного:

{
  user: {
    id: 123,
    roles: ['admin']
  },
  access: {
    api: true,
    adminPanel: false
  }
}

Затем на основе этих данных создаются разные токены с разными подмножествами информации.


Практические сценарии использования

1. Аутентификация + делегирование

  • мастер-токен хранится в cookie
  • производные токены используются для API-запросов

2. Временные ссылки

  • токен содержит fileId и TTL
  • используется для скачивания

3. Микросервисная архитектура

  • каждый сервис получает свой уровень токена
  • минимальный набор данных

4. Zero-trust системы

  • каждый запрос сопровождается новым токеном
  • строгая проверка контекста

Ошибки проектирования

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

Слишком длинный TTL → увеличивает окно атаки

Передача лишних данных → утечка чувствительной информации

Отсутствие nonce → возможность повторного использования токена


Оптимизация производительности

Многоуровневые токены увеличивают нагрузку из-за частых операций шифрования. Методы оптимизации:

  • кэширование расшифрованных данных (в пределах TTL)
  • уменьшение размера payload
  • использование асинхронных операций
  • минимизация вложенности

Сравнение с JWT

Характеристика Iron JWT
Шифрование Да Обычно нет
Подпись Да Да
Многоуровневость Гибкая Ограниченная
Контроль TTL Встроенный Через claims
Безопасность данных Высокая Зависит от реализации

Расширение модели

Многоуровневые токены можно комбинировать с:

  • OAuth (в качестве access token)
  • WebSockets (для авторизации соединений)
  • GraphQL (разные уровни доступа к схемам)

Структурирование стратегии токенов

Уровни можно формализовать:

Уровень Назначение TTL Ключ
L1 Сессия 24 часа masterKey
L2 API доступ 5 минут apiDerivedKey
L3 Одноразовые действия 10 секунд ephemeralKey

Безопасное удаление токенов

Iron не хранит состояние, поэтому отзыв токена реализуется через:

  • изменение ключа (инвалидация всех токенов)
  • хранение blacklist (например, Redis)
  • сокращение TTL

Интеграция с системами логирования

Каждый уровень токена может включать:

{
  traceId: 'abc123',
  issuedAt: Date.now()
}

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


Гибкость модели

Многоуровневые токены позволяют:

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

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