Repository navigation
fix(datasources): bound connector reads and verify real query access - #183
Conversation
Datasource Lambdas cap success (4 MiB) and error (64 KiB) bodies before parsing and close streams on every exit. Missing explicit instance IDs fail closed. Connection tests run the real bounded query operation, and Jaeger/Dynatrace/Datadog/Loki report partial or unverified results instead of absence. Prometheus/Mimir enforce the saved execution ceiling inside the connector. Optional Jaeger/Dynatrace VPC attachment stays default-off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 AI Code Review (two independent reviewers)_Reviewer responses: codex/ALL claude/ALL _ Status: PASSED — No blocking issues found Both panels' MAJOR claims check out as either intentional, disclosed behavior changes or as heuristics that exactly mirror existing base-code logic. Key verifications: the backfill script's origin-match condition replicates Chair Review — PR #183: fix(datasources): bound connector reads and verify real query access1. SummaryThis PR replaces public health-endpoint connection tests with bounded real-query probes across all eight native observability connectors, adds byte/deadline bounds to connector HTTP reads, makes explicit-instance credential lookups fail closed (no kind-mirror fallback), and extends the completeness-evidence ( 2. Issues per lensL2 — Code correctnessMAJOR claims — verified, downgraded (excluded from gate):
MINOR:
L3 — Security / AWS mutation safetyBoth panels independently confirmed: no ADR-005 violation — no AWS-mutating call, no IAM/Terraform change, no hardcoded secret; SSRF guards ( MAJOR claims — verified, downgraded (excluded from gate):
MINOR:
L4 — Observability / data-integration correctnessNo Steampipe query or CIS control is touched. Both panels found the completeness-evidence model coherent: MINOR:
L5 — Docs/ADR consistencyThe four locale docs,
MINOR:
3. Suggestions
4. VerdictAll CRITICAL/MAJOR candidates were reconciled against BASE plus the complete patch: the two claude L2 MAJORs are disclosed, knob-controlled intentional behavior changes; codex's ClickHouse L2 MAJOR is pre-existing exposure that this PR actually narrows; claude's L3 MAJOR is the deliberate fail-closed fix with a documented, repo-conventional rollout ordering; codex's L3 MAJOR replicates the base code's own accepted heuristic under stricter conditions and never widens base exposure. No in-scope CRITICAL/MAJOR remains; remaining findings are MINOR. No images were listed in the manifest and no deleted/unavailable/omitted entries exist. IMAGE_COVERAGE: NOT_REQUIRED Triggered by commit |
…ation Review follow-ups for the connector bounds: connect, headers and body share one monotonic deadline so a slow upstream cannot double the aligned HTTP timeout past the Lambda wall; oversized or slow error bodies keep their HTTP status. Loki and Jaeger report limit saturation as partial with requested/returned counts, separately from byte-bound loss. Connection probes return latency_ms, accept empty or warned results, and keep the SSRF classification. The default kind mirror is stamped with its instance id, the id-keyed lookup accepts only that default's mirror (legacy unstamped mirrors keep working with a warning until the next save), and timeoutS rides the console conn config for every kind. Restores the resolve-and-recheck disclosure that the stacked agent change replaces. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
55b8c7d to
06759fd
Compare
Custom MCP transports connect to the address set validated at request time while preserving Host, TLS SNI and certificate verification, and reject every 3xx. IPv6 addresses are bracketed so AAAA-only endpoints connect. The transport deadline and the MCP session read timeout follow a 60s read budget separate from the 8s connect budget. A malformed port is an SSRF-classified rejection, discarded per-address failures are logged, and pasted trailing whitespace in an api_key value is stripped. The pin composes with the default-off custom MCP governance: spec validation and the attested secret version run first, then the validated addresses are pinned for that session. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…tor-bounds # Conflicts: # agent/agent.py # agent/lambda/datasource_http.py # agent/pinned_http.py # agent/streamable_http_sigv4.py # agent/test_agent.py # agent/test_pinned_http.py
* fix(web): show datasource completeness, limits and shared scope The datasource API and UI report instance-specific configuration only, show effective execution/response limits, pass the selected window to trace and SaaS kinds, reject unsupported SQL range shapes, and label shared default datasources. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): align datasource guides with the stacked connector contract Review follow-ups: the datasource guides (ko/en/ja/zh) and API reference describe the shared timeout contract, the real-query connection test and the Mimir API prefix; the reference doc records Loki saturation disclosure, the shared request deadline and the oauth_3lo posture. The form no longer offers oauth_3lo. A Datadog instance's legacy key pair counts as configured and survives a settings-only PATCH regardless of the row's authType. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: address review feedback (iteration 1/5) * fix: address review feedback (iteration 2/5) * fix(web): defer oauth_3lo enablement to the custom MCP governance gate The enable-time transport check is superseded by the merged default-off governance gate, which admits only api_key and oauth_client_credentials; registration validation and the form still reject oauth_3lo. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Reverts the #185 squash (b5bfb94). It was merged into this branch instead of dev, which pushed this PR's diff to 245 KB — past the AI review input limit, so the reviewers were never called. The web and documentation change returns as a dev-based PR after this one merges. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The instance-id stamp on the default kind mirror, the console-path timeoutS forwarding and the default/delete mirror handling are web changes that ship with the datasource web contract PR. Keeping them here pushed this PR against the review input limit; the connector side already fails closed without an id-bound credential, and the runbook's backfill (re-save the default) writes the id key with today's web code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The optional Jaeger/Dynatrace VPC flags move to their own PR and the datasource-development FAQ wording moves to the web contract PR; both are independent of the connector changes reviewed here. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The feature-level bullet describes the net behavior of the connector and web changes together, so it ships with the final PR of the pair; this keeps the connector PR within the review input limit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The AI review input limit is 128 KiB and this PR's diff was 131 KiB, so the review never reached a model. The 544-line test_external_connections.py moves unchanged to a follow-up PR stacked on this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Moved |
|
Review response for
|
…tor-bounds # Conflicts: # docs/runbooks/CLAUDE.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Part 1 of 3 (stack base). Merge order: this PR → #184 → #185. #184 and #185 are stacked on this branch so each review sees the connector behavior its own change depends on; once this merges, retarget #184 to
dev.{ok, verified, latency_ms, error?}with fixed sentences, acceptsok|empty|partial(an upstream warning onvector(1)is still access), and keeps the SSRF-policy classification.partial/ unverified completion states instead of claiming absence. Loki and Jaeger report reaching the requested limit aslimitSaturated+partialwithrequestedLimit/returnedCount;truncatedis reserved for records the connector actually dropped (Jaeger's byte-boundpreviewis no longer echoed).apiPrefix(null/absent =/prometheus, explicit""= root).mirrorDefaultCredential(..., instanceId), all four write sites). The connector's id-keyed lookup accepts the mirror only for that default; a sibling id can never borrow it. A mirror written before the stamp (migrated default whose id key was never written) fails closed on the credential-blind path; the administrator save of the verified current default (exact endpoint match, under the manage lock) recovers it, writes the id key and stamps the mirror. Switching or deleting a default never lends the previous default's mirror to its successor. Rollout order and the backfill procedure:docs/runbooks/datasource-credential-isolation.md— re-save every migrated default before deploying the connector producers.timeoutSrides the console conn config for every kind (previously ClickHouse only), so console and credential-blind paths hand the connector the same bound.jaeger_vpc_enabled/dynatrace_vpc_enabled(defaultfalse, requireagentcore_enabled && integrations_enabled).No deployment or flag activation is done here. A gateway catalog/schema refresh is a separate provisioning step.
Review follow-ups (round 1)
Lambda wall-clock overrun → single deadline; migrated-default
NotConnectedregression → stamped mirror, recovery only through the verified-current-default admin save, documented backfill before rollout;timeoutSpath divergence → forwarded on the console path here; Loki saturation reported as complete →limitSaturated;pinned_http.pyasserted but absent → that docstring now lands with the module in #184 and the resolve-and-recheck disclosure is kept here;latency_msrestored; Prometheus/Mimir probe acceptance aligned; MimirapiPrefixnull handling; orphaned_timeout_paramhelpers removed.Tests
bash scripts/v2/merge-verify.shon Python 3.12 againstdev9b8ab40: web vitest PASS, Terraform fmt + validate PASS, deployment Node tests PASS. The only Python-stage failures aretest_review_codec_sandbox.py/test_pr_review_head_images.py, which need a preparedAWSOPS_REVIEW_CODEC_STATEthis host does not have (same on thedevbaseline).test_external_connections.pyadds deadline-sharing, Loki/Jaeger saturation, probe latency/SSRF-classification and stamped-mirror cases).terraform test(mock provider) → 27 passed.🤖 Generated with Claude Code