Support OAuth client secrets for MCP servers - #2169
Aaronontheweb wants to merge 8 commits into
Conversation
Aaronontheweb
left a comment
There was a problem hiding this comment.
The direction is sound, but this revision is not ready to merge.
The profile remains the authority for a configured client secret. The SDK receives that identity for code exchange and token refresh.
The token record keeps dynamic credentials but does not copy a profile secret. The restart test proves secret rotation for one client ID.
Two secret-boundary defects remain:
- A profile replacement can retain and transmit an omitted old secret.
- The public schema approves a secret that CLI inspection hides and the daemon uses.
I reproduced the first defect with the built CLI. I added a confidential profile, then replaced it with a public client at another URL.
mcp get still reported Client secret: configured after the replacement.
CI passed on revision e2573c35. I did not perform a live provider OAuth exchange.
491eb01 to
94b929a
Compare
41a062c to
ae23323
Compare
Aaronontheweb
left a comment
There was a problem hiding this comment.
Not done reviewing but found some show-stopper code smells
| var bound = config.GetSection("McpServers") | ||
| .Get<Dictionary<string, McpServerEntry>>() ?? []; | ||
|
|
||
| Assert.Equal("configured-client-secret", bound["github"].OAuthClientSecret?.Value); |
There was a problem hiding this comment.
Demonstrates that secret redaction works
|
|
||
| /// <summary>OAuth client secret for a pre-registered confidential client.</summary> | ||
| [JsonIgnore] | ||
| public SensitiveString? OAuthClientSecret { get; set; } |
c9f4179 to
38f50a5
Compare
| positional.Add(args[i]); | ||
| } | ||
|
|
||
| if (oauthClientSecret is not null && string.IsNullOrWhiteSpace(oauthClientSecret)) |
Outcome
Netclaw supports pre-registered confidential OAuth clients for HTTP and SSE MCP servers.
Operators can supply both values with:
The CLI writes the client ID to
netclaw.json.It writes only the encrypted client secret to
secrets.json.The configured identity reaches the MCP SDK for authorization-code exchange and refresh-token redemption.
The configured secret remains authoritative after token updates, secret rotation, and daemon restart.
Netclaw
0.27.0-beta.4shipped before this PR was ready.This change targets the next Netclaw
0.27prerelease.Closes #2141.
Scope
PR #2167 is merged and shipped in
0.27.0-beta.4.This PR adds the permanent confidential-client fix.
This PR does not change the anonymous-discovery flow from #2123.
Security
SensitiveStringand blocks JSON serialization of the secret.OAuthClientSecretinnetclaw.json.Verification
The programmable OAuth server requires a matching confidential-client secret.
It verifies both code exchange and refresh after a daemon restart.
The restart case rotates the configured secret.
It proves that the SDK sends the replacement secret and skips dynamic client registration.
ASPIRE010warning.git diff --checkpassed.The behavioral eval suite did not run because the required provider settings are absent.
No live GitHub or Google OAuth exchange ran.
The in-process server provides the protocol-boundary proof.