Skip to content

No Pre-Commit Validation Hook for Network Policy YAML Changes - IssueFinder - SN 21 #1445

@dinuduke

Description

@dinuduke

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

  1. Modify openclaw-sandbox.yaml to add host: "*" with access: full
  2. Run pre-commit run --all-files
  3. 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-yaml

Alternatives 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestenhancement: testingUse this label to identify requests to improve NemoClaw test coverage.priority: highImportant issue that should be resolved in the next releasesecuritySomething isn't secure

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions