mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-11 18:00:54 -10:00
* feat(aimlapi): shared service key and attribution for aimlapi.com services Adds the pieces the Toolbox and MCP integrations share: - internal/aimlapi: X-AIMLAPI-Source (agent/zero), the fixed Toolbox and MCP URLs, and an exact-hostname check (https, default port, no userinfo) for api/tools/mcp.aimlapi.com before the key or attribution headers are attached. The partner id still comes from ResolvePartnerID. - internal/config: AIMLAPIServiceKey picks the key from the aimlapi profile (or AIMLAPI_API_KEY without one), reading the credential store, and withholds it when any aimlapi-keyed profile points at a proxy base URL or AIMLAPI_INFERENCE_URL is overridden. Keys that are not a single token are refused. * feat(mcp): AI/ML API MCP server as an opt-in built-in default Seeds `aimlapi` (https://mcp.aimlapi.com/mcp, streamable HTTP) next to Exa as a built-in MCP server that ships disabled: its tool runs and generations are billed to the user's AI/ML API balance. The disable is marked as explicitly set, so a project config cannot lift it; the user turns it on with `zero mcp enable aimlapi`, which now writes `"disabled": false` for a default that ships off (and `zero mcp add aimlapi` does the same). `zero doctor` reports the untouched default as a pass rather than a warning. The MCP client attaches the AI/ML API key and the X-AIMLAPI-Source / X-AIMLAPI-Partner-ID headers in one place (internal/mcp/aimlapi.go), called from the three header-application points. Both apply only to a request whose own URL is exactly https://mcp.aimlapi.com on the default port, whatever the server is named. The key is resolved for every request through config.LoadAIMLAPIServiceKey, so switching the aimlapi provider to a proxy, or a key that is not a single token, means no Authorization header on the next request. It is never put in config, the server identity used for OAuth token binding, list output or errors. A user Authorization header, `"auth": "oauth"`, or a project-touched server goes without it. A 401 from that host explains how to add a key or sign in with `zero mcp oauth login`. * fix(aimlapi): validate whitespace and preserve store errors * fix(mcp): tailor unauthorized hints to credential policy * docs(mcp): clarify automatic credential eligibility * test(mcp): cover edited disabled built-in defaults * fix(aimlapi): report store reads after proxy eligibility checks * docs(aimlapi): document MCP key precedence and clarify 401 hints Operator copy now matches normalizeProvider resolution (inline key, apiKeyEnv, then credential store) and warns that AIMLAPI_API_KEY can bill MCP before a stored profile key. SECURITY and service-key godoc stay aligned. 401 hints no longer imply a proxy-only failure mode. Adds a regression test that resolved profile keys win over the store. Co-authored-by: Cursor <[email protected]> * fix(mcp): keep the aimlapi key off redirects and error text, persist enable Redirect hops: net/http copies the first request's headers onto every redirect hop without calling the header hooks, so the automatic AI/ML API key and attribution followed a same-origin hop that fails the exact-URL rule (userinfo) and an eligible hop reused the first hop's key. The redirect guard now restores the server's own values for those headers and applies the per-request rule again. Error text: httpStatusError copied up to 1 KiB of the response body into the error, so a body echoing the injected key (or its prefix, when cut by the read limit) reached CLI output. When the request carried the automatic key, the body is now omitted instead of matched. Enable persistence: MCPServerConfig had no serializer and Disabled is omitempty, so any read-modify-write of config.json (SetTheme, SetActiveProvider, ...) dropped `"disabled": false` and the shipped disable turned aimlapi off again. MarshalJSON now writes the flag whenever it was explicitly set; `zero mcp add` keeps writing only a disable. Co-Authored-By: Claude Opus 5.5 <[email protected]> --------- Co-authored-by: Stan <[email protected]> Co-authored-by: Hugo <[email protected]> Co-authored-by: Cursor <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
2.5 KiB
2.5 KiB
Security Policy
Zero is a terminal coding agent: it reads and edits files in your repository and can run shell commands and call external model/tool endpoints. We take security reports seriously.
Reporting a vulnerability
Please do not open a public issue for security vulnerabilities.
Report privately through GitHub's private vulnerability reporting:
- Go to the repository's Security tab → Report a vulnerability (GitHub Security Advisories).
- Describe the issue, the affected version/commit, reproduction steps, and the impact.
If you cannot use GitHub Security Advisories, open a regular issue that contains only a request to be contacted for a security report (no details), and a maintainer will arrange a private channel.
Please include, where possible:
- The version, branch, or commit affected.
- A minimal reproduction and the impact (e.g. sandbox escape, secret exposure, RCE).
- Any logs or output, with secrets redacted.
What to expect
- We aim to acknowledge a report within a few business days.
- We will work with you on a fix and a coordinated disclosure timeline, and credit you in the release notes unless you prefer to remain anonymous.
Scope notes
- Findings that require a malicious local user who already controls the machine running Zero, or that
depend on a user explicitly disabling the sandbox (
--skip-permissions-unsafe), are generally out of scope — but please report anything you are unsure about. - Zero sends no telemetry. Network calls go to the model/tool providers you configure (and, for
keyless web search, to Exa's hosted MCP endpoint at
https://mcp.exa.ai/mcp). The built-in AI/ML API MCP server (https://mcp.aimlapi.com/mcp) is off until you runzero mcp enable aimlapi. Once enabled, the Bearer key follows the aimlapi profile resolution order (inline key, then the profile'sapiKeyEnv— defaultAIMLAPI_API_KEY— then the credential store), orAIMLAPI_API_KEYalone when no aimlapi profile exists; a non-emptyAIMLAPI_API_KEYcan override a stored profile key for MCP billing. The automatic key is withheld if an aimlapi profile (or a profile readingAIMLAPI_API_KEY) uses a base URL other thanhttps://api.aimlapi.com/v1,AIMLAPI_INFERENCE_URLpoints elsewhere, a non-empty user Authorization header is configured, OAuth is selected, project config has touched the server, or the key is missing or not a single token (including Unicode whitespace). See docs/EXTENDING.md.