npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ycforge/auth

v0.3.0

Published

Shared authentication strategies for Yandex Cloud (IAM tokens, metadata service, service account keys) and YDB, with adapters for @ydbjs/auth and NestJS

Readme

@ycforge/auth

Общая логика аутентификации для API Яндекс Облака и YDB, выделенная из @ycforge/ydb-orm и @ycforge/yandex-kms-orm-provider.

  • Нулевое количество runtime-зависимостей в ядре (только Node.js builtins + глобальный fetch).
  • Кэширование токенов с запасом 60 секунд и single-flight обновлением.
  • Встроенный retry с экспоненциальным бэкоффом (5 попыток, базовая задержка 100 мс, множитель 10).
  • Capability-матрица: каждый запрос токена проверяется на совместимость с целевым использованием.
  • Опциональные адаптеры: @ydbjs/auth (драйвер YDB) и NestJS.

Требуется Node.js >= 22 (ESM).

Установка

yarn add @ycforge/auth
# опционально, для YDB-адаптера:
yarn add @ydbjs/auth
# опционально, для NestJS-модуля:
yarn add @nestjs/common reflect-metadata

Быстрый старт

import { createAuth, YCLOUD_AUTH_USAGE } from '@ycforge/auth';

const auth = createAuth({ type: 'metadata' });
const token = await auth.getToken(YCLOUD_AUTH_USAGE);

Стратегии

iam_token — статический IAM-токен

const auth = createAuth({
  type: 'iam_token',
  token: process.env.IAM_TOKEN!,
  // опционально: после наступления этого момента getToken() будет бросать ошибку
  // вместо возврата заведомо протухшего токена (Date, ISO-строка или unix s/ms)
  expiresAt: '2026-09-01T00:00:00Z',
});

metadata — сервис метаданных ВМ

const auth = createAuth({
  type: 'metadata',
  // значения по умолчанию:
  endpoint:
    'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token',
  flavor: 'Google',
});

auth_key — авторизованный ключ сервисного аккаунта

Подписывает JWT с алгоритмом PS256 и обменивает его на IAM-токен по адресу https://iam.api.cloud.yandex.net/iam/v1/tokens (таймаут 10 с на запрос, retry с бэкоффом, тела HTTP-ошибок никогда не логируются).

import { createAuth, authKeyFromFile } from '@ycforge/auth';

const auth = createAuth(authKeyFromFile('./authorized_key.json'));
// или inline:
const auth2 = createAuth({
  type: 'auth_key',
  keyId: 'aje...',
  serviceAccountId: 'sa-...',
  privateKey: process.env.PRIVATE_KEY!,
});

access_token / anonymous / static (только YDB)

createAuth({ type: 'access_token', token: '...' });
createAuth({ type: 'anonymous' }); // пустой токен
createAuth({ type: 'static', username: 'user', password: 'pass' });

Стратегия static (username/password) не может получить токен без YDB gRPC эндпоинта: в ядре её getToken() бросает ошибку с подсказкой использовать адаптер @ycforge/auth/ydb, который делегирует вызовы StaticCredentialsProvider из @ydbjs/auth.

Capability-матрица

| Стратегия | ycloud | ydb | | -------------- | -------- | ----- | | iam_token | ✅ | ✅ | | metadata | ✅ | ✅ | | auth_key | ✅ | ✅ | | access_token | ❌ | ✅ | | anonymous | ❌ | ✅ | | static | ❌ | ✅ |

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

auth.getProvider(usage?) возвращает TokenProvider; если usage передан, совместимость проверяется на каждом вызове getToken().

YDB-адаптер (@ycforge/auth/ydb)

Требует опционального peer-зависимости @ydbjs/auth (>= 6).

Зачем нужен адаптер

@ydbjs/auth (слой аутентификации YDB JS SDK) ожидает объект CredentialsProvider. Этот объект должен реализовывать getToken() и уже уметь подставлять возвращаемое значение в gRPC-метаданные как x-ydb-auth-ticket. Адаптер @ycforge/auth/ydb превращает ваш AuthManager именно в такой CredentialsProvider, поэтому одна и та же конфигурация аутентификации может использоваться и для REST API Яндекс Облака, и для YDB.

Зачем нужны endpoint / secure / channelOptions?

Большинству стратегий YDB-эндпоинт не нужен. Адаптер требует его только для стратегии static (username/password), потому что StaticCredentialsProvider из @ydbjs/auth выполняет gRPC-вызов Login к YDB-эндпоинту для обмена учётных данных на auth ticket.

Для iam_token, metadata, auth_key, access_token и anonymous параметры endpoint, secure и channelOptions игнорируются — адаптер просто вызывает auth.getToken(usage) и позволяет @ycforge/auth заниматься кэшированием и обновлением токена.

Примеры использования

Первый аргумент адаптера — AuthManager, второй обязательный аргумент — usage ('ydb' или 'ycloud'), третий опциональный — настройки YdbCredentialsAdapterOptions.

import { createAuth, authKeyFromFile, YDB_AUTH_USAGE } from '@ycforge/auth';
import { createYdbCredentialsProvider } from '@ycforge/auth/ydb';

// Стратегии, которым НЕ нужен endpoint:
const authKey = createAuth(authKeyFromFile('./authorized_key.json'));
const iam = createAuth({ type: 'iam_token', token: process.env.IAM_TOKEN! });
const meta = createAuth({ type: 'metadata' });
const anon = createAuth({ type: 'anonymous' });

const creds = createYdbCredentialsProvider(authKey, YDB_AUTH_USAGE);
// Передайте `creds` в Driver ydb-js-sdk там, где ожидается CredentialsProvider.

// Для логина по логину/паролю endpoint НУЖЕН:
const staticAuth = createAuth({
  type: 'static',
  username: 'user',
  password: 'pass',
});
const staticCreds = createYdbCredentialsProvider(staticAuth, YDB_AUTH_USAGE, {
  endpoint: 'grpcs://ydb.serverless.yandexcloud.net:2135',
  secure: true, // по умолчанию; установите false для локального незащищённого YDB (grpc://)
});

Стратегия static работает только с usage === 'ydb'. При попытке передать 'ycloud' адаптер бросит AuthConfigurationError.

Маппинг стратегий

| Стратегия | Что возвращает адаптер | Нужен endpoint | | --------------- | ------------------------------------------------------------ | ---------------- | | static | StaticCredentialsProvider из @ydbjs/auth | да | | anonymous | AnonymousCredentialsProvider из @ydbjs/auth | нет | | всё остальное | Тонкий CredentialsProvider, делегирующий auth.getToken(usage) | нет |

NestJS-модуль (@ycforge/auth/nestjs)

Требует опциональных peer-зависимостей @nestjs/common (>= 10) и reflect-metadata.

import { Module } from '@nestjs/common';
import {
  InjectAuth,
  YCFORGE_AUTH,
  YcAuthModule,
} from '@ycforge/auth/nestjs';
import type { AuthManager } from '@ycforge/auth';

@Module({
  imports: [
    YcAuthModule.forRoot({
      config: { type: 'metadata' },
      global: true, // опционально
    }),
    // или асинхронно:
    // YcAuthModule.forRootAsync({
    //   inject: [ConfigService],
    //   useFactory: (cfg: ConfigService) => cfg.get('auth'),
    // }),
  ],
})
export class AppModule {}

@Injectable()
export class SomeService {
  constructor(@InjectAuth() private readonly auth: AuthManager) {}
}

Менеджер предоставляется под символом YCFORGE_AUTH и также доступен через moduleRef.get(YCFORGE_AUTH).

Пример: использование одного AuthManager с @ycforge/ydb-orm

Если у вас уже зарегистрирован YcAuthModule, можно внедрить тот же AuthManager в модуль YDB ORM вместо дублирования учётных данных.

import { Module, Inject } from '@nestjs/common';
import { YdbModule } from '@ycforge/ydb-orm';
import { YCFORGE_AUTH, YcAuthModule, InjectAuth } from '@ycforge/auth/nestjs';
import type { AuthManager } from '@ycforge/auth';

@Module({
  imports: [
    YcAuthModule.forRoot({
      config: { type: 'metadata' },
      global: true,
    }),
    YdbModule.forRootAsync({
      useFactory: (auth: AuthManager) => ({
        endpoint: 'grpcs://ydb.serverless.yandexcloud.net:2135',
        database: '/ru-central1/.../...',
        auth, // ydb-orm сам обернёт его в CredentialsProvider для YDB
      }),
      inject: [YCFORGE_AUTH],
    }),
  ],
})
export class AppModule {}

ORM будет использовать внедрённый auth-менеджер и запрашивать токены с usage 'ydb'. Если настроенная стратегия несовместима с YDB (например, access_token там, где ожидается IAM), поведение будет таким же, как при передаче произвольного CredentialsProvider.

Пример: использование одного AuthManager с @ycforge/orm-security-providers

Используйте тот же AuthManager для security-провайдеров Яндекс Облака. Зарегистрируйте модуль один раз и внедряйте менеджер туда, где его ожидает провайдер; провайдер будет запрашивать токены с usage 'ycloud'.

import { Module } from '@nestjs/common';
import { YandexKmsModule } from '@ycforge/orm-security-providers';
import { YCFORGE_AUTH, YcAuthModule } from '@ycforge/auth/nestjs';
import type { AuthManager } from '@ycforge/auth';

@Module({
  imports: [
    YcAuthModule.forRoot({
      global: true,
      config: authKeyFromFile('./keys/kms-key.json'),
    }),
    YandexKmsModule.forRootAsync({
      useFactory: (auth: AuthManager) => ({
        keyId: process.env.KMS_KEY_ID!,
        auth,
      }),
      inject: [YCFORGE_AUTH],
    }),
  ],
})
export class AppModule {}

Один экземпляр AuthManager теперь обслуживает и YDB, и YCloud потребителей; каждый потребитель запрашивает нужный usage ('ydb' или 'ycloud').

Скрипты

yarn build   # tsc → dist/
yarn test    # jest (ESM, ts-jest)
yarn lint    # eslint + prettier

Лицензия

MIT