Spaces:
Running
Running
Fix critical security issue: Enforce API key requirement for MCP clients
Browse filesSECURITY FIX:
- MCP clients were bypassing API key requirement and using Space API key
- Now properly distinguish between web browser requests and MCP client requests
- Space API key only used for web browser demo requests
- MCP clients MUST provide their own API key via headers
Changes:
- Add User-Agent detection to identify web browsers vs MCP clients
- Enforce strict API key requirement for all MCP client requests
- Provide detailed error message with configuration example
- Maintain web demo functionality for browser users
This ensures:
β
Web demo works for browser users (limited usage)
β MCP clients cannot use Space API key (security)
β
MCP clients must provide own API key (production usage)
app.py
CHANGED
@@ -29,15 +29,46 @@ def get_api_client():
|
|
29 |
is_space = os.getenv("SPACE_ID") is not None
|
30 |
space_api_key = os.getenv("A1D_API_KEY")
|
31 |
|
32 |
-
# 3.
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
return A1DAPIClient(space_api_key)
|
36 |
|
37 |
-
#
|
38 |
if not api_key:
|
39 |
raise ValueError(
|
40 |
-
"API key is required
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
print("π Using API key from MCP client headers")
|
43 |
return A1DAPIClient(api_key)
|
|
|
29 |
is_space = os.getenv("SPACE_ID") is not None
|
30 |
space_api_key = os.getenv("A1D_API_KEY")
|
31 |
|
32 |
+
# 3. Determine if this is a web browser request or MCP client request
|
33 |
+
is_web_request = False
|
34 |
+
try:
|
35 |
+
request = gr.request()
|
36 |
+
if request and hasattr(request, 'headers'):
|
37 |
+
user_agent = request.headers.get('user-agent', '').lower()
|
38 |
+
# Web browsers typically have 'mozilla' in user agent
|
39 |
+
is_web_request = 'mozilla' in user_agent or 'chrome' in user_agent or 'safari' in user_agent
|
40 |
+
except:
|
41 |
+
is_web_request = True # Default to web request if we can't determine
|
42 |
+
|
43 |
+
# 4. Use Space API key ONLY for web browser requests on Hugging Face Space
|
44 |
+
if not api_key and is_space and space_api_key and is_web_request:
|
45 |
+
print("π‘ Using API key from Space environment variable (web demo)")
|
46 |
return A1DAPIClient(space_api_key)
|
47 |
|
48 |
+
# 5. For MCP clients, API key is mandatory
|
49 |
if not api_key:
|
50 |
raise ValueError(
|
51 |
+
"π API key is required for MCP clients!\n\n"
|
52 |
+
"Please provide API_KEY in request headers.\n"
|
53 |
+
"Get your API key at https://a1d.ai\n\n"
|
54 |
+
"Configuration example:\n"
|
55 |
+
'{\n'
|
56 |
+
' "mcpServers": {\n'
|
57 |
+
' "a1d": {\n'
|
58 |
+
' "command": "npx",\n'
|
59 |
+
' "args": [\n'
|
60 |
+
' "mcp-remote@latest",\n'
|
61 |
+
' "https://aigchacker-a1d-mcp-server.hf.space/gradio_api/mcp/sse",\n'
|
62 |
+
' "--header",\n'
|
63 |
+
' "API_KEY:${MCP_API_KEY}"\n'
|
64 |
+
' ],\n'
|
65 |
+
' "env": {\n'
|
66 |
+
' "MCP_API_KEY": "your_a1d_api_key_here"\n'
|
67 |
+
' }\n'
|
68 |
+
' }\n'
|
69 |
+
' }\n'
|
70 |
+
'}'
|
71 |
+
)
|
72 |
|
73 |
print("π Using API key from MCP client headers")
|
74 |
return A1DAPIClient(api_key)
|