You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Split out from PR #1773 review (Comment 2 — discussion r3716615618).
ConfigController.handle (POST /v1/ops/config/reload) serializes the whole merged Config and returns it. Secret fields on the pre-existing managed types are protected
by @JsonProperty(access = WRITE_ONLY) (Upstream.key, Upstream.secretExtraData, Key.key), so they are never serialized. But Application external-service auth_settings (client_secret, …) and ToolSetauth_settings
(client_secret / code_verifier) are notWRITE_ONLY — those fields must
round-trip through the resource write path — so /reload returns them in plaintext.
This is admin-only (so not a privilege-escalation), but it is an inconsistent reveal
path:
Pre-existing. Config-file-defined apps/toolsets already expose these secrets
(plaintext in the file) via /reload. This is therefore not introduced by the
applications/toolsets → platform migration — migrating such an app keeps the same /reload visibility (plaintext-in-file before, decrypted-blob after).
New (via feat: materialize applications/toolsets into the platform bucket #1773). A natively-created platform app/toolset has its secret redacted on the resource GET (redactExternalServiceSecrets / redactAuthSettingsSecrets) yet is still revealed via /reload — a
redact-on-GET vs. reveal-on-reload inconsistency with no file-era equivalent.
Proposal
Redact secret-bearing application/toolset fields in the /reload response — reuse the
existing redactExternalServiceSecrets / redactAuthSettingsSecrets helpers so the
same values the per-entity GET strips are also stripped here, covering both the
pre-existing file case and the native platform case. Alternatively, centralize a
single "config for admin viewing" projection so the reveal decision lives in one place.
Notes
WRITE_ONLY is not the right fix for these fields — they legitimately round-trip
through the resource write path.
Keep the fix consistent with the redaction the per-entity GET already applies.
Context
Split out from PR #1773 review (Comment 2 — discussion r3716615618).
ConfigController.handle(POST /v1/ops/config/reload) serializes the whole mergedConfigand returns it. Secret fields on the pre-existing managed types are protectedby
@JsonProperty(access = WRITE_ONLY)(Upstream.key,Upstream.secretExtraData,Key.key), so they are never serialized. ButApplicationexternal-serviceauth_settings(client_secret, …) andToolSetauth_settings(
client_secret/code_verifier) are notWRITE_ONLY— those fields mustround-trip through the resource write path — so
/reloadreturns them in plaintext.This is admin-only (so not a privilege-escalation), but it is an inconsistent reveal
path:
(plaintext in the file) via
/reload. This is therefore not introduced by theapplications/toolsets →
platformmigration — migrating such an app keeps the same/reloadvisibility (plaintext-in-file before, decrypted-blob after).platformapp/toolset has its secretredacted on the resource GET (
redactExternalServiceSecrets/redactAuthSettingsSecrets) yet is still revealed via/reload— aredact-on-GET vs. reveal-on-reload inconsistency with no file-era equivalent.
Proposal
Redact secret-bearing application/toolset fields in the
/reloadresponse — reuse theexisting
redactExternalServiceSecrets/redactAuthSettingsSecretshelpers so thesame values the per-entity GET strips are also stripped here, covering both the
pre-existing file case and the native
platformcase. Alternatively, centralize asingle "config for admin viewing" projection so the reveal decision lives in one place.
Notes
WRITE_ONLYis not the right fix for these fields — they legitimately round-tripthrough the resource write path.