fix(ducklake): pin HTTPS for delta-kernel staging reads via duckgres#73027
Conversation
On cache-proxy-enabled duckgres clusters the org's ambient S3 secret carries USE_SSL false so httpfs flows through the logging proxy — but delta_scan's delta-kernel object store ignores DuckDB's proxy and dials the plain-HTTP S3 endpoint directly, which worker egress silently drops. Every duckgres-side delta_scan (data-imports and data-modeling copy workflows) failed after 10 retries and ~58s, continuously re-attempted across many teams, each attempt pinning a worker (verified in mw-prod-us CP logs, 2026-07-22: 29 failures/15min, ~2 worker-minutes burned per minute, zero successes). Create a session-scoped credential_chain secret with USE_SSL true SCOPEd to the staging tree before any delta_scan: longer scope wins prefix resolution there and nowhere else, delta-kernel goes direct HTTPS (allowed egress) with the worker's own ambient credentials, and duckgres wipes the secret at the next session create. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
😎 This pull request was merged. |
|
Reviews (1): Last reviewed commit: "fix(ducklake): pin HTTPS for delta-kerne..." | Re-trigger Greptile |
There was a problem hiding this comment.
Small, contained fix that forces HTTPS via a narrowly-scoped, session-only S3 secret using ambient credential_chain (no hardcoded creds, strengthens rather than weakens transport security); covered by a TDD-added test, and corroborated by an active Greptile review plus positive reactions from Greptile and a security-focused bot with no unresolved concerns.
- Author wrote 0% of the modified lines and has 30 merged PRs in these paths (familiarity MODERATE).
- 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 27L, 3F substantive, 41L/4F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1b-small (41L, 4F, single-area, fix) |
| stamphog 2.0.0b3 | .stamphog/policy.yml @ b954a44 · reviewed head cc3e43d |
|
CI triage: the failing 🤖 Generated with Claude Code |
🤖 CI report
|
| File | Patch | Uncovered changed lines |
|---|---|---|
posthog/ducklake/storage.py |
50.0% | 695 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 29967943894 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
platform_features |
██░░░░░░░░░░░░░░░░░░ 12.1% |
7 / 58 |
batch_exports |
████████░░░░░░░░░░░░ 39.6% |
8,412 / 21,250 |
demo |
███████████░░░░░░░░░ 56.2% |
1,497 / 2,663 |
warehouse_sources_queue |
████████████░░░░░░░░ 59.2% |
148 / 250 |
tasks |
██████████████░░░░░░ 69.1% |
29,366 / 42,488 |
data_tools |
██████████████░░░░░░ 70.0% |
63 / 90 |
ai_gateway |
███████████████░░░░░ 75.0% |
9 / 12 |
signals |
████████████████░░░░ 79.1% |
20,386 / 25,788 |
cdp |
████████████████░░░░ 80.7% |
3,117 / 3,863 |
data_modeling |
█████████████████░░░ 82.8% |
5,529 / 6,675 |
wizard |
█████████████████░░░ 84.8% |
935 / 1,102 |
notebooks |
█████████████████░░░ 85.3% |
7,266 / 8,522 |
agent_platform |
█████████████████░░░ 86.4% |
3,807 / 4,405 |
actions |
█████████████████░░░ 86.6% |
717 / 828 |
cohorts |
██████████████████░░ 87.8% |
4,488 / 5,114 |
product_tours |
██████████████████░░ 87.9% |
1,303 / 1,482 |
exports |
██████████████████░░ 88.4% |
6,949 / 7,861 |
data_warehouse |
██████████████████░░ 88.8% |
11,867 / 13,358 |
business_knowledge |
██████████████████░░ 89.0% |
4,391 / 4,936 |
engineering_analytics |
██████████████████░░ 89.2% |
5,641 / 6,323 |
conversations |
██████████████████░░ 89.3% |
16,820 / 18,834 |
dashboards |
██████████████████░░ 89.4% |
5,983 / 6,693 |
visual_review |
██████████████████░░ 89.4% |
5,818 / 6,505 |
error_tracking |
██████████████████░░ 89.7% |
10,174 / 11,342 |
alerts |
██████████████████░░ 89.9% |
4,054 / 4,508 |
early_access_features |
██████████████████░░ 90.1% |
1,031 / 1,144 |
mcp_analytics |
██████████████████░░ 90.1% |
2,763 / 3,065 |
streamlit_apps |
██████████████████░░ 90.4% |
2,501 / 2,767 |
links |
██████████████████░░ 90.6% |
183 / 202 |
slack_app |
██████████████████░░ 90.7% |
9,025 / 9,948 |
marketing_analytics |
██████████████████░░ 91.0% |
11,792 / 12,964 |
stamphog |
██████████████████░░ 91.1% |
4,056 / 4,450 |
product_analytics |
██████████████████░░ 91.3% |
5,811 / 6,362 |
mcp_store |
██████████████████░░ 91.9% |
4,257 / 4,634 |
notifications |
███████████████████░ 92.6% |
1,011 / 1,092 |
ai_observability |
███████████████████░ 92.7% |
14,944 / 16,117 |
web_analytics |
███████████████████░ 92.9% |
14,119 / 15,206 |
surveys |
███████████████████░ 93.0% |
5,730 / 6,163 |
managed_migrations |
███████████████████░ 93.1% |
1,424 / 1,530 |
posthog_ai |
███████████████████░ 93.2% |
1,326 / 1,422 |
approvals |
███████████████████░ 93.3% |
3,437 / 3,682 |
reminders |
███████████████████░ 93.4% |
468 / 501 |
workflows |
███████████████████░ 93.5% |
6,337 / 6,775 |
legal_documents |
███████████████████░ 94.1% |
1,568 / 1,667 |
endpoints |
███████████████████░ 94.1% |
8,640 / 9,177 |
messaging |
███████████████████░ 94.3% |
2,682 / 2,845 |
tracing |
███████████████████░ 94.5% |
2,670 / 2,826 |
skills |
███████████████████░ 94.5% |
2,893 / 3,061 |
revenue_analytics |
███████████████████░ 94.6% |
3,651 / 3,858 |
review_hog |
███████████████████░ 94.7% |
6,814 / 7,199 |
logs |
███████████████████░ 95.4% |
9,935 / 10,416 |
experiments |
███████████████████░ 95.7% |
24,882 / 25,996 |
growth |
███████████████████░ 96.1% |
3,245 / 3,376 |
replay_vision |
███████████████████░ 96.2% |
14,973 / 15,572 |
annotations |
███████████████████░ 96.2% |
732 / 761 |
feature_flags |
███████████████████░ 96.5% |
17,110 / 17,734 |
user_interviews |
███████████████████░ 96.5% |
2,638 / 2,734 |
access_control |
███████████████████░ 96.8% |
851 / 879 |
warehouse_sources |
███████████████████░ 97.1% |
327,769 / 337,448 |
customer_analytics |
███████████████████░ 97.3% |
8,380 / 8,610 |
data_catalog |
███████████████████░ 97.4% |
2,367 / 2,429 |
analytics_platform |
████████████████████ 98.0% |
2,153 / 2,197 |
metrics |
████████████████████ 98.2% |
2,491 / 2,536 |
pulse |
████████████████████ 98.4% |
2,017 / 2,049 |
live_debugger |
████████████████████ 99.2% |
613 / 618 |
field_notes |
████████████████████ 99.4% |
158 / 159 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
|
Retaining stamphog approval — delta since last review classified as |
… tests The verification tests isolate verification-QUERY failure handling and mock setup_duckgres_session (session setup, not under test). The new create_staging_read_secret is another setup step; unmocked, its conn.execute tripped the test's execute side_effect before the verification query ran, so the exception escaped the handler. Mock it alongside setup_duckgres_session in both the failure and success cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Retaining stamphog approval — delta since last review classified as |
Problem
On cache-proxy-enabled duckgres clusters, the org's ambient S3 secret deliberately carries
USE_SSL falseso httpfs traffic flows through the logging cache proxy. Butdelta_scan's delta-kernel object store ignores DuckDB's proxy configuration and dials the plain-HTTP S3 endpoint directly — and direct port-80 egress is silently dropped by the duckgres worker network policy.Verified in mw-prod-us CP logs (2026-07-22): every duckgres-side
delta_scanin the data-imports and data-modeling copy workflows fails withDeltaKernel ObjectStoreError … GET http://s3.us-east-1.amazonaws.com/... after 10 retriesat ~58s per attempt, continuously re-attempted across many teams (team 2, devex, 19618, 35787, …) — 29 failures/15min, ~2 worker-minutes burned per minute, zero successes, each attempt pinning a dedicated worker under duckgres's one-session-per-worker model.Change
create_staging_read_secret(conn, catalog_bucket)inposthog/ducklake/storage.py, called aftersetup_duckgres_sessionat the three duckgresdelta_scansites (imports create, imports verification, modeling create):credential_chainresolves the worker's own ambient (org-scoped) credentials and region; no secret material crosses the wire.How did you test this code?
I'm an agent; checks actually run:
test_copy_data_imports_to_ducklake_activity_via_duckgresto require the secret DDL (provider/scope/USE_SSL) before the firstdelta_scan; watched it fail, then implemented.test_ducklake_copy_data_imports_workflow.py -k duckgres: 4 passed;test_ducklake_copy_data_modeling_workflow.py -k duckgres: 1 passed.Rollback
Revert; behavior returns to today's failing-loop state (no data loss — the loop never succeeded).
🤖 Agent context
Authored by Claude Code (Fable 5) during the duckgres-sink throughput investigation; the failure signature (silent port-80 egress drop) matches the documented worker warmup air-gap incident.
🤖 Generated with Claude Code