Skip to content

fix: route captured network decisions through Tessera - #1419

Open
Richie Gomez (richiemsft) wants to merge 3 commits into
richiemsft/wfp-learning-mode-decoderfrom
richiemsft/wfp-learning-mode-integration
Open

Richie Gomez (richiemsft) wants to merge 3 commits into
richiemsft/wfp-learning-mode-decoderfrom
richiemsft/wfp-learning-mode-integration

Conversation

@richiemsft

@richiemsft Richie Gomez (richiemsft) commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

📖 Description

Routes direct ProcessContainer denial-capture traffic through Tessera so WFP Learning Mode can observe the policy decision without weakening enforcement.

  • Synthesizes internetClient only for direct directional captureDenials requests.
  • Keeps the serialized PSEC egress policy authoritative.
  • Deliberately excludes runtime proxy mode from the synthesized direct-egress capability.
  • Adds regression coverage for direct and proxy postures and shared capability helpers.

This is PR 3 of 4 in the WFP Learning Mode stack. Its base is the decoder-layer branch.

🔗 References

Related to #1286.

Depends on the preceding decoder PR in this stack.

🔍 Validation

  • cargo test -p mxc-sdk --lib 'capture_denials_' — 25 passed.
  • cargo test -p mxc-sdk --lib 'network_policy_helpers::tests::' — 5 passed.

✅ Checklist

  • Signed the Contributor License Agreement
  • Linked to an issue
  • Updated documentation (covered by the following documentation PR)
  • Updated Copilot instructions (not applicable)
  • If this PR changes Cargo.lock, the dependency-feed-check check passes (not applicable)

📋 Issue Type

  • Bug fix
  • Feature
  • Task

🧱 Stack

  1. feat: prefer option-aware Learning Mode trace startup #1417 — API startup and compatibility
  2. feat: decode WFP Learning Mode network events #1418 — WFP event decoding
  3. fix: route captured network decisions through Tessera #1419 — ProcessContainer integration
  4. docs: describe WFP denial capture #1420 — Documentation

Review and merge in this order.

Microsoft Reviewers: Open in CodeFlow

@richiemsft
Richie Gomez (richiemsft) requested a review from a team as a code owner October 6, 2026 20:38
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@MGudgin Gudge (MGudgin) 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.

Verified review notes

The substantive issue is treating the normalized network_egress Option as evidence that a caller explicitly requested egress; the second comment asks for a negative control on the separate no-capture guard. This is a comment-only review, not a change request.

Verified clean: GitHub's patch matches the local delta. The new tests preserve the proxy posture and prove that the default-deny egress table is still serialized. ensure_capability avoids duplicate capability strings. The runner gains only two new tests (48 to 50); neither covers a parsed request with absent or ingress-only network policy. I did not reproduce a brokered-DNS/Tessera bypass on a PSEC host and am not asserting one.

Verified pre-existing — not attributed to this PR

src/mxc-sdk/src/core/mxc_common/network_parser.rs:159-175 is byte-identical at base and head. Its normalization of absent egress to Some(default) is not itself charged to this PR; the new gate's reliance on presence is the introduced defect. The existing egress-rule serializer and guarded AppContainer capability helper are also unchanged and are not being treated as regressions.

.collect();
add_default_network_capabilities(policy, &mut capabilities);
if policy.capture_denials.is_some()
&& policy.network_egress.is_some()

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.

Medium (correctness) — Normalized Some does not mean explicitly requested egress.

Attribution: introduced_by_change — this new gate tests network_egress.is_some(), but parse_network_policy fills network_egress = Some(NetworkEgressPolicy::default()) when network is absent and also when a supplied network section omits egress.

Consequently, parsed direct captureDenials requests with no network section or with ingress only can gain internetClient even though the PR promises synthesis only for direct directional egress requests. The PSEC default egress table still denies traffic; this is a capability-posture and denial-observation change, not proof of an egress bypass. Fix: Preserve explicit egress-section presence through normalization and use that signal here; add parse-to-PSEC tests for absent network, ingress-only and explicitly authored egress.

.cloned()
.collect();
add_default_network_capabilities(policy, &mut capabilities);
if policy.capture_denials.is_some()

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.

Medium (test coverage) — Pin the no-capture side of this privilege gate.

Attribution: introduced_by_change — both added tests have capture_denials = Some(...). Existing shared-helper tests do not run through this new effective_capabilities branch. If this capture_denials.is_some() guard were removed, ordinary default-deny ProcessContainer requests could gain internetClient without failing a PSEC-builder test.

Fix: Build a PSEC spec with capture_denials = None and directional egress.default = deny; assert that it has no internetClient and still serializes deny-default egress. The parse-to-PSEC matrix in the other comment should cover the positive and negative cases together.

@richiemsft
Richie Gomez (richiemsft) force-pushed the richiemsft/wfp-learning-mode-decoder branch from d66c3b4 to b3f6785 Compare October 7, 2026 18:37
@richiemsft
Richie Gomez (richiemsft) force-pushed the richiemsft/wfp-learning-mode-integration branch from 731c328 to cd9e80a Compare October 7, 2026 18:37
@richiemsft
Richie Gomez (richiemsft) force-pushed the richiemsft/wfp-learning-mode-decoder branch from b3f6785 to 31a0195 Compare October 7, 2026 18:45
@richiemsft
Richie Gomez (richiemsft) force-pushed the richiemsft/wfp-learning-mode-integration branch 4 times, most recently from cdbd9d6 to 82dce5d Compare October 7, 2026 20:37
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e408b60b-e267-416c-806d-0a7e119fe53f
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e408b60b-e267-416c-806d-0a7e119fe53f
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e408b60b-e267-416c-806d-0a7e119fe53f
@richiemsft
Richie Gomez (richiemsft) force-pushed the richiemsft/wfp-learning-mode-decoder branch from 05c16d0 to 183a905 Compare October 7, 2026 22:36
@richiemsft
Richie Gomez (richiemsft) force-pushed the richiemsft/wfp-learning-mode-integration branch from 82dce5d to 72c85b5 Compare October 7, 2026 22:36

This branch has not been deployed

No deployments
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.

2 participants