Skip to content

feat(boost): combined spec updates, auth pivot, dev scaffold, and entity provider fixes #3647

Description

@gabemontero

This issue covers spec updates, an auth pivot, dev scaffold additions, and entity provider fixes for the boost workspace — combined into a single change.

1. Staged-issues bookkeeping

Add the GitHub issue URL for issue 16 (#3597) to workspaces/boost/staged-issues.md in the boost-skills-routes section.

2. Auth pivot: RFC 8693 → OAuth2 Client Credentials

Pivot Kagenti authentication from per-user RFC 8693 token exchange to service-account OAuth2 Client Credentials Grant across all specification, openspec, and config schema files.

Config key changes

Old keys (remove):

  • boost.kagenti.auth.tokenExchange.enabled
  • boost.kagenti.auth.tokenExchange.audience
  • boost.kagenti.auth.tokenExchange.userTokenHeader

New keys (add):

  • boost.kagenti.auth.tokenEndpoint — Keycloak token endpoint URL
  • boost.kagenti.auth.clientId — OAuth2 client ID for service-account
  • boost.kagenti.auth.clientSecret — OAuth2 client secret (visibility: secret)
  • boost.kagenti.auth.tokenExpiryBufferSeconds — Seconds before expiry to refresh (default: 60)

Files to update

Specifications (3):

  • workspaces/boost/specifications/boost-context.md — Update principle 10 from "Per-User Identity Delegation" to "Service-Account Keycloak Authentication"; update augment lesson; update security PRD summary line
  • workspaces/boost/specifications/prd/security-safety-governance.md — Replace all RFC 8693 / token exchange references with Client Credentials Grant / KeycloakTokenManager throughout (capability 3, security mode table, architecture diagram, traceability table, customer context)
  • workspaces/boost/specifications/prd/platform-operations-deployment.md — Update Kagenti Auth line in configurable categories (line ~189)

OpenSpec (7):

  • workspaces/boost/openspec/changes/security-safety-governance/design.md — Update decision 4 and risks
  • workspaces/boost/openspec/changes/security-safety-governance/proposal.md — Update identity/auth section and key file reference
  • workspaces/boost/openspec/changes/security-safety-governance/tasks.md — Update section 7 tasks and section 10 verification tasks
  • workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md — Replace all token exchange scenarios with service-account auth scenarios (token acquisition, streaming lifecycle, 401 retry with max-1-retry constraint, user identity propagation via X-Backstage-User header, Kagenti REST API endpoints)
  • workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md — Update token exchange config table to Keycloak service-account fields
  • workspaces/boost/openspec/changes/platform-operations-deployment/tasks.md — Update task 2.5 wording
  • workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/design.md — Update non-goal to note service-account auth adopted instead

Config/code (3):

  • workspaces/boost/plugins/boost-backend/config.d.ts — Replace tokenExchange nested object with flat tokenEndpoint, clientId, clientSecret, tokenExpiryBufferSeconds fields under kagenti.auth
  • workspaces/boost/plugins/boost-backend/src/config/schemas.ts — Bump BOOST_CONFIG_SCHEMA_VERSION to 2, replace tokenExchange.* field entries with new flat field entries, add sensitive: true to clientSecret
  • workspaces/boost/plugins/boost-backend/src/config/schemas.test.ts — Update test expectations for new field names; add validation tests for tokenExpiryBufferSeconds (valid integers accepted, negative rejected, non-integer rejected, undefined returns undefined)

Generated (1):

  • workspaces/boost/plugins/boost-backend/report.api.md — Regenerate via yarn build:api-reports

Staged issues (1):

  • workspaces/boost/staged-issues.md — Update issue 13 section: header, description, task list, spec references

Key design decisions

  • tokenExpiryBufferSeconds schema is .number().int().min(0).optional() with no .default(60)RuntimeConfigResolver returns raw YAML values that bypass Zod defaults, so the consumer (KeycloakTokenManager) must apply configValue ?? 60
  • clientSecret field has sensitive: true and @visibility secret in config.d.ts
  • Max-1-retry on 401: "if the retried request also returns 401, the error is propagated to the caller"

3. Spec adjustments for working dev environment

workspaces/boost/specifications/boost-context.md

  • Add boost-responses-api-toolkit and boost-toolscope to the workspace structure tree
  • Update the paragraph describing the packages to mention toolscope (zero Backstage deps) and responses-api-toolkit (minimal Backstage deps)
  • Add new "Local Development" section with:
    • Host Packages: Explains packages/app and packages/backend as standard Backstage scaffolding, not product code
    • Metrics Compatibility Shim: Documents the no-op metricsServiceRef factory needed because backend-defaults doesn't provide one yet (as of Backstage 1.52)
    • TLS and IDE Environment Caveats: NODE_TLS_REJECT_UNAUTHORIZED=0 for self-signed OpenShift route certs; IDE subprocess env var gotcha

workspaces/boost/specifications/prd/platform-operations-deployment.md

  • Add boost-responses-api-toolkit and boost-toolscope rows to the workspace package table

4. Backend code changes for integration testing

New files

workspaces/boost/app-config.yaml — Development-mode app-config with:

  • Guest auth provider
  • SQLite in-memory database
  • boost.security.mode: 'development-only-no-auth'
  • boost.providers.llamastack and boost.providers.kagenti config with env var defaults pointing at a dev cluster
  • boost.kagenti entity provider config with auth settings (tokenEndpoint, clientId, clientSecret from env vars)
  • NOTE: All default URLs use :- syntax for env var fallback, not hardcoded values

workspaces/boost/packages/backend/ — Host backend package:

  • package.json with dependencies on backend-defaults, plugin-proxy-backend, plugin-auth-backend, plugin-auth-backend-module-guest-provider, plugin-catalog-backend, plugin-catalog-backend-module-logs, plugin-permission-backend, plugin-permission-backend-module-allow-all-policy, and all boost plugins
  • src/index.ts with:
    • No-op metricsServiceRef factory shim (catalog-backend depends on it, backend-defaults doesn't provide it yet — uses @backstage/backend-plugin-api/alpha)
    • Registration of all core Backstage plugins + all boost plugins (boost-backend, boost-backend-module-llamastack, boost-backend-module-kagenti, kagenti-entity-provider, llamastack-entity-provider)
  • .eslintrc.js extending @backstage/cli/config/eslint.backend

workspaces/boost/scripts/load-secrets.sh — Shell script to load dev secrets from K8s:

  • Reads KAGENTI_CLIENT_SECRET, KAGENTI_CLIENT_ID, KAGENTI_TOKEN_ENDPOINT, KAGENTI_BASE_URL, KAGENTI_NAMESPACE, BOOST_MODEL from a K8s secret
  • Sets NODE_TLS_REJECT_UNAUTHORIZED=0
  • Masks sensitive values in output (<set> for secrets)

Modified files

workspaces/boost/plugins/kagenti-entity-provider/src/providers/kagentiAuth.ts (new file) — KeycloakAuthClient class:

  • OAuth2 Client Credentials Grant token acquisition
  • Token caching with expiry buffer
  • getBearerToken() returns cached token or fetches fresh one
  • Uses node:buffer for base64 encoding (NOT btoa which is browser-only in older Node)

workspaces/boost/plugins/kagenti-entity-provider/src/types.ts — Add KagentiEntityProviderConfig.auth optional field with tokenEndpoint, clientId, clientSecret

workspaces/boost/plugins/kagenti-entity-provider/src/module.ts — Read auth config from boost.kagenti.auth.*, construct KeycloakAuthClient when all 3 auth fields are present, pass to entity providers

workspaces/boost/plugins/kagenti-entity-provider/src/providers/KagentiAgentEntityProvider.ts:

  • Accept optional KeycloakAuthClient in constructor
  • Fetch bearer token before namespace loop and add Authorization header
  • Use correct API URL: GET /api/v1/agents?namespace={ns} (NOT /a2a/)
  • Handle response shape: { items: AgentCard[] } OR AgentCard[] via unwrapItems helper

workspaces/boost/plugins/kagenti-entity-provider/src/providers/KagentiToolEntityProvider.ts:

  • Same auth and URL pattern as agent provider
  • GET /api/v1/tools?namespace={ns}
  • Same unwrapItems response handling

workspaces/boost/plugins/kagenti-entity-provider/src/providers/entityHelpers.ts — Add unwrapItems<T>() helper function to handle both { items: T[] } and T[] response shapes from Kagenti API

workspaces/boost/plugins/kagenti-entity-provider/src/providers/KagentiAgentEntityProvider.test.ts and KagentiToolEntityProvider.test.ts — Add tests for Keycloak auth integration (bearer token header, auth failure handling)

workspaces/boost/plugins/boost-backend/src/mcp/routes.ts and workspaces/boost/plugins/boost-backend/src/skills/routes.ts — Add TODO comments noting future cross-reference with catalog for MCP/skill access (not functional changes, just markers)

yarn.lock

The yarn.lock will need regenerating after the dependency changes in packages/backend/package.json. Run yarn install in the boost workspace.

Verification

After all changes:

  1. cd workspaces/boost && yarn tsc — no type errors
  2. cd workspaces/boost && yarn test --watchAll=false — all tests pass
  3. cd workspaces/boost && yarn build:api-reports — report.api.md up to date
  4. cd workspaces/boost && yarn lint — clean

Security constraints

  • The only references to "augment" or "Augment" should be at the high level, introductory phase, where we acknowledge that boost is a clean room re-implementation of augment (e.g., specifications/boost-context.md provenance notes and "Augment lesson" callouts)
  • Do not reference any specific customer names in code or openspecs

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions