fix: redact provider api keys, bound cache writers, harden pgvector init#452
Conversation
Address a batch of code-review findings, validating each against source before acting (three reported items were rejected as incorrect or already handled and are intentionally omitted). - security(auditlog): redact `api-key` (Azure) and `x-goog-api-key` (Gemini/Vertex) request headers, which previously leaked in cleartext when header logging was enabled. - reliability(responsecache): bound semantic-cache vector-store inserts with the same worker pool the exact cache already uses, so a burst of misses can no longer spawn unbounded goroutines against the vector DB. - reliability(responsecache): tolerate `CREATE EXTENSION` permission errors on managed Postgres (RDS/Cloud SQL) when the `vector` extension is already installed, instead of aborting startup. - perf(gateway): cache pricing lookups per (model, provider) in batch usage logging to avoid per-item model-registry lock contention on large batches. - perf(server): reuse 32KB stream copy buffers via a sync.Pool. - refactor(core): collapse hand-written request MarshalJSON boilerplate to `type alias` conversions for ChatRequest, ResponsesRequest, EmbeddingRequest, BatchRequest, ToolCall, and FunctionCall, removing the silent field-drop risk. Message/ResponseMessage are intentionally left explicit due to their duplicate `json:"content"` Swagger tag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds credential header redaction entries, refactors several JSON marshalers to use type aliases, caches batch pricing lookups, bounds semantic cache writes with a worker pool, tolerates pre-existing pgvector installs, and reuses stream copy buffers. ChangesAudit Log Header Redaction
MarshalJSON Type Alias Refactor
Batch Usage Pricing Cache
Semantic Cache Worker Pool
PGVector Extension Tolerant Initialization
Stream Copy Buffer Pooling
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/gateway/batch_usage.go`:
- Line 94: The cache key in the batch usage path is currently built by joining
model and provider with a NUL byte, which is less idiomatic and depends on
string contents never containing that separator. Update the map key in the code
around the cache lookup in the batch usage logic to use a dedicated struct with
model and provider fields instead of a concatenated string, and adjust the key
creation wherever that cache key is produced or consumed so the behavior stays
the same but is self-documenting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0439a938-3f24-4067-8370-5d7b0b429c72
📒 Files selected for processing (11)
internal/auditlog/auditlog.gointernal/auditlog/auditlog_test.gointernal/core/batch_json.gointernal/core/chat_json.gointernal/core/embeddings_json.gointernal/core/message_json.gointernal/core/responses_json.gointernal/gateway/batch_usage.gointernal/responsecache/semantic.gointernal/responsecache/vecstore_pgvector.gointernal/server/stream_support.go
- vecstore pgvector: give the extension-existence fallback its own timeout
so a slow CREATE EXTENSION failure that drained the outer deadline cannot
make the check spuriously report the extension as missing (Greptile P2).
- batch usage: key the local pricing cache with a struct{model, provider}
instead of a NUL-joined string for clarity (CodeRabbit).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/responsecache/vecstore_pgvector.go (1)
94-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd unit test coverage for
pgExtensionInstalledand the tolerant fallback path.Codecov flagged missing coverage in this file. Since this helper directly gates whether initialization fails or continues on managed Postgres, table-driven tests covering the "installed", "not installed", and "query error" cases would materially reduce risk.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/responsecache/vecstore_pgvector.go` around lines 94 - 103, Add unit test coverage for pgExtensionInstalled and the fallback behavior it supports in vecstore_pgvector.go. Create table-driven tests for pgExtensionInstalled to cover the installed, not installed, and query-error cases by exercising the QueryRow/Scan path on a test pool or mocked pgx behavior. Also add a test for the initialization flow that uses this helper so the tolerant fallback path is verified when pgExtensionInstalled returns false on query error, ensuring managed Postgres continues without masking the original CREATE EXTENSION failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@internal/responsecache/vecstore_pgvector.go`:
- Around line 94-103: Add unit test coverage for pgExtensionInstalled and the
fallback behavior it supports in vecstore_pgvector.go. Create table-driven tests
for pgExtensionInstalled to cover the installed, not installed, and query-error
cases by exercising the QueryRow/Scan path on a test pool or mocked pgx
behavior. Also add a test for the initialization flow that uses this helper so
the tolerant fallback path is verified when pgExtensionInstalled returns false
on query error, ensuring managed Postgres continues without masking the original
CREATE EXTENSION failure.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1471ce13-3615-4931-a9c0-13c91867bc5a
📒 Files selected for processing (2)
internal/gateway/batch_usage.gointernal/responsecache/vecstore_pgvector.go
Addresses a batch of code-review findings. Each reported item was validated against source before acting; three were rejected as incorrect or already handled (see below) and are intentionally not changed.
Fixed
api-key(Azure) andx-goog-api-key(Gemini/Vertex) request headers.azure.gosets its credential header asapi-key, which was missing fromRedactedHeaders, so it could be persisted in cleartext when header logging is enabled. Added both header names + a test case.go func()per cache miss straight at the vector store — a miss storm could exhaust connections. Now uses the same bounded worker pool (cacheWriteWorkerCount=8, queued,wg-tracked, clean shutdown) that the exact cache already uses.CREATE EXTENSION vectoraborted startup on managed Postgres (RDS/Cloud SQL/Heroku) where the app role lacks the privilege even when a DBA already installed pgvector. Now tolerates the error only whenpg_extensionconfirms the extension is present; otherwise still fails loudly.ResolvePricing(registryRLock) per item, up to ~50k/batch. Added a loop-local(model, provider)pricing cache (cachesniltoo).flushStreamallocated a fresh 32KB buffer per stream; now drawn from async.Pool.MarshalJSONboilerplate totype aliasconversions forChatRequest,ResponsesRequest,EmbeddingRequest,BatchRequest,ToolCall,FunctionCall(−150 lines), removing the silent field-drop risk when new typed fields are added. Output is byte-identical (verified via existing round-trip tests).Message/ResponseMessagewere intentionally left explicit — their duplicatejson:"content"Swagger tag makes a blind alias unsafe.Rejected (with evidence)
slices.Containsdesign is deliberate and already benchmarked against exactly this map baseline (json_fields_bench_test.go);UnknownJSONFieldsexists to avoid per-request map allocations. M is 14–27 and thegjsonwalk dominates.maps.Clone. The premise (hand-rolled loops) is stale; they live in 4 packages and carry intent-revealing names/docs.SumUsageCostis already period-bounded and indexed (idx_usage_timestamp,idx_usage_user_path). A rollup must also handle hierarchical user-path prefix matching, cache-type exclusion, period boundaries, and resets across 3 storage backends — a dedicated, designed change.Testing
go build ./...,go vet, and fullgo test ./...pass.make test-race,make lint, and the hot-path alloc/byte performance guard.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Performance
Refactor