feat: secrets agent-proxy start and connect commands#308
feat: secrets agent-proxy start and connect commands#308saifsmailbox98 wants to merge 20 commits into
Conversation
MITM agent proxy that brokers credentials on the wire (header rewriting and credential substitution), plus the connect wrapper that fetches the root CA, placeholders, and secrets and forks the agent process.
- refresh the proxy MI access token before it expires (re-login goroutine), so secret fetches and CA signing don't start 401ing after the token TTL - evict an agent's cache on a 401/403 during refresh, so a revoked or expired agent JWT stops receiving brokered credentials (fail closed) - leaf certs use the IP SAN for IP-literal CONNECT targets (not DNS names) - connection deadlines: bound CONNECT read, TLS handshake, and idle tunnel - case-insensitive host matching for wildcards (matching exact behavior) - blocked hosts return 403 (not 502) so policy blocks are distinguishable - pass INFISICAL_DOMAIN to the agent so its infisical commands hit the same instance - require --env (no silent 'dev' default)
- register --token flag so INFISICAL_TOKEN auth works in connect - strip machine identity credentials from the agent environment - retry proxy token refresh on failure instead of waiting a full cycle - standardize on zerolog; name cert lifetime constants - cap leaf cert expiry at the intermediate; close re-sign cache race - exit accept loop on listener close; handle IPv6 CONNECT targets - strip hop-by-hop headers; drain request body on keep-alive tunnels - tiered host-pattern precedence matching the design doc
|
💬 Discussion in Slack: #pr-review-cli-308-feat-secrets-agent-proxy-start-and-connect-commands Posted by Review Police — reviews, comments, new commits, and CI failures will stream into this channel. |
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 34725125 | Triggered | Base64 Basic Authentication | 8a9ea27 | packages/agentproxy/rewrite_test.go | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
|
| Filename | Overview |
|---|---|
| packages/agentproxy/proxy.go | Core MITM proxy: auth, routing, CONNECT/plain-forward paths. Previously flagged: binds 0.0.0.0 (no loopback-only option). New code is otherwise well-structured with proper hop-by-hop stripping, host pinning, and policy checks. |
| packages/agentproxy/cache.go | Agent credential cache with periodic refresh. TOCTOU on concurrent miss and revocation lag were previously discussed and accepted as intentional design. Logic is sound. |
| packages/agentproxy/ca.go | Intermediate CA lifecycle: lazy init, renewal with fallback on Infisical outage, leaf cache with generation-stamped eviction. Correct use of dual-lock pattern to avoid leaf-to-stale-intermediate association. |
| packages/agentproxy/match.go | Host/port/path pattern matching. IPv6 literals in patterns are broken: bracketed form stores brackets but incoming hostnames never have them; unbracketed form mis-parses address colons as port separators. |
| packages/agentproxy/rewrite.go | Header rewriting and placeholder substitution across path/query/body/header. Oversized body pass-through is correct (avoids truncation) but emits no log, making silent credential non-injection hard to detect. |
| packages/cmd/agent_proxy.go | connect command: auth, CA fetch, placeholder/secret injection, env building. Lowercase proxy env vars (https_proxy, http_proxy, no_proxy) are stripped but not re-set; signal.Notify subscribes to all signals with a buffer of 1. |
| packages/cmd/agent_proxy_start.go | start command: MI auth, token refresh goroutine with retry backoff, delegates to agentproxy.Start. Token refresh logic is correct (half-TTL refresh, short retry on failure). |
| packages/api/agent_proxy.go | API client methods for CA fetch, intermediate CA signing, and proxied-service listing. Straightforward REST wrappers with proper error handling. |
Reviews (4): Last reviewed commit: "fix: pin upstream Host header to the mat..." | Re-trigger Greptile
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 11 · PR risk: 0/10 |
|
@greptile review |
|
@greptile review |
|
@greptile review |
…rets The agent proxy's credential fetch and the connect wrapper's secret fetch now request reference expansion and imported secrets, matching infisical run.
…ifecycle timeouts
Description 📣
Adds the Infisical Agent Proxy — the client that powers Secrets Brokering. Untrusted code (AI agents, unsafe code-execution environments) routes its HTTP traffic through the proxy, which injects real credentials on the wire so the agent only ever handles placeholders. Backend + frontend companion PR: Infisical/infisical#7246.
Two commands under
infisical secrets agent-proxy:start— a single-port MITM proxy that brokers credentials on the wire. On the first request from an agent it discovers that agent's proxied services (using the agent's JWT) and fetches the real secret values (using its own machine identity), caches per agent, and re-polls on an interval. It signs a short-lived intermediate CA against the org root CA and mints leaf certs per hostname locally. Supports header rewriting (bearer / basic auth / API key) and credential substitution across path/query/body/header, plus--unmatched-host=allow|block,--poll-interval, and--port.connect— the wrapper that sets up an agent: authenticates the agent machine identity, downloads the org root CA, fetches proxied-service placeholders + regular secrets, and forks the agent with the environment wired up (HTTPS_PROXY/HTTP_PROXY, CA-trust vars,NO_PROXY, placeholder env vars, real secrets). Machine-identity credentials are stripped from the child so the agent only gets a scoped JWT.--no-proxyadds bypass hosts (merged with the loopback defaults).Host matching follows exact-host > specific-port > longest-path-prefix, with full ties broken deterministically by service name. Credential injection always wins over client-supplied headers (hop-by-hop stripping runs before injection).
Type ✨
Tests 🛠️
# Here's some code block to paste some code snippets