import { Module } from '@nestjs/common'; import { assertJwksConfig } from '../config/check-jwks-config'; import { assertOboCacheEncryptionKey } from '../config/check-obo-cache-encryption-key'; import { AuthModule } from '../auth/auth.module'; import { RedisModule } from '../redis/redis.module'; import { BFF_SIGNING_KEY, buildBffSigningKey } from './bff-signing-key'; import { DownstreamTokenCache } from './downstream-token-cache.service'; import { OBO_CACHE_KEY } from './downstream.token'; import { JwksController } from './jwks.controller'; import { OboStrategy } from './strategies/obo.strategy'; import { SignedAssertionStrategy } from './strategies/signed-assertion.strategy'; /** * `DownstreamModule` — primitives for the downstream-API framework * per [ADR-0014](../../../../docs/decisions/0014-downstream-api-access-obo-pattern.md). * * **Scope (v1).** This module ships the auth-strategy primitives, * the OBO token cache, and the BFF's JWKS publishing endpoint. The * framework around them (`DownstreamApiClientFactory`, cockatiel * resilience stack, audience pre-check, error translation, OTel * custom spans) lands alongside the first concrete consumer per the * ADR's own guidance: * * "Mitigated by writing the framework code only in the same * iteration as the first concrete integration; until then, this * ADR plus mock-driven unit tests on the strategies (OBO, * signed-assertion) keep the design honest." * * What's exposed for the future integration to consume: * * - `OboStrategy` (Entra-protected downstreams). * - `SignedAssertionStrategy` (non-Entra downstreams). * - `DownstreamTokenCache` (used internally by OboStrategy; exposed * in case a future consumer wants direct cache management). * * Imports `AuthModule` for the shared `MSAL_CLIENT`, `RedisModule` * for the shared `ioredis` client. */ @Module({ imports: [AuthModule, RedisModule], controllers: [JwksController], providers: [ { provide: OBO_CACHE_KEY, useFactory: () => assertOboCacheEncryptionKey(), }, { provide: BFF_SIGNING_KEY, useFactory: () => buildBffSigningKey(assertJwksConfig()), }, DownstreamTokenCache, OboStrategy, SignedAssertionStrategy, ], exports: [OboStrategy, SignedAssertionStrategy, DownstreamTokenCache], }) export class DownstreamModule {}