Plan — MT-3: CredentialManager interface + EnvCredentialManager#
Summary#
Create a CredentialManager abstraction layer that decouples secret access from environment variables. The initial EnvCredentialManager implementation preserves existing behavior (reads GITHUB_TOKEN/HUMAN_PAT and GITHUB_WEBHOOK_SECRET from process.env via ConfigService). This is Phase 1 foundation for the multi-tenant initiative and unblocks TenantResolver (#352).
Files#
| File | Action | Description |
|---|---|---|
src/credential/credential-manager.interface.ts | create | CredentialManager interface, PlatformCredentials/LLMCredentials types, CREDENTIAL_MANAGER injection token |
src/credential/credential-error.ts | create | Typed CredentialError class extending Error |
src/credential/env/env-credential-manager.ts | create | ENV-backed implementation using ConfigService; GITHUB_TOKEN with HUMAN_PAT fallback |
src/credential/credential.module.ts | create | NestJS module providing CREDENTIAL_MANAGER token with EnvCredentialManager |
src/credential/env/env-credential-manager.spec.ts | create | Unit tests: happy path, HUMAN_PAT fallback, missing token error, missing ANTHROPIC_API_KEY returns empty |
Steps#
- Create
credential-manager.interface.tswithPlatformCredentials,LLMCredentialsinterfaces,CredentialManagerinterface, andCREDENTIAL_MANAGERSymbol token. - Create
credential-error.tswith a typedCredentialErrorclass (extendsError, setsname = 'CredentialError'). - Create
env-credential-manager.tsimplementingCredentialManager— injectConfigService, readGITHUB_TOKEN(fallbackHUMAN_PAT), throwCredentialErrorif neither set, readGITHUB_WEBHOOK_SECRET, readANTHROPIC_API_KEY(return empty string if missing). IgnorecredentialPathparameter. - Create
credential.module.ts— importConfigModule, provide{ provide: CREDENTIAL_MANAGER, useClass: EnvCredentialManager }, exportCREDENTIAL_MANAGER. - Create
env-credential-manager.spec.ts— test cases: (a) returns correct ENV values, (b) falls back toHUMAN_PAT, (c) throwsCredentialErrorwhen no token, (d) returns emptyapiKeywhenANTHROPIC_API_KEYmissing. - Run
tsc --noEmit,npm run lint,npm run testto verify.
Verification#
npm run testpasses with new spec file includedtsc --noEmitcompiles without errorsnpm run lintpasses with zero warnings
Risks#
ConfigServicetype resolution:EnvCredentialManagermust useconfig.get<string>()(notgetOrThrow()) to support theHUMAN_PATfallback pattern — mirrorsGitHubServiceconstructor approach.