Skip to content

Commit f8978b9

Browse files
author
Olivier Gintrand
committed
fix: decrypt oauth_config secrets before IdP token exchange
The client_secret is encrypted at rest via protect_oauth_config_for_storage. Must call decrypt_oauth_config_for_runtime before sending to Entra ID. Without this, AADSTS7000215 'Invalid client secret provided' occurs.
1 parent 84251f7 commit f8978b9

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

mcpgateway/routers/mcp_oauth.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
from mcpgateway.config import settings
3939
from mcpgateway.db import Server as DbServer, get_db
40+
from mcpgateway.services.encryption_service import decrypt_oauth_config_for_runtime
4041
from mcpgateway.utils.create_jwt_token import create_jwt_token
4142
from mcpgateway.utils.log_sanitizer import sanitize_for_log
4243

@@ -119,8 +120,8 @@ async def _discover_oidc_metadata(issuer: str) -> Dict[str, Any]:
119120
# ---------------------------------------------------------------------------
120121

121122

122-
def _get_server_oauth_config(db: Session, server_id: str) -> tuple[DbServer, Dict[str, Any]]:
123-
"""Load virtual server and validate it has MCP OAuth proxy config."""
123+
async def _get_server_oauth_config(db: Session, server_id: str) -> tuple[DbServer, Dict[str, Any]]:
124+
"""Load virtual server, validate and decrypt MCP OAuth proxy config."""
124125
server = db.get(DbServer, server_id)
125126
if not server or not server.enabled:
126127
raise HTTPException(status_code=404, detail="Server not found")
@@ -132,6 +133,9 @@ def _get_server_oauth_config(db: Session, server_id: str) -> tuple[DbServer, Dic
132133
detail="MCP OAuth proxy not configured for this server (missing client_id in oauth_config)",
133134
)
134135

136+
# Decrypt secrets (client_secret is encrypted at rest)
137+
oauth_config = await decrypt_oauth_config_for_runtime(oauth_config)
138+
135139
return server, oauth_config
136140

137141

@@ -202,7 +206,7 @@ async def register_client(
202206
Entra app ``client_id`` from the virtual server's ``oauth_config``.
203207
No actual registration happens.
204208
"""
205-
_, oauth_config = _get_server_oauth_config(db, server_id)
209+
_, oauth_config = await _get_server_oauth_config(db, server_id)
206210

207211
client_id = oauth_config["client_id"]
208212
response = DCRResponse(
@@ -240,7 +244,7 @@ async def authorize(
240244
if response_type != "code":
241245
raise HTTPException(status_code=400, detail="Only response_type=code is supported")
242246

243-
_, oauth_config = _get_server_oauth_config(db, server_id)
247+
_, oauth_config = await _get_server_oauth_config(db, server_id)
244248

245249
# Validate client_id matches configured value
246250
if client_id != oauth_config["client_id"]:
@@ -339,7 +343,7 @@ async def callback(
339343
if session.get("sid") != server_id:
340344
raise HTTPException(status_code=400, detail="Server ID mismatch")
341345

342-
_, oauth_config = _get_server_oauth_config(db, server_id)
346+
_, oauth_config = await _get_server_oauth_config(db, server_id)
343347

344348
# Discover IdP token endpoint
345349
auth_server = oauth_config.get("authorization_server") or oauth_config.get("authorization_servers", [None])[0]

0 commit comments

Comments
 (0)