Skip to content

fix(admin): preserve OAuth client_secret when editing gateways and A2A agents#4150

Open
ecthelion77 wants to merge 1 commit intoIBM:mainfrom
forterro:fix/oauth-secret-preservation-upstream
Open

fix(admin): preserve OAuth client_secret when editing gateways and A2A agents#4150
ecthelion77 wants to merge 1 commit intoIBM:mainfrom
forterro:fix/oauth-secret-preservation-upstream

Conversation

@ecthelion77
Copy link
Copy Markdown
Contributor

@ecthelion77 ecthelion77 commented Apr 13, 2026

🐛 Bug-fix PR

🔗 Issue

Closes #4156

📌 Summary

Editing a gateway or A2A agent via the admin UI silently erases the OAuth client_secret, breaking all OAuth-authenticated gateways that are subsequently edited for any reason (e.g., changing tags, description, or team assignment).

🔁 Reproduction Steps

  1. Create a gateway with OAuth authentication including a client_secret
  2. Verify the gateway works (tools are discovered, OAuth token exchange succeeds)
  3. Edit the gateway via the admin UI (change any field — description, tags, etc.)
  4. Save the edit
  5. The gateway is now broken — client_secret is gone from oauth_config
  6. Any OAuth token exchange attempt fails with invalid_client

🐞 Root Cause

Two bugs that combine to cause data loss:

Bug 1 — Frontend (gateways.js, a2aAgents.js):

When the edit modal populates form fields, all secret fields (bearer token, password, custom headers, query params) are set to MASKED_AUTH_VALUE ("*****") — except oauth_client_secret which is set to "":

// All other secrets:
authTokenField.value = MASKED_AUTH_VALUE;       // ✅ Preserved
authPasswordField.value = MASKED_AUTH_VALUE;    // ✅ Preserved

// OAuth client_secret:
oauthClientSecretField.value = "";              // ❌ Sends empty string

Bug 2 — Backend (admin.py, admin_edit_gateway and admin_edit_a2a_agent):

When the form submits with oauth_client_secret = "", the handler skips adding client_secret to the oauth_config dict entirely:

if oauth_client_secret:               # False for "" → key never added
    oauth_config["client_secret"] = ...
# No fallback → client_secret simply missing → lost on save

The service layer's protect_oauth_config_for_storage() has preservation logic for MASKED_AUTH_VALUE, but it only works when the key exists in the dict. Since admin.py omits the key entirely, the preservation logic never fires.

Note: The admin_edit_server handler (virtual servers) already has the correct preservation pattern, making the inconsistency clear.

💡 Fix Description

Frontend: Set oauthClientSecretField.value to MASKED_AUTH_VALUE when a secret exists (consistent with all other secret fields), or "" when no secret is configured.

Backend: When oauth_client_secret is empty or equals MASKED_AUTH_VALUE and a client_id is present, send the masked placeholder value so the service layer preserves the existing encrypted secret:

if oauth_client_secret and oauth_client_secret != settings.masked_auth_value:
    # Encrypt new secret
    oauth_config["client_secret"] = await encryption.encrypt_secret_async(oauth_client_secret)
elif oauth_client_id:
    # Preserve existing secret via masked placeholder
    oauth_config["client_secret"] = settings.masked_auth_value

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test
Coverage ≥ 80 % make coverage
Manual regression no longer fails Edit gateway → secret preserved

📐 MCP Compliance (if relevant)

  • Matches current MCP spec
  • No breaking change to MCP clients

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • No secrets/credentials committed

@ecthelion77
Copy link
Copy Markdown
Contributor Author

Suggested labels: bug, MUST, python, javascript, ui, security

@ecthelion77 ecthelion77 force-pushed the fix/oauth-secret-preservation-upstream branch from e58ecb8 to 6281288 Compare April 14, 2026 12:46
@ecthelion77 ecthelion77 force-pushed the fix/oauth-secret-preservation-upstream branch 2 times, most recently from 5758a09 to 6477883 Compare April 14, 2026 15:34
…A agents

Signed-off-by: Olivier Gintrand <olivier.gintrand@forterro.com>
@ecthelion77 ecthelion77 force-pushed the fix/oauth-secret-preservation-upstream branch from 6477883 to b8a1e11 Compare April 14, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][AUTH]: OAuth client_secret silently erased when editing gateways or A2A agents via admin UI

1 participant