Audit BYOK Model Endpoints Before Your AI Agent Gets the Key A security review of the open-source AI development platform MonkeyCode reveals that its 'bring your own key' (BYOK) model endpoint configuration poses a security boundary risk for AI coding agents. The review highlights that while a proxy reduces direct provider-key exposure inside the agent VM, it does not automatically settle endpoint trust, token lifetime, replay, or revocation. The developer recommends auditing BYOK endpoints with a policy document and a zero-dependency checker to enforce security constraints such as HTTPS, allowed hosts, and key scope. “Bring your own key” looks like a settings feature. For an AI coding agent, it is also a security boundary: a privileged workload will send repository context, prompts, and credentials toward a network destination selected by configuration. That boundary deserves more than a successful GET /models request. I reviewed MonkeyCode https://github.com/chaitin/MonkeyCode , an open-source AI development platform, at commit c58bcd4 https://github.com/chaitin/MonkeyCode/tree/c58bcd4dd4b7031f469a1271f276d22550b8f523 . Its source provides a useful concrete case because users can configure model providers while task runtimes receive proxy credentials. This is a source review, not a penetration test. In particular, I am not claiming encryption, rotation, or revocation behavior that the reviewed files do not establish. The reviewed model API-key schema https://github.com/chaitin/MonkeyCode/blob/c58bcd4dd4b7031f469a1271f276d22550b8f523/backend/ent/schema/modelapikey.go and model repository https://github.com/chaitin/MonkeyCode/blob/c58bcd4dd4b7031f469a1271f276d22550b8f523/backend/biz/setting/repo/model.go separate a configured provider credential from a runtime API key. The task path then calls CreateRuntimeAPIKey and gives the runtime a proxy base URL plus that runtime token. In the reviewed repository logic, a token is associated with a user, model, and VM; a token for the same user and VM can be reused and rebound to a model. That yields two distinct questions: | Plane | Secret holder | Security question | |---|---|---| | Provider plane | Control service | Can this credential call only the intended provider, models, and operations? | | Runtime plane | Agent VM | Is this delegated token narrowly bound, short-lived, observable, and invalid after its task boundary ends? | A proxy reduces direct provider-key exposure inside the VM. It does not automatically settle endpoint trust, server-side storage, token lifetime, replay, or revocation. A configurable model base URL controls where sensitive payloads leave the platform. Audit it like a webhook destination or package registry: TLS answers “is this encrypted to the named peer?” It does not answer “should this peer receive the repository?” An allow-list or administrator approval supplies that missing policy decision. Here is a small policy document from the companion files: { "endpoint": "https://llm-gateway.example/v1", "allowed hosts": "llm-gateway.example" , "require https": true, "forbid url credentials": true, "key scope": "model-inference-only", "runtime credential": { "audience": "llm-proxy", "bound to": "user", "model", "vm" , "max ttl seconds": 3600 }, "egress": { "allowed ports": 443 , "follow redirects": false } } The included zero-dependency checker rejects HTTP, URL credentials, unknown hosts, unrestricted key scope, missing bindings, excessive TTL, and redirects: node check-policy.mjs byok-policy.json node test-policy.mjs Expected output: PASS BYOK endpoint policy PASS policy accepts the safe fixture and rejects five unsafe properties This is a configuration gate, not a network scanner. Production enforcement must also validate DNS results at connection time, prevent redirect bypass, use a trusted TLS stack, and keep egress policy outside the agent's control. For each secret type, write down: php create - store - delegate - use - observe - rotate - revoke - delete Then demand evidence for each arrow. A schema field proves persistence, not encryption. A generated token proves delegation, not expiry. A proxy proves mediation, not least privilege. The runtime-token reuse behavior is also a reason to define model-switch semantics explicitly. If rebinding is intentional, ask what happens to an in-flight request using the prior model, how caches are keyed, and which audit event links old and new authority. My acceptance gate would be: no provider key enters the task VM; the outbound host is approved after DNS and redirect handling; the runtime token is audience-, user-, model-, and VM-bound; expiry and revocation are tested; and logs prove the decision without exposing content. Disclosure: I contribute to the MonkeyCode project. The observations and limitations above are based on the linked repository at the pinned commit and the local policy tests described here.