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)
|