Skip to content

fix(sdk/python): add AGENTFIELD_SKIP_IP_DETECTION opt-out for container IP probing - #921

Closed
AmirF194 wants to merge 3 commits into
Agent-Field:mainfrom
AmirF194:fix/624-container-ip-detection-optout
Closed

fix(sdk/python): add AGENTFIELD_SKIP_IP_DETECTION opt-out for container IP probing#921
AmirF194 wants to merge 3 commits into
Agent-Field:mainfrom
AmirF194:fix/624-container-ip-detection-optout

Conversation

@AmirF194

Copy link
Copy Markdown

Root cause

_build_callback_candidates() in sdk/python/agentfield/agent.py calls _detect_container_ip() unconditionally whenever _is_running_in_container() is true, with no way to opt out. _detect_container_ip() sends blocking requests to AWS/Azure/GCP cloud-metadata endpoints (169.254.169.254, metadata.google.internal) and falls back to the third-party api.ipify.org, regardless of whether an explicit AGENT_CALLBACK_URL (or constructor callback_url) is already set. In a Kubernetes deployment with a restrictive NetworkPolicy, this fires on every agent start, flooding deny logs, and it also leaks pod egress to a third party for a best-effort candidate that most deployments never use.

Fix

Add AGENTFIELD_SKIP_IP_DETECTION (default false, same boolean-env-var convention already used by AGENTFIELD_LOG_PAYLOADS/AGENTFIELD_LOG_TRACKING/AGENTFIELD_LOG_FIRE in logger.py) and gate the _detect_container_ip() call behind it. Default behavior is unchanged; the Railway-specific hint and the local-network/hostname/localhost fallbacks are untouched. Documented in docs/ENVIRONMENT_VARIABLES.md.

On the prior closed attempts

Four earlier PRs on this issue (#698, #740, #770, #834) were closed as placeholder tests dropped into a root tests/ directory that isn't part of this repo's layout, without an actual fix. This PR is different: it changes the real behavior in sdk/python/agentfield/agent.py and adds tests in sdk/python/tests/test_agent_networking.py, the file that already covers this exact function, following its existing monkeypatch style.

Verification

  • New tests (test_build_callback_candidates_skips_ip_detection_when_disabled, test_build_callback_candidates_runs_ip_detection_by_default, test_ip_detection_disabled_is_case_insensitive, test_ip_detection_disabled_defaults_to_false) fail on unmodified main (AttributeError / probe still called) and pass on this branch, in a clean Docker container.
  • Full sdk/python suite (./scripts/run_pytest.sh) green on Python 3.10 and 3.12 (the matrix's low and high ends): 1968 passed, 4 pre-existing skips, no new failures.
  • ruff check . on this branch reports the same 9 pre-existing findings as unmodified main, all inside a build/lib/ pip-build artifact directory unrelated to this diff; nothing in the changed files.
  • Not verified: an actual Kubernetes NetworkPolicy blocking egress (no cluster in this sandbox). The fix is a control-flow gate on an existing, already-tested function, not a change to its detection logic.

…er IP probing

_build_callback_candidates() calls _detect_container_ip() unconditionally
whenever _is_running_in_container() is true, regardless of whether an
explicit callback URL is already known. That function fires blocking
requests to cloud-metadata endpoints (169.254.169.254,
metadata.google.internal) and falls back to the third-party api.ipify.org,
with no way to turn it off. In a Kubernetes NetworkPolicy-restricted
environment this floods deny logs and leaks pod egress to a third party
for a best-effort callback candidate that is often unused.

Add AGENTFIELD_SKIP_IP_DETECTION (default false, same boolean-env-var
convention used elsewhere in this module) and gate the probe behind it.
Default behavior is unchanged.

Fixes Agent-Field#624
@AmirF194
AmirF194 requested review from a team and AbirAbbas as code owners August 16, 2026 19:25
@CLAassistant

CLAassistant commented Aug 16, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ santoshkumarradha
❌ AmirF194
You have signed the CLA already but the status is still pending? Let us recheck it.

@santoshkumarradha santoshkumarradha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for tightening this up. The opt-out gate is small, the networking tests passed locally, and the docs note is clear. The only remaining blocker I see is the CLA check. Once that’s signed, this should be good to go.

@AmirF194

Copy link
Copy Markdown
Author

Thanks for the review. Working on getting the CLA signed, will follow up here once it's cleared.

@github-actions

Copy link
Copy Markdown
Contributor

Performance

SDK Memory Δ Latency Δ Tests Status
Python 9.0 KB - 0.28 µs -20%

✓ No regressions detected

@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 84%, aggregate ≥ 85%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 87.10% 87.40% ↓ -0.30 pp 🟡
sdk-go 92.80% 92.00% ↑ +0.80 pp 🟢
sdk-python 94.20% 93.73% ↑ +0.47 pp 🟢
sdk-typescript 91.17% 90.42% ↑ +0.75 pp 🟢
web-ui 84.76% 84.79% ↓ -0.03 pp 🟡
aggregate 85.62% 85.75% ↓ -0.13 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions

Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 0 ➖ no changes
sdk-go 0 ➖ no changes
sdk-python 0 ➖ no changes
sdk-typescript 0 ➖ no changes
web-ui 0 ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

@AbirAbbas

Copy link
Copy Markdown
Contributor

Closing this in favour of #969, which lands the same opt-out from a clean-room implementation (written from #624's description, not from this diff) and also skips the probe automatically when a callback URL is already configured — the case pocesar originally reported. The CLA has been pending for ten days and we'd rather not leave #624 open longer; the diagnosis and the env-var approach were yours and #969 credits you for them. If you sign the CLA later we'd be glad to take future contributions.

@AbirAbbas AbirAbbas closed this Aug 26, 2026
auto-merge was automatically disabled August 26, 2026 16:05

Pull request was closed

@AmirF194
AmirF194 deleted the fix/624-container-ip-detection-optout branch August 26, 2026 16:22
@AmirF194

Copy link
Copy Markdown
Author

Thanks for the update, and for crediting the diagnosis. Glad to see #969 merged and covering the callback URL case too. Working on getting the CLA signed, would like to contribute again here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants