Bash ast permission validator
Skill kjuhwa/skills-hub/skills/agent-sdk/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 of regex-matching strings.From its SKILL.md
npx -y skills add kjuhwa/skills-hub --skill bash-ast-permission-validatorAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.6 KB, 708 tokens by cl100k_base, as published. Nobody here has run it
Bash AST permission validator
When to use
- Agent has a
Bashtool 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
- Parse with
bash-parser(npm) -> AST with nodes likeCommand,LogicalExpression(&&/||),Pipeline(|),Subshell,Redirect,CommandExpansion($(...)),ParameterExpansion(${var}). - Walk the AST; classify each node:
Command: look upname.textin the safe-command allowlist. OK if name + flags are allowed.LogicalExpressionor 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.
- Return a
BashValidationResultwith:allowed, primaryreason(typed discriminated union), andsubcommandResults[]so the UI can highlight the offending subcommand. - In "compound partial fail", report both passed + failed lists so the user can trim the command and retry.
Example
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-parsercan 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.tsthat shells out to the PS parser or parses with a separate grammar. $(foo)command substitution must be blocked even iffooalone 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.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.