From 1a1e361d68e644cc3a87d04d8230227185d64afb Mon Sep 17 00:00:00 2001 From: "fineas-bot[bot]" <258147136+fineas-bot[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:58:51 -0400 Subject: [PATCH 1/2] Retire completed compatibility aliases Use the canonical Bearer and GitHub broker paths now that all active callers and credentials have migrated. --- contrib/chart/templates/apirs.yaml | 12 +---- .../chart/tests/test_overlay_image_compat.sh | 12 +---- contrib/chart/values.schema.json | 6 --- contrib/chart/values.yaml | 12 ++--- docs/pages/reference/configuration.mdx | 3 -- docs/public/md/reference/configuration.md | 3 -- .../crates/centaur-api-server/src/routes.rs | 47 ++++++++++++++----- services/console/docs/API.md | 2 - 8 files changed, 42 insertions(+), 55 deletions(-) diff --git a/contrib/chart/templates/apirs.yaml b/contrib/chart/templates/apirs.yaml index 81a11a9f0..9730d5a90 100644 --- a/contrib/chart/templates/apirs.yaml +++ b/contrib/chart/templates/apirs.yaml @@ -3,7 +3,7 @@ {{- $mcpPublicUrl := default .Values.slackbotv2.mcpPublicUrl .Values.apiRs.mcpPublicUrl -}} {{- $apiRsName := include "centaur.componentName" (dict "root" . "component" "api-rs") -}} {{- $sandboxOverlayMountPath := .Values.overlay.sandboxMountPath | default "/home/agent/overlay/org" -}} -{{- $githubAppBrokerBootstrapEnabled := and (or .Values.tokenBroker.enabled .Values.tokenBroker.githubApp.enabled) .Values.tokenBroker.githubApp.enabled .Values.tokenBroker.githubApp.bootstrap.enabled -}} +{{- $githubAppBrokerBootstrapEnabled := and .Values.tokenBroker.githubApp.enabled .Values.tokenBroker.githubApp.bootstrap.enabled -}} {{- if and $githubAppBrokerBootstrapEnabled (not $console.enabled) -}} {{- fail "console.enabled must be true when tokenBroker.githubApp bootstrap is enabled" -}} {{- end -}} @@ -13,14 +13,6 @@ {{- $githubAppBrokerBootstrapImageRepository := default .Values.sandbox.image.repository .Values.tokenBroker.githubApp.bootstrap.image.repository -}} {{- $githubAppBrokerBootstrapImageTag := default .Values.sandbox.image.tag .Values.tokenBroker.githubApp.bootstrap.image.tag -}} {{- $githubAppBrokerBootstrapImagePullPolicy := default .Values.sandbox.image.pullPolicy .Values.tokenBroker.githubApp.bootstrap.image.pullPolicy -}} -{{- $githubAppBrokerCredentialIds := list "github-app" -}} -{{- with .Values.tokenBroker.githubApp.credentialId -}} -{{- $githubAppBrokerCredentialIds = append $githubAppBrokerCredentialIds . -}} -{{- end -}} -{{- range .Values.tokenBroker.githubApp.extraCredentialIds -}} -{{- $githubAppBrokerCredentialIds = append $githubAppBrokerCredentialIds . -}} -{{- end -}} -{{- $githubAppBrokerCredentialIds = uniq $githubAppBrokerCredentialIds -}} {{- $githubAppBrokerNamespaces := default (list "default") .Values.tokenBroker.githubApp.credentialNamespaces -}} {{- $repoCacheStorageType := include "centaur.repoCacheStorageType" . -}} {{- $repoCacheUsePvc := eq $repoCacheStorageType "persistentVolumeClaim" -}} @@ -360,7 +352,7 @@ spec: name: {{ .Values.tokenBroker.githubApp.existingSecretName | quote }} key: {{ .Values.tokenBroker.githubApp.existingSecretKeys.installationId | quote }} - name: GITHUB_APP_BROKER_CREDENTIAL_IDS - value: {{ join " " $githubAppBrokerCredentialIds | quote }} + value: "github-app" - name: GITHUB_APP_BROKER_NAMESPACES value: {{ join " " $githubAppBrokerNamespaces | quote }} volumeMounts: diff --git a/contrib/chart/tests/test_overlay_image_compat.sh b/contrib/chart/tests/test_overlay_image_compat.sh index 1c87fccf4..7faff1530 100644 --- a/contrib/chart/tests/test_overlay_image_compat.sh +++ b/contrib/chart/tests/test_overlay_image_compat.sh @@ -185,17 +185,6 @@ for expected in \ fi done -helm template test "$chart_dir" "${common[@]}" \ - --set console.enabled=true \ - --set tokenBroker.githubApp.enabled=true \ - --set tokenBroker.githubApp.credentialId=fineas-github-app \ - --set tokenBroker.githubApp.existingSecretName=fineas-github-app \ - >"$scratch/github-app-alias.yaml" -if ! grep -qF 'value: "github-app fineas-github-app"' "$scratch/github-app-alias.yaml"; then - echo "GitHub App compatibility alias must not replace the canonical github-app credential" >&2 - exit 1 -fi - helm template test "$chart_dir" "${common[@]}" \ --set console.enabled=true \ --set tokenBroker.githubApp.enabled=true \ @@ -205,6 +194,7 @@ for expected in \ 'name: github-app-broker-bootstrap' \ 'grant: "github_app_installation"' \ 'name: GITHUB_APP_ID' \ + 'value: "github-app"' \ 'name: github-app-broker-secret' \ 'secretName: "fineas-github-app"'; do if ! grep -qF "$expected" "$scratch/github-app.yaml"; then diff --git a/contrib/chart/values.schema.json b/contrib/chart/values.schema.json index 6daa70db1..378ea3c2c 100644 --- a/contrib/chart/values.schema.json +++ b/contrib/chart/values.schema.json @@ -131,16 +131,10 @@ "tokenBroker": { "type": "object", "properties": { - "enabled": { "type": "boolean" }, "githubApp": { "type": "object", "properties": { "enabled": { "type": "boolean" }, - "credentialId": { "type": "string" }, - "extraCredentialIds": { - "type": "array", - "items": { "type": "string" } - }, "credentialNamespaces": { "type": "array", "items": { "type": "string" } diff --git a/contrib/chart/values.yaml b/contrib/chart/values.yaml index 40dfaa8ea..7b17be543 100644 --- a/contrib/chart/values.yaml +++ b/contrib/chart/values.yaml @@ -190,18 +190,12 @@ console: replicaCount: 1 resources: {} -# Managed short-lived token credentials for sandbox proxy rules. This -# transitional bootstrap upserts the GitHub App installation credential into -# the upstream Console credential-grant registry before api-rs starts. +# Managed short-lived token credentials for sandbox proxy rules. The bootstrap +# upserts the GitHub App installation credential into the upstream Console +# credential-grant registry before api-rs starts. tokenBroker: - enabled: false githubApp: enabled: false - # Compatibility alias provisioned alongside the canonical `github-app` - # credential. The built-in infra role always consumes `github-app`; do not - # add a second same-scope proxy source for this alias. - credentialId: github-app - extraCredentialIds: [] credentialNamespaces: - default - infra diff --git a/docs/pages/reference/configuration.mdx b/docs/pages/reference/configuration.mdx index 41f4b979c..53841c94f 100644 --- a/docs/pages/reference/configuration.mdx +++ b/docs/pages/reference/configuration.mdx @@ -39,7 +39,6 @@ These must exist for the normal Helm deployment. For local development, | `SLACK_BOT_TOKEN` | `secretManager.existingSecretName`; local bootstrap reads shell env. | Slack Web API access for Slackbot and api-rs Slack helpers. | | `SANDBOX_SIGNING_KEY` | `secretManager.existingSecretName`; local bootstrap generates it. | Signing key for short-lived sandbox API tokens. | | `IRON_MANAGEMENT_API_KEY` | `secretManager.existingSecretName`; local bootstrap generates it. | Management key for API-created iron-proxy pods. | -| `IRON_BROKER_TOKEN` | `secretManager.existingSecretName`; required when `tokenBroker.enabled=true`. | Bearer token iron-proxy presents to iron-token-broker and the broker enforces on its HTTP API. | | `OP_SERVICE_ACCOUNT_TOKEN` | Local shell, then `centaur-infra-env`; production Secret. | 1Password service-account auth when using `onepassword` secret source. | | `OP_VAULT` | Local shell, then `centaur-infra-env`; defaults to `ai-agents` in code. | 1Password vault used for `op://...` secret refs. | @@ -192,8 +191,6 @@ Kubernetes backend: | `KUBERNETES_SECRET_ENV_NAME`, `KUBERNETES_SECRET_ENV_PREFIX`, `KUBERNETES_BOOTSTRAP_SECRET_NAME` | `secretManager.*`, `secrets.bootstrapSecretName`. | Secrets read by API-created proxy/sandbox pods. | | `KUBERNETES_IRON_PROXY_IMAGE`, `KUBERNETES_IRON_PROXY_IMAGE_PULL_POLICY`, `KUBERNETES_IRON_PROXY_PORT`, `KUBERNETES_IRON_PROXY_MANAGEMENT_PORT`, `KUBERNETES_IRON_PROXY_HEALTH_PORT` | `ironProxy.*`. | Per-sandbox iron-proxy image and ports. | | `FIREWALL_MANAGER_SECRET_SOURCE`, `FIREWALL_MANAGER_SECRET_TTL`, `KUBERNETES_FIREWALL_MANAGER_SECRET_SOURCE` | `ironProxy.secretSource`, `ironProxy.secretTtl`. | Secret source and cache TTL for rendered proxy config. | -| `FIREWALL_MANAGER_TOKEN_BROKER_TTL` | `tokenBroker.ttl`. | Proxy-side cache TTL for access tokens minted by iron-token-broker. Applied to every `brokered_token` secret. | -| `KUBERNETES_TOKEN_BROKER_NAME`, `KUBERNETES_TOKEN_BROKER_URL` | `tokenBroker.*`. | iron-token-broker Deployment name and ClusterIP URL. The chart owns the broker Deployment, Service, and NetworkPolicies; the API reconciles its ConfigMap and triggers a rolling restart when the rendered content changes. | | `KUBERNETES_OP_CONNECT_HOST`, `KUBERNETES_OP_CONNECT_APP_NAME`, `KUBERNETES_OP_CONNECT_PORT` | Chart helper or `api.extraEnv`. | 1Password Connect endpoint details. | | `KUBERNETES_API_POD_LABEL_SELECTOR` | Chart-rendered labels or `api.extraEnv`. | API pod selector for API-managed proxy policies. | | `KUBERNETES_EGRESS_DISCOVERY_ENABLED`, `KUBERNETES_EGRESS_SERVICE_NAMESPACE`, `KUBERNETES_CLUSTER_DOMAIN`, `KUBERNETES_EGRESS_TAILNET_FQDN_ANNOTATION` | `api.egressDiscovery.*`. | Egress service discovery for sandbox NetworkPolicies. | diff --git a/docs/public/md/reference/configuration.md b/docs/public/md/reference/configuration.md index 41f4b979c..53841c94f 100644 --- a/docs/public/md/reference/configuration.md +++ b/docs/public/md/reference/configuration.md @@ -39,7 +39,6 @@ These must exist for the normal Helm deployment. For local development, | `SLACK_BOT_TOKEN` | `secretManager.existingSecretName`; local bootstrap reads shell env. | Slack Web API access for Slackbot and api-rs Slack helpers. | | `SANDBOX_SIGNING_KEY` | `secretManager.existingSecretName`; local bootstrap generates it. | Signing key for short-lived sandbox API tokens. | | `IRON_MANAGEMENT_API_KEY` | `secretManager.existingSecretName`; local bootstrap generates it. | Management key for API-created iron-proxy pods. | -| `IRON_BROKER_TOKEN` | `secretManager.existingSecretName`; required when `tokenBroker.enabled=true`. | Bearer token iron-proxy presents to iron-token-broker and the broker enforces on its HTTP API. | | `OP_SERVICE_ACCOUNT_TOKEN` | Local shell, then `centaur-infra-env`; production Secret. | 1Password service-account auth when using `onepassword` secret source. | | `OP_VAULT` | Local shell, then `centaur-infra-env`; defaults to `ai-agents` in code. | 1Password vault used for `op://...` secret refs. | @@ -192,8 +191,6 @@ Kubernetes backend: | `KUBERNETES_SECRET_ENV_NAME`, `KUBERNETES_SECRET_ENV_PREFIX`, `KUBERNETES_BOOTSTRAP_SECRET_NAME` | `secretManager.*`, `secrets.bootstrapSecretName`. | Secrets read by API-created proxy/sandbox pods. | | `KUBERNETES_IRON_PROXY_IMAGE`, `KUBERNETES_IRON_PROXY_IMAGE_PULL_POLICY`, `KUBERNETES_IRON_PROXY_PORT`, `KUBERNETES_IRON_PROXY_MANAGEMENT_PORT`, `KUBERNETES_IRON_PROXY_HEALTH_PORT` | `ironProxy.*`. | Per-sandbox iron-proxy image and ports. | | `FIREWALL_MANAGER_SECRET_SOURCE`, `FIREWALL_MANAGER_SECRET_TTL`, `KUBERNETES_FIREWALL_MANAGER_SECRET_SOURCE` | `ironProxy.secretSource`, `ironProxy.secretTtl`. | Secret source and cache TTL for rendered proxy config. | -| `FIREWALL_MANAGER_TOKEN_BROKER_TTL` | `tokenBroker.ttl`. | Proxy-side cache TTL for access tokens minted by iron-token-broker. Applied to every `brokered_token` secret. | -| `KUBERNETES_TOKEN_BROKER_NAME`, `KUBERNETES_TOKEN_BROKER_URL` | `tokenBroker.*`. | iron-token-broker Deployment name and ClusterIP URL. The chart owns the broker Deployment, Service, and NetworkPolicies; the API reconciles its ConfigMap and triggers a rolling restart when the rendered content changes. | | `KUBERNETES_OP_CONNECT_HOST`, `KUBERNETES_OP_CONNECT_APP_NAME`, `KUBERNETES_OP_CONNECT_PORT` | Chart helper or `api.extraEnv`. | 1Password Connect endpoint details. | | `KUBERNETES_API_POD_LABEL_SELECTOR` | Chart-rendered labels or `api.extraEnv`. | API pod selector for API-managed proxy policies. | | `KUBERNETES_EGRESS_DISCOVERY_ENABLED`, `KUBERNETES_EGRESS_SERVICE_NAMESPACE`, `KUBERNETES_CLUSTER_DOMAIN`, `KUBERNETES_EGRESS_TAILNET_FQDN_ANNOTATION` | `api.egressDiscovery.*`. | Egress service discovery for sandbox NetworkPolicies. | diff --git a/services/api-rs/crates/centaur-api-server/src/routes.rs b/services/api-rs/crates/centaur-api-server/src/routes.rs index c4965393d..26c405489 100644 --- a/services/api-rs/crates/centaur-api-server/src/routes.rs +++ b/services/api-rs/crates/centaur-api-server/src/routes.rs @@ -2630,6 +2630,15 @@ fn authorize_workflow_api(headers: &HeaderMap) -> Result Result { + authorize_session_api_with_service_token_matcher(headers, |token| { + token_matches_configured_env(token, SESSION_API_SERVICE_KEY_ENVS) + }) +} + +fn authorize_session_api_with_service_token_matcher( + headers: &HeaderMap, + service_token_matches: impl Fn(&str) -> bool, +) -> Result { if let Some(presented) = header_value(headers, "X-Centaur-Feedback-Key") { if !token_matches_configured_env(presented.trim(), &["SLACK_FEEDBACK_API_KEY"]) { return Err(ApiError::Unauthorized( @@ -2645,18 +2654,8 @@ fn authorize_session_api(headers: &HeaderMap) -> Result` form (`github.com` rejects `Bearer` for git transport) while the REST API keeps `Bearer`. To provision it manually instead of via Helm, run: -`tokenBroker.githubApp.credentialId` and `extraCredentialIds` are compatibility aliases provisioned alongside the canonical `github-app` credential. They are bootstrap-only unless a separate, explicitly scoped secret references them; the built-in GitHub rules intentionally have one source so equal-priority credentials cannot compete for the same Authorization header. - ``` centaur-perms broker create --namespace default --foreign-id github-app \ --grant github_app_installation --client-id "$GITHUB_APP_ID" \ From 9d064a6327e9f9a2d0c462745cce73dee7c0c5ae Mon Sep 17 00:00:00 2001 From: "fineas-bot[bot]" <258147136+fineas-bot[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:00:22 -0400 Subject: [PATCH 2/2] Bump chart version for compatibility cleanup --- contrib/chart/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/chart/Chart.yaml b/contrib/chart/Chart.yaml index a03091a65..75c2b8323 100644 --- a/contrib/chart/Chart.yaml +++ b/contrib/chart/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: centaur description: Helm chart for the trusted Centaur control plane type: application -version: 0.1.103 +version: 0.1.104 appVersion: "0.1.0" dependencies: - name: connect