-
Notifications
You must be signed in to change notification settings - Fork 2.2k
No Pre-Commit Validation Hook for Network Policy YAML Changes - IssueFinder - SN 21 #1445
Copy link
Copy link
Open
Labels
enhancementNew feature or requestNew feature or requeststatus: triageFor new items that haven't been reviewed yet.For new items that haven't been reviewed yet.
Description
Problem Statement
The .pre-commit-config.yaml is comprehensive (gitleaks, hadolint, shellcheck) but has no validation hook for YAML network policy files. A malicious or accidental change to openclaw-sandbox.yaml (e.g., adding access: full to a new endpoint, or adding 0.0.0.0/0 as a host) would not be caught by any automated check before commit.
Impact
Policy changes that weaken security posture can be merged without automated detection.
Affected Area
- File(s): .pre-commit-config.yaml, nemoclaw-blueprint/policies/
Steps to Reproduce
- Modify
openclaw-sandbox.yamlto addhost: "*"withaccess: full - Run
pre-commit run --all-files - No hook catches the dangerous policy change
Expected Behavior
A pre-commit hook validates policy YAML against a security schema.
Actual Behavior
No validation occurs for policy YAML files.
Severity / Priority Suggestion
- Medium
Proposed Design
Recommended Fix
Step 1 — Create scripts/validate-policies.js:
#!/usr/bin/env node
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
// SPDX-License-Identifier: Apache-2.0
"use strict";
const fs = require("fs");
const yaml = require("js-yaml");
const path = require("path");
const VALID_METHODS = new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
const VALID_PROTOCOLS = new Set(["rest"]);
const VALID_ENFORCEMENTS = new Set(["enforce", "audit"]);
const VALID_ACCESS = new Set(["full"]);
function validatePolicy(filePath) {
const content = fs.readFileSync(filePath, "utf-8");
const doc = yaml.load(content);
const errors = [];
if (!doc.version) errors.push("Missing required field: version");
const policies = doc.network_policies || {};
for (const [name, policy] of Object.entries(policies)) {
if (!policy.endpoints || !Array.isArray(policy.endpoints)) {
errors.push(`${name}: endpoints must be an array`);
continue;
}
for (const ep of policy.endpoints) {
if (!ep.host) errors.push(`${name}: endpoint missing host`);
if (!ep.port) errors.push(`${name}: endpoint missing port`);
if (ep.protocol && !VALID_PROTOCOLS.has(ep.protocol))
errors.push(`${name}: invalid protocol "${ep.protocol}"`);
if (ep.access && !VALID_ACCESS.has(ep.access))
errors.push(`${name}: invalid access "${ep.access}"`);
if (ep.enforcement && !VALID_ENFORCEMENTS.has(ep.enforcement))
errors.push(`${name}: invalid enforcement "${ep.enforcement}"`);
if (ep.access && ep.rules)
errors.push(`${name}: access:full and rules are mutually exclusive`);
for (const rule of ep.rules || []) {
const allow = rule.allow || {};
if (allow.method && !VALID_METHODS.has(allow.method))
errors.push(`${name}: invalid HTTP method "${allow.method}"`);
if (allow.path && !allow.path.startsWith("/"))
errors.push(`${name}: path must start with /: "${allow.path}"`);
}
}
}
return errors;
}
let exitCode = 0;
const files = process.argv.slice(2);
for (const f of files) {
const errors = validatePolicy(f);
if (errors.length > 0) {
console.error(`\n❌ ${f}:`);
errors.forEach((e) => console.error(` - ${e}`));
exitCode = 1;
} else {
console.log(`✅ ${path.basename(f)}`);
}
}
process.exit(exitCode);Step 2 — Add to .pre-commit-config.yaml (prek format):
- id: validate-policy-yaml
name: Validate NemoClaw policy YAML
entry: node scripts/validate-policies.js
language: node
files: 'nemoclaw-blueprint/policies/.*\.yaml$'
priority: 6
additional_dependencies: ['js-yaml']Step 3 — Add js-yaml as dev dependency:
npm install --save-dev js-yamlAlternatives Considered
No response
Category
enhancement: feature
Checklist
- I searched existing issues and this is not a duplicate
- This is a design proposal, not a "please build this" request
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requeststatus: triageFor new items that haven't been reviewed yet.For new items that haven't been reviewed yet.