Make hosted OAuth and MCP auth generic (#1375)

* Make hosted OAuth and MCP auth generic

* Address PR feedback and lint issues

* Suppress built-in Google secret in hosted proxy flows

* Align hosted OAuth secret suppression with proxy config

* Harden hosted OAuth callback helpers

* Tighten hosted OAuth URL rewriting
This commit is contained in:
Henry Park
2026-03-19 15:50:54 -07:00
committed by GitHub
parent 65062f3cc0
commit c4ab382522
8 changed files with 785 additions and 232 deletions
+14 -4
View File
@@ -267,14 +267,24 @@ async def _stream_tool_call(request: web.Request, cid: str, tc: dict) -> web.Str
async def oauth_exchange(request: web.Request) -> web.Response:
"""Mock OAuth token exchange proxy for E2E tests.
Accepts form params (code, redirect_uri, code_verifier) and returns
a fake token response. Called by ironclaw's exchange_via_proxy() when
IRONCLAW_OAUTH_EXCHANGE_URL is set.
Accepts the generic hosted OAuth proxy contract used by IronClaw and
returns a fake token response. MCP callback tests assert that provider-
specific token params such as RFC 8707 `resource` are forwarded here.
"""
data = await request.post()
code = data.get("code", "")
access_token_field = data.get("access_token_field", "access_token")
if code == "mock_mcp_code":
if not data.get("token_url", "").endswith("/oauth/token"):
return web.json_response({"error": "missing_token_url"}, status=400)
if not data.get("client_id"):
return web.json_response({"error": "missing_client_id"}, status=400)
if not data.get("resource"):
return web.json_response({"error": "missing_resource"}, status=400)
return web.json_response({
"access_token": f"mock-token-{code}",
access_token_field: f"mock-token-{code}",
"refresh_token": "mock-refresh-token",
"expires_in": 3600,
})
@@ -99,6 +99,10 @@ async def test_mcp_activate_triggers_auth(ironclaw_server):
assert auth_url is not None or awaiting_token, (
f"Activate should require auth, got: {data}"
)
if auth_url is not None:
assert _extract_state(auth_url).startswith("ic2."), (
f"Hosted MCP OAuth should emit versioned state, got: {auth_url}"
)
# ── Section C: OAuth Round-Trip ──────────────────────────────────────────