Skip to content

refactor(policy): extract shared L7 endpoint validation#2389

Open
gracesmith6504 wants to merge 1 commit into
NVIDIA:mainfrom
gracesmith6504:fix/1714-shared-l7-validation
Open

refactor(policy): extract shared L7 endpoint validation#2389
gracesmith6504 wants to merge 1 commit into
NVIDIA:mainfrom
gracesmith6504:fix/1714-shared-l7-validation

Conversation

@gracesmith6504

Copy link
Copy Markdown
Contributor

Summary

Extract 9 L7 endpoint semantic checks into a shared validate_l7_endpoint_semantics() function in openshell-policy. Both profile lint (openshell-providers) and the runtime validator (openshell-supervisor-network) now call the shared function via a lightweight L7EndpointFields field bag, eliminating duplication and preventing drift. Also consolidates the L7Protocol enum into a single definition in openshell-policy.

Related Issue

Fixes #1714

Changes

  • New shared validation module crates/openshell-policy/src/l7_validate.rs with L7Protocol enum, L7EndpointFields struct, validate_l7_endpoint_semantics() function, and 15 unit tests
  • Re-export shared validation types from crates/openshell-policy/src/lib.rs
  • Add openshell-policy dependency to crates/openshell-providers/Cargo.toml
  • Replace inline L7 checks with shared function call in crates/openshell-providers/src/profiles.rs; add 5 integration tests
  • Delete duplicate L7Protocol enum from crates/openshell-supervisor-network/src/l7/mod.rs, import and re-export from openshell-policy; replace 9 duplicated checks with shared function call; align rules_would_deny_all computation
  • Fix 4 test fixtures in crates/openshell-server/src/grpc/policy.rs and provider.rs: add access: "full" to endpoints with protocol

Testing

  • mise run pre-commit passes
  • Unit tests added/updated
  • E2E tests added/updated (if applicable)

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable)

Move 9 L7 endpoint semantic checks into a shared
validate_l7_endpoint_semantics() function in openshell-policy.

Both profile lint (openshell-providers) and the runtime validator
(openshell-supervisor-network) now call the shared function via a
lightweight L7EndpointFields field bag, eliminating duplication and
preventing the two implementations from drifting apart.

Update server test fixtures that used protocol without rules or
access, which the shared validator now correctly rejects.

Fixes NVIDIA#1714

Signed-off-by: Grace Smith <grasmith@redhat.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@johntmyers johntmyers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

gator-agent

PR Review Status

Validation: This PR is project-valid because it implements the confirmed provider-v2 lint/runtime validation gap in #1714 using the shared policy-layer approach recommended during maintainer triage.
Head SHA: 73f81c6673a825dde5b41c8f1d8710b5cb89a1f9

Review findings:

  • Changes are requested for collection-presence regression, mixed-case MCP validation/runtime inconsistency, and divergent malformed-rule classification.
  • One additional suggestion asks the author to preserve or explicitly test the intended JSON-RPC diagnostic aggregation.

Docs: Not needed; this restores lint/runtime parity for already-documented endpoint semantics and does not introduce new user-facing behavior.

Next state: gator:in-review pending an author update.

pub access: &'a str,

/// `true` when the endpoint has a non-empty rules list.
pub has_rules: bool,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

gator-agent

Warning: has_rules conflates an absent rules field with an explicitly empty rules: []. The old runtime validator explicitly rejected an empty list, but that check is removed, so an L4 endpoint with rules: [] now produces no L7 error and rules: [] plus access is accepted. Preserve presence separately or retain the runtime-specific empty-list check, with regression coverage for absent versus empty collections.

impl L7Protocol {
/// Parse a protocol string into a known variant.
pub fn parse(s: &str) -> Option<Self> {
match s.to_ascii_lowercase().as_str() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

gator-agent

Warning: Case-insensitive parsing now drives the shared MCP exemptions, but downstream validation and expand_access_presets still compare the authored string to lowercase "mcp". For example, protocol: MCP with allow_all_known_mcp_methods: true and no rules now passes semantic validation, but the runtime does not synthesize the MCP allow-all rule. Normalize protocol values before all downstream processing or reject noncanonical casing, then add a validation-to-expansion regression test.

ep.get("rules")
.and_then(|v| v.as_array())
.is_some_and(|rules| {
!rules.is_empty() && rules.iter().all(|rule| rule.get("allow").is_none())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

gator-agent

Warning: The two callers still disagree on what constitutes a missing allow clause: profile lint uses Option::is_none, while this adapter only detects a missing JSON key. allow: null passes here, and proto-to-OPA conversion turns allow: None into an empty allow object, so configurations rejected by lint can pass runtime semantic validation. Preserve optionality through conversion or pass a shared rule-shape classification, and test the same malformed rule through both callers.

}

// 4. json-rpc requires explicit rules
if is_jsonrpc && !ep.has_rules && ep.access.is_empty() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

gator-agent

Suggestion: This changes runtime error aggregation: JSON-RPC without rules previously emitted both the explicit-rules and base-allow errors, while JSON-RPC with an access preset also emitted the missing-rules error. If reducing redundant diagnostics is intentional, add exact error-list tests for these combinations; otherwise preserve the previous aggregation.

@johntmyers johntmyers added the gator:in-review Gator is reviewing or awaiting PR review feedback label Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gator:in-review Gator is reviewing or awaiting PR review feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(providers): provider v2 profile lint does not validate L7 endpoint constraints (protocol/access/rules)

2 participants