-
Notifications
You must be signed in to change notification settings - Fork 39
Feat: Config file for Context Guru that terminates TLS #720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| # AuthBridge config for the context-guru demo — HTTPS variant. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit — nothing references this file, so it's hard to find. The demo README's "Configuration reference" section documents A one-liner in the README — something like " |
||
| # | ||
| # Use a `tls_bridge` block so | ||
| # the forward proxy MITM-terminates the agent's outbound TLS. Without it, HTTPS | ||
| # LLM calls arrive as an opaque CONNECT tunnel and context-guru sees no body. | ||
| # With it, the decrypted HTTP request is fed through the outbound pipeline, so | ||
| # inference-parser + context-guru can read and rewrite the LLM request body. | ||
| # | ||
| # ── PREREQUISITES (all three are required for HTTPS interception to work) ── | ||
| # 1. Client trusts the bridge CA. TLS termination means the proxy presents its | ||
| # OWN leaf cert for the LLM host. The agent's HTTP client rejects it unless | ||
| # it trusts /tmp/tls-bridge-ca/ca.crt. For a Node agent: | ||
| # NODE_EXTRA_CA_CERTS=/tmp/tls-bridge-ca/ca.crt | ||
| # (Python: REQUESTS_CA_BUNDLE / SSL_CERT_FILE; Go: SSL_CERT_FILE.) | ||
| # 2. Agent routes HTTPS through the forward proxy: | ||
| # HTTPS_PROXY=http://127.0.0.1:8081 | ||
| # 3. Plugin is compiled in (it is opt-in) and the package is fully built: | ||
| # LOG_LEVEL=debug go run -tags include_plugin_contextguru . | ||
| # | ||
| # THREE MODES via the context-guru entry's `on_error` (unchanged from the demo): | ||
| # enforce (default) — compaction is applied to the outbound request. | ||
| # observe — shadow: engine runs and records what it WOULD save, but | ||
| # the request is forwarded unchanged. A/B the gain live. | ||
| # off — kill-switch: the plugin is dropped entirely (baseline). | ||
| mode: proxy-sidecar | ||
| listener: | ||
| roles: [forward] # egress-only: no reverse proxy at all | ||
| forward_proxy_addr: "localhost:8081" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion — keep the loopback intent, but use the literal IP: Narrowing from The hostname form is the risk. which would then fail to connect, with a confusing "connection refused" against a proxy that the logs just said was listening. Nothing catches this — the field goes straight to
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (carried from round 2, non-blocking) — consider Narrowing from The hostname form is the part I'd change. That combination fails with a "connection refused" against a proxy the logs just announced as listening, which is an annoying thing to debug in a demo. Nothing guards it either — the value goes straight to The literal IP is deterministic and matches the documented |
||
| # reverse_proxy_backend: "http://localhost:8001" # the agent (moved off :0) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit — the commented-out line still carries Suggest deleting the line outright rather than commenting it: with
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit (carried from round 2, non-blocking) — this commented-out line still carries Suggest deleting the line outright instead of leaving it commented: with |
||
|
|
||
| # TLS termination of agent egress so the outbound pipeline sees decrypted HTTPS. | ||
| tls_bridge: | ||
| mode: enabled # disabled | enabled (empty == disabled) | ||
| ca_dir: /tmp/tls-bridge-ca # required when enabled; MUST persist across restarts | ||
| generate_ca: true # demo/standalone: mint a self-signed CA into ca_dir | ||
| # if absent. In-cluster this stays false (CA is a | ||
| # mounted cert-manager Secret). | ||
| ports: [443, 8443] # ports to intercept as TLS (this is also the default). | ||
| # Only HTTP(S)-bearing ports — do NOT add non-HTTP | ||
| # TLS ports (LDAPS/DB-over-TLS) or the bridge breaks them. | ||
| # upstream_ca_bundle: /path/to/roots.pem # extra roots for re-origination to a | ||
| # private-CA LLM endpoint; omit for system roots only. | ||
|
|
||
| pipeline: | ||
| outbound: | ||
| plugins: | ||
| - name: inference-parser | ||
| - name: context-guru | ||
| on_error: enforce # enforce | observe | off (see header) | ||
| config: | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| # Only inference paths are compacted; everything else passes through. | ||
| paths: ["/v1/chat/completions", "/v1/completions", "/v1/messages"] | ||
| # Static cheap model for the LLM-backed extract:code component. OpenAI wire | ||
| # only (base_url + /v1/chat/completions). Key injected from a Secret via env. | ||
| # NOTE: if CG_MODEL_BASE is now an https:// endpoint, this outbound call ALSO | ||
| # goes through the forward proxy — its host must be on an intercepted port | ||
| # (443/8443) or listed under passthrough_hosts, and its cert must verify. | ||
| model: | ||
| base_url: "${CG_MODEL_BASE}" | ||
| model: "${CG_MODEL_NAME}" | ||
| api_key: "${CG_MODEL_KEY}" | ||
| # `engine` is context-guru's native config, passed verbatim to config.LoadBytes. | ||
| engine: | ||
| # 2 deterministic reducers (dedup, collapse) + extract strategy=code. | ||
| pipeline: [dedup, extract, collapse] | ||
| components: | ||
| dedup: # drop byte-identical tool outputs | ||
| min_tokens: 40 | ||
| extract: # LLM writes a sandboxed, deletion-only, | ||
| strategy: code # containment-proven projection of each | ||
| marker_mode: summary # large tool output (v1: no restoration -> | ||
| model: { source: config } # summary leaves a ⟪cg⟫ breadcrumb, no stash) | ||
| trigger: { min_output_tokens: 120 } # only project outputs at least this big | ||
| collapse: # gentle head/tail net for anything extract left | ||
| max_tokens: 300 | ||
| head_lines: 12 | ||
| tail_lines: 12 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion —
cmd/authbridge-cpex/main.go:315-346carries a byte-identical copy of both functions, still onsrv.ListenAndServe()and still logging the requestedaddr. Same:0blind spot, same async-fatal-on-bind-failure.Worth applying the same change there so the two binaries don't drift — or a line in the commit message noting cpex is deliberately out of scope.
(The change itself reads well: hoisting
net.Listenout of the goroutine also turns a bind failure into a synchronous fatal, which is strictly better than the old behavior of logging "listening" and then dying from inside the goroutine.)