Labels: ready-to-code
Depends on: Issue 13 (#3309)
Refactor KeycloakAuthClient in boost-node to use Backstage cacheService for token caching instead of private instance fields, and add HTTPS validation for tokenEndpoint. This aligns with boost design principle 1 ("All operational caches use Backstage cacheService") and the PRD cache migration table which lists KeycloakAuthClient as P1 for cacheService migration.
Context
PR #3661 extracted KeycloakAuthClient from kagenti-entity-provider and boost-backend-module-kagenti into boost-node as a shared implementation. The current implementation uses in-memory token caching (private cachedToken and tokenExpiresAt fields) with in-flight deduplication. This works correctly but deviates from the architectural principle that all operational caches use cacheService.
The boost-backend-module-kagenti package already has a KeycloakTokenCache class wrapping cacheService. The refactored KeycloakAuthClient should compose with this pattern rather than duplicating it.
Additionally, KeycloakAuthClient.getBearerToken() sends clientId:clientSecret as a Basic auth header to tokenEndpoint without validating the URL scheme is HTTPS. The Zod schema validates URL format (z.string().url()) but not HTTPS. In production, sending credentials over HTTP exposes them in transit.
Tasks
Specifications
specifications/boost-context.md — Design Principle 1 (Backstage cacheService from Day One)
specifications/prd/pluggable-ai-platform-architecture.md — Cache migration table (KeycloakAuthClient row)
openspec/changes/security-safety-governance/specs/access-control/spec.md — Service-account auth scenarios
openspec/changes/platform-operations-deployment/specs/cache-migration/spec.md
Labels:
ready-to-codeDepends on: Issue 13 (#3309)
Refactor
KeycloakAuthClientinboost-nodeto use BackstagecacheServicefor token caching instead of private instance fields, and add HTTPS validation fortokenEndpoint. This aligns with boost design principle 1 ("All operational caches use BackstagecacheService") and the PRD cache migration table which listsKeycloakAuthClientas P1 for cacheService migration.Context
PR #3661 extracted
KeycloakAuthClientfromkagenti-entity-providerandboost-backend-module-kagentiintoboost-nodeas a shared implementation. The current implementation uses in-memory token caching (privatecachedTokenandtokenExpiresAtfields) with in-flight deduplication. This works correctly but deviates from the architectural principle that all operational caches usecacheService.The
boost-backend-module-kagentipackage already has aKeycloakTokenCacheclass wrappingcacheService. The refactoredKeycloakAuthClientshould compose with this pattern rather than duplicating it.Additionally,
KeycloakAuthClient.getBearerToken()sendsclientId:clientSecretas a Basic auth header totokenEndpointwithout validating the URL scheme is HTTPS. The Zod schema validates URL format (z.string().url()) but not HTTPS. In production, sending credentials over HTTP exposes them in transit.Tasks
KeycloakAuthClienttoboost-nodeso bothboost-backend-module-kagentiandkagenti-entity-providershare one implementation (done in PR feat(#3309): add Kagenti auth, 401 retry, and user header #3661)coreServices.cacheto thekagenti-entity-providermodule depsKeycloakAuthClientconstructor to accept aCacheServiceinstancecachedToken/tokenExpiresAtfields withcacheService.get()/cacheService.set()using TTL derived from token expiry minus buffermodule.tsto passcache(with namespace) toKeycloakAuthClientcacheServiceinstead of relying on in-memory statetokenEndpointinKeycloakAuthClientconstructor — reject HTTP URLs unless security mode isdevelopment-only-no-authKeycloakTokenCacheand its test fromboost-backend-module-kagenti— it becomes redundant onceKeycloakAuthClientusescacheServicedirectly. Also remove thevoid keycloakTokenCacheplaceholder inmodule.ts.KagentiProviderFactoryJSDoc (references "task 3.3, 3.4, 3.7" from an older numbering scheme)Specifications
specifications/boost-context.md— Design Principle 1 (Backstage cacheService from Day One)specifications/prd/pluggable-ai-platform-architecture.md— Cache migration table (KeycloakAuthClient row)openspec/changes/security-safety-governance/specs/access-control/spec.md— Service-account auth scenariosopenspec/changes/platform-operations-deployment/specs/cache-migration/spec.md