Skip to content

fix(router): make computeSha256 independent of metric/access log attributes#2633

Merged
endigma merged 5 commits intomainfrom
jesse/eng-6851-fix-compute-sha256-safelist-independent-checks
Mar 12, 2026
Merged

fix(router): make computeSha256 independent of metric/access log attributes#2633
endigma merged 5 commits intomainfrom
jesse/eng-6851-fix-compute-sha256-safelist-independent-checks

Conversation

@endigma
Copy link
Copy Markdown
Member

@endigma endigma commented Mar 11, 2026

Convert the mutually exclusive if/else-if chain to independent if blocks so safelist/logUnknown checks always evaluate. Guard the persisted query hash overwrite to preserve client-provided hashes for "run by ID" requests. Use client-provided hash for telemetry when a request has a hash but no query body.

Add tests for safelist + access log SHA256 attributes and update cache metrics expectations.

Summary by CodeRabbit

  • Tests

    • Added safelist tests for operation SHA‑256 scenarios, persisted‑query behaviors, and access‑log hashing (including client‑provided persisted hash cases).
    • Updated structured‑logging expectations to the new persisted operation SHA‑256 value.
    • Expanded cache‑warmup assertions to include query‑hash hit/miss metrics.
  • Improvements

    • Use client‑provided persisted query hashes for telemetry to avoid unnecessary hashing.
    • Make operation‑hash computation conditional so it can originate from attributes, logs, or persisted operations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4c4b9429-bb24-427b-a9ad-9ce5b47571ae

📥 Commits

Reviewing files that changed from the base of the PR and between e1fbfd8 and d0f3720.

📒 Files selected for processing (1)
  • router-tests/structured_logging_test.go

Walkthrough

Adds two query-hash metric fields for cache-warmup tests, expands safelist tests to exercise access-log sha256 handling, and updates graph-server/prehandler logic to prefer client-provided persisted hashes when no query body, conditionally compute operation SHA‑256, and materialize persisted-query hashes for safelist/logUnknown paths.

Changes

Cohort / File(s) Summary
Test Metrics
router-tests/cache_warmup_test.go
Added QueryHashMisses and QueryHashHits fields to CacheMetricsAssertion to record raw query-body hash misses/hits in cache-warmup assertions.
Safelist Tests
router-tests/safelist_test.go
Added three subtests exercising safelist behavior when an operation_sha256 access-log attribute is present (persisted queries with/without extensions, and rejection of non-persisted queries).
Structured Logging Tests
router-tests/structured_logging_test.go
Updated expected operation_sha256 value and renamed a test to reflect "persisted hash only" scenario.
Prehandler / SHA‑256 Control Flow
router/core/graphql_prehandler.go, router/core/graph_server.go
Relaxed/reordered guards determining when to compute SHA‑256; handleOperation now uses client-provided persisted hash if no query body, otherwise computes the hash, updates telemetry/context, and materializes a PersistedQuery hash for safelist/logUnknown when appropriate.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: making computeSha256 independent of metric/access log attributes by converting mutually exclusive conditions into independent blocks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 11, 2026

Router image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-b3f8bd7d6695bac9f7b65e6558592669c72bf0bf

@endigma endigma force-pushed the jesse/eng-6851-fix-compute-sha256-safelist-independent-checks branch from 594fa6f to 9252484 Compare March 11, 2026 17:23
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 11, 2026

Codecov Report

❌ Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.91%. Comparing base (0ea3e7d) to head (d0f3720).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
router/core/graphql_prehandler.go 77.77% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2633      +/-   ##
==========================================
- Coverage   64.58%   62.91%   -1.68%     
==========================================
  Files         301      244      -57     
  Lines       42876    25816   -17060     
  Branches     4600        0    -4600     
==========================================
- Hits        27690    16241   -11449     
+ Misses      15165     8202    -6963     
- Partials       21     1373    +1352     
Files with missing lines Coverage Δ
router/core/graph_server.go 84.60% <100.00%> (ø)
router/core/graphql_prehandler.go 83.07% <77.77%> (ø)

... and 543 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

endigma added 2 commits March 11, 2026 17:45
…ibutes

Convert the mutually exclusive if/else-if chain in graph_server.go:671-689 to
independent if blocks so safelist/logUnknown checks always evaluate. Guard the
persisted query hash overwrite in graphql_prehandler.go:558-563 to preserve
client-provided hashes for "run by ID" requests. Use client-provided hash for
telemetry when a request has a hash but no query body.

Add tests for safelist + access log SHA256 attributes (the configuration that
exposed the bug). Update cache_warmup_test.go cache metrics expectations.
@endigma endigma force-pushed the jesse/eng-6851-fix-compute-sha256-safelist-independent-checks branch from 9252484 to de3b807 Compare March 11, 2026 17:45
endigma added 2 commits March 11, 2026 17:58
…elemetry

Tests previously expected sha256 of empty string for operation_sha256 when
a request provided a persisted hash but no query body. Now correctly expects
the client-provided persisted hash.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
router-tests/structured_logging_test.go (1)

2032-2065: ⚠️ Potential issue | 🟡 Minor

Rename this subtest or add a query body.

After the assertion change, this case is clearly exercising the no query body path, but the subtest name still says “with persisted hash and body”. That makes the suite advertise coverage it does not actually provide.

✏️ Suggested tweak
-		t.Run("validate request.operation.sha256Hash expression with persisted hash and body", func(t *testing.T) {
+		t.Run("validate request.operation.sha256Hash expression with persisted hash and no query body", func(t *testing.T) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@router-tests/structured_logging_test.go` around lines 2032 - 2065, The
subtest started with t.Run("validate request.operation.sha256Hash expression
with persisted hash and body", ...) no longer includes a query body, so either
rename that test title to reflect the "no body" path (e.g., change the t.Run
string to mention "no body" or "persisted hash only") or add a GraphQL request
body to the GraphQLRequest used in xEnv.MakeGraphQLRequest (populate the Body
field alongside OperationName and Extensions) so the test truly exercises the
"with persisted hash and body" scenario; update the t.Run string or the
GraphQLRequest Body accordingly and keep assertions against
request.operation.sha256Hash unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@router-tests/structured_logging_test.go`:
- Around line 2032-2065: The subtest started with t.Run("validate
request.operation.sha256Hash expression with persisted hash and body", ...) no
longer includes a query body, so either rename that test title to reflect the
"no body" path (e.g., change the t.Run string to mention "no body" or "persisted
hash only") or add a GraphQL request body to the GraphQLRequest used in
xEnv.MakeGraphQLRequest (populate the Body field alongside OperationName and
Extensions) so the test truly exercises the "with persisted hash and body"
scenario; update the t.Run string or the GraphQLRequest Body accordingly and
keep assertions against request.operation.sha256Hash unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 49cc0862-cfac-42fb-badc-f1e4708d124d

📥 Commits

Reviewing files that changed from the base of the PR and between de3b807 and 9c7a30f.

📒 Files selected for processing (1)
  • router-tests/structured_logging_test.go

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
router-tests/structured_logging_test.go (1)

2032-2065: Rename this subtest to match the scenario.

The request here no longer includes a query body, so "with persisted hash and body" now points at a different code path than the one being asserted.

♻️ Suggested rename
-		t.Run("validate request.operation.sha256Hash expression with persisted hash and body", func(t *testing.T) {
+		t.Run("validate request.operation.sha256Hash expression with persisted hash and no query body", func(t *testing.T) {

Based on learnings: Hash validation for persisted queries with query bodies is performed in router/core/graphql_prehandler.go in handleOperation, not in the APQ processing logic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@router-tests/structured_logging_test.go` around lines 2032 - 2065, The
subtest name is misleading because the request has no query body and exercises
the APQ/persisted-hash path; rename the t.Run description from "validate
request.operation.sha256Hash expression with persisted hash and body" to reflect
the actual scenario (e.g. "validate request.operation.sha256Hash expression with
persisted hash (no body)" or similar) so the test name matches the asserted
behavior in this test and distinguishes it from the body-validation path handled
by handleOperation in graphql_prehandler.go.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@router-tests/structured_logging_test.go`:
- Around line 2032-2065: The subtest name is misleading because the request has
no query body and exercises the APQ/persisted-hash path; rename the t.Run
description from "validate request.operation.sha256Hash expression with
persisted hash and body" to reflect the actual scenario (e.g. "validate
request.operation.sha256Hash expression with persisted hash (no body)" or
similar) so the test name matches the asserted behavior in this test and
distinguishes it from the body-validation path handled by handleOperation in
graphql_prehandler.go.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0726ac63-0e0e-4e1d-b1ae-14d2dc88c630

📥 Commits

Reviewing files that changed from the base of the PR and between 9c7a30f and e1fbfd8.

📒 Files selected for processing (1)
  • router-tests/structured_logging_test.go

@endigma endigma merged commit f03d96e into main Mar 12, 2026
32 checks passed
@endigma endigma deleted the jesse/eng-6851-fix-compute-sha256-safelist-independent-checks branch March 12, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants