nitinjain999/platform-skills/ai-governance
Claude Code and agent skill by nitinjain999/platform-skills
- community
Checking that the SKILL.md file is still in the repository.
Generate and enforce policy gates for AI coding agents (Copilot, Claude Code) — real-time session hooks that deny protected-path edits and dangerous commands, plus a merge-time backstop for anything that bypasses them. Use when asked to "govern AI agents", "block AI from touching secrets", "add an AI policy gate", or "why did the AI agent hook not fire".
Install
npx vskill@latest install nitinjain999/platform-skills/ai-governanceSKILL.md
Generate and enforce a policy gate for AI coding agents operating on this repo: real-time session hooks for Copilot and Claude Code, plus a merge-time GitHub Actions check that catches anything the hooks miss.
Read references/ai-governance.md before responding.
Interactive Wizard (fires when no arguments are provided)
When invoked with no arguments, ask before proceeding:
Q1 — Mode?
Q2 — Context (after mode selected, one at a time):
- generate:
Which default policy pack? (terraform / kubernetes / generic / blank) - check:
Give me a file path, a command string, or a diff range (e.g. main...HEAD) to test: - audit:
Which org or repo list should I scan? - explain:
Path to the .ai-governance.yaml to explain (default: ./.ai-governance.yaml):
Then proceed into the relevant mode below.
Mode: generate
Scaffold the policy file, evaluator, session hooks, and merge-time check for this repo.
Steps:
- Detect which AI tools are configured (
.github/copilot/,.claude/,.cursor/,.codex/if present) and which CI system is in use — reuse the scan approachsetup-agents.mdalready implements; do not reimplement it.
- Write
.ai-governance.yamlwith the chosen default pack. All packs share this shape; onlyprotected_pathsdiffers:
generic: ```yaml version: 1 source: local enforcement: audit protected_paths:
- ".github/workflows/**"
- ".github/hooks/**"
- ".claude/settings.json"
- ".ai-governance.yaml"
- ".ai-governance/**"
- "/secrets/"
denied_commands:
- "rm -rf"
- "git push --force"
max_diff_files: 25 require_disclosure: true ```
terraform (adds): "**/*.tfstate", "iam/**" to protected_paths; adds "terraform apply" to denied_commands.
kubernetes (adds): "**/rbac/**", "**/*secret*.yaml" to protected_paths; adds "kubectl delete" to denied_commands.
blank: same shape, empty protected_paths/denied_commands — for a team that wants to author its own list from the CODEOWNERS-mandatory paths onward.
- Copy
examples/ai-governance/evaluate.shinto.ai-governance/evaluate.shin the target repo, executable bit set (chmod +x).
- Check for
yqv4 (command -v yq && yq --version). If it is missing, stop and ask the user to install it: Homebrew (brew install yq) on macOS, their distribution's package, or a release binary from github.com/mikefarah/yq/releases checked against its published checksum. Never install it yourself. It needssudo, and this binary parses the file that decides what the agent may touch, so where it comes from is the user's call. In CI,ubuntu-latestalready ships yq v4, andexamples/ai-governance/ai-governance-check.ymlpins and verifies its own copy.
- Write
.github/hooks/preToolUse.json:
``json { "version": 1, "hooks": { "preToolUse": [ {"type": "command", "bash": ".ai-governance/evaluate.sh --mode=hook --platform=copilot --event=preToolUse", "timeoutSec": 10} ] } } ` And .github/hooks/postToolUse.json (same shape, --event=postToolUse). This one is not a second gate. --event=postToolUse short-circuits before the policy is even loaded: it appends one completed line to the audit log, emits no decision, and exits 0. It never re-evaluates protected_paths or denied_commands — the call has already run by then, and re-deciding would duplicate the audit line preToolUse already wrote for the same call under audit or warn: `json { "version": 1, "hooks": { "postToolUse": [ {"type": "command", "bash": ".ai-governance/evaluate.sh --mode=hook --platform=copilot --event=postToolUse", "timeoutSec": 10} ] } } ``
On Claude Code, prefer the plugin: with platform-guardrails@platform-skills enabled, the PreToolUse/PostToolUse gate already ships from the plugin and switches on in any project that commits .ai-governance.yaml. Skip the settings merge below in that case (a second wiring would evaluate every call twice), and keep only the policy file and .ai-governance/ assets in the repository.
- Merge, never overwrite
.claude/settings.json.
Claude Code's settings.json hook registration is three levels deep, not two: each event key holds an array of matcher-group objects, and each matcher group holds its own inner hooks array of handler objects. matcher is optional — omitting it means "match every tool call", which is what this policy wants (every call gets evaluated, not just one tool): ``json { "hooks": { "PreToolUse": [ { "hooks": [ {"type": "command", "command": ".ai-governance/evaluate.sh --mode=hook --platform=claude --event=PreToolUse"} ] } ] } } ``
Merge into that structure with jq, appending a new matcher group whether or not the event key already has entries, and skipping the append if this exact command is already registered so re-running generate is idempotent: ```bash PRE_CMD='.ai-governance/evaluate.sh --mode=hook --platform=claude --event=PreToolUse' POST_CMD='.ai-governance/evaluate.sh --mode=hook --platform=claude --event=PostToolUse'
mkdir -p .claude [[ -f .claude/settings.json ]] || echo '{}' > .claude/settings.json
jq --arg pre "$PRE_CMD" --arg post "$POST_CMD" ' def add_group($event; $cmd): if [ (.hooks[$event] // [])[] | (.hooks // [])[]? | select(.command == $cmd) ] | length > 0 then . else .hooks[$event] = ((.hooks[$event] // []) + [{"hooks": [{"type": "command", "command": $cmd}]}]) end; add_group("PreToolUse"; $pre) | add_group("PostToolUse"; $post) ' .claude/settings.json > .claude/settings.json.tmp \ && mv .claude/settings.json.tmp .claude/settings.json ```
(.hooks[$event] // []) is what makes this safe on a file that has no hooks key, has hooks but not this event, or already has other matcher groups registered for this event. Never write .hooks.PreToolUse = [...] — that discards any matcher group the user already had.
- Write
.github/workflows/ai-governance-check.yml(copy fromexamples/ai-governance/ai-governance-check.yml) — this fetches the base branch's copy of the evaluator and policy before running, not the PR's own copy (see references/ai-governance.md's "Trusted verifier" section for why).
Bootstrap ordering — state this explicitly, don't let the user find out from a failing check: the workflow's git show origin/<base>:.ai-governance/evaluate.sh has nothing to read until a copy of the evaluator and policy already exists on the base branch. The very first PR that runs generate is, by definition, the PR that would create those files — so if that same PR also enables the required check, the check fails on its own PR before anything is on main to fetch. Sequence it in two stages:
- Land
.ai-governance.yaml,.ai-governance/evaluate.sh, the hook configs, and the workflow file in a normal PR, merged without the check marked as required yet — it will run (and may fail-open on thegit show, which is fine for this one merge) but nothing blocks on it. - Only after that PR is on the base branch, do step 9's branch-protection change, making the check required from that point on. Every PR after this one has a real base-branch copy to fetch.
- Add
.ai-governance/audit.logto.gitignore— it can contain command text and file paths that may carry secrets, and must never be committed:
``bash grep -qxF '.ai-governance/audit.log' .gitignore 2>/dev/null || echo '.ai-governance/audit.log' >> .gitignore ``
- Print the exact branch-protection step (Settings → Branches → the target branch's ruleset → require the
ai-governancecheck) and the exact CODEOWNERS lines to add — and print it as a follow-up step to run after the bootstrap PR above has merged, not alongside this PR:
`` .ai-governance.yaml @your-org/platform-team .ai-governance/ @your-org/platform-team .github/hooks/ @your-org/platform-team .github/workflows/ai-governance-check.yml @your-org/platform-team .claude/settings.json @your-org/platform-team `` State explicitly: this command cannot set branch protection or write CODEOWNERS itself — no repo-admin scope is assumed.
Validation:
One exception to the tier table, worth stating when you hand this over: a diff that touches a governance asset (.ai-governance.yaml, .ai-governance/**, .github/hooks/**, .github/workflows/ai-governance-check.yml, .claude/settings.json) and another protected path denies under every tier, audit included. Otherwise a single PR could switch off the gate and change what it was guarding at the same time. Changing a governance asset on its own is an ordinary protected_paths hit and follows the tier as normal.
Mode: check
Dry-run the evaluator against a path, a command string, or a diff range, without a live agent session.
Steps:
- Accept a path (file edit test), a command string (bash test), or a diff range (
check --diff main...HEAD). - Always pass
--platform=none. That is the evaluator's platform-neutral renderer: it prints{"decision":…,"rule":…,"reason":…}instead of a Copilot or Claude envelope, because a platform engineer tuning policy needs the rule that fired, not a vendor transport format. It also writes nothing to.ai-governance/audit.log, so a dry run never leaves fake entries in the real audit trail:
```bash # File edit test — an edit payload, so this is write intent echo '{"toolName":"edit","toolArgs":{"path":".github/workflows/release.yml","content":"x"}}' \
# → {"decision":"deny","rule":"protected_paths","reason":"protected_paths: .github/workflows/** (.github/workflows/release.yml)"}
# Command string test — denied_commands, not protected_paths echo '{"toolName":"bash","toolArgs":{"command":"terraform apply -auto-approve"}}' \
# → {"decision":"deny","rule":"denied_commands","reason":"denied_commands: terraform apply"}
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/ai-governance/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/nitinjain999/platform-skills/ai-governance)