Skip to content
Agentmart
Submit a tool

bash-ast-permission-validator

Validate agent bash commands by parsing them into an AST (bash-parser) and evaluating each subcommand of a pipeline/&&/|| chain against an allowlist, instead…

Skill by kjuhwa

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/kjuhwa-bash-ast-permission-validator

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Validate agent bash commands by parsing them into an AST (bash-parser) and evaluating each subcommand of a pipeline/&&/|| chain against an allowlist, instead of regex-matching strings.

Use cases: data, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/bash-ast-permission-validator

What's inside

Skill name
bash-ast-permission-validator
Description
Validate agent bash commands by parsing them into an AST (bash-parser) and evaluating each subcommand of a pipeline/&&/|| chain against an allowlist, instead of regex-matching strings.
License
MIT
Instructions
54 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Bash AST permission validator

## When to use
- Agent has a `Bash` tool and you want fine-grained allow/deny in "Explore" / read-only mode.
- Regex matching on the raw string keeps letting dangerous constructs through (command substitution, process substitution, redirects).
- Need to show the user WHY a compound command was blocked, pointing at the specific subcommand.

## How it works
1. Parse with `bash-parser` (npm) -> AST with nodes like `Command`, `LogicalExpression` (&&/||), `Pipeline` (|), `Subshell`, `Redirect`, `CommandExpansion` ($(...)), `ParameterExpansion` (${var}).
2. Walk the AST; classify each node:
   - `Command`: look up `name.text` in the safe-command allowlist. OK if name + flags are allowed.
   - `LogicalExpression` or compound: ALL children must be allowed.
   - `Pipeline`: block entirely in safe mode (writes to network / side effects via the pipe target).
   - `Redirect`: block anything except `<` (input redirect).
   - `CommandExpansion`, `ProcessSubstitution`, `ParameterExpansion` (with unsafe defaults): block.
   - Background `&`: block.
3. Return a `BashValidationResult` with: `allowed`, primary `reason` (typed discriminated union), and `subcommandResults[]` so the UI can highlight the offending subcommand.
4. In "compound partial fail", report both passed + failed lists so the user can trim the command and retry.

## Example
```ts
import bashParser from 'bash-parser';

function validate(cmd: string, allowlist: CompiledBashPattern[]): BashValidationResult {
  const ast = bashParser(cmd);
  const results: SubcommandResult[] = [];
  walk(ast, (node) => {
    if (node.type === 'Command') {
      const ok = allowlist.some(p => p.matches(node.name.text, node.suffix));
      results.push({ command: renderCommand(node), allowed: ok,
        reason: ok ? undefined : 'not in allowlist' });
    } else if (node.type === 'Pipeline') {
      results.push({ command: renderCommand(node), allowed: false,
        reason: 'pipelines blocked in explore mode' });
    } // etc.
  });
  const allowed = results.every(r => r.allowed);
  return allowed ? { allowed } : {
    allowed: false,
    reason: { type: 'compound_partial_fail',
      failedCommands: results.filter(r => !r.allowed).map(r => r.command),
      passedCommands: results.filter(r => r.allowed).map(r => r.command) },
    subcommandResults: results,
  };
}
```

## Gotchas
- `bash-parser` can throw on malformed input - wrap in try/catch and return `{ allowed: false, reason: { type: 'parse_error', error } }`. Don't default-allow on parse failure.
- Don't forget Windows: this validator is bash-only; for PowerShell you need a parallel `powershell-validator.ts` that shells out to the PS parser or parses with a separate grammar.
- `$(foo)` command substitution must be blocked even if `foo` alone would pass - the substituted result is used as part of another command.
- Keep subcommand rendering in sync with the AST nodes so error messages show the actual text the user typed.

From kjuhwa/skills-hub, MIT.

More from kjuhwa/skills-hub

Signals

Stars
0
Forks
0
Open issues
17
Last commit (this folder)
Apr 24, 2026 (6 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from kjuhwa

Cite this page

bash-ast-permission-validator skill. Agent Mart. https://agentmart.dev/skills/kjuhwa-bash-ast-permission-validator (last updated 2026-10-24)