Reference
OpenCode bash policy enforcement
SCE can block bash tool commands before they execute in OpenCode, so repositories can enforce safer command paths and preferred workflows.
OpenCode only
This page documents the current OpenCode integration only. Enforcement is implemented by the generated plugin at config/.opencode/plugins/sce-bash-policy.ts. That plugin intercepts bash tool calls, reads the resolved bash policy config, and throws a blocking error before any subprocess starts when a rule matches.
Overview
When an active rule matches a normalized command segment, the whole OpenCode bash tool command is blocked. The failure message keeps a stable shape so users and tooling can recognize policy failures consistently.
Blocked by SCE bash-tool policy '<id>': <message>Policy config lives under policies.bash in either sce/config.json or repo-local .sce/config.json.
Config shape
The active bash policy config has two optional parts: built-in preset IDs and repo-defined custom rules.
{
"policies": {
"bash": {
"presets": ["use-nix-flake-over-cargo"],
"custom": [
{
"id": "block-rm",
"match": {
"argv_prefix": ["rm"]
},
"message": "This repository does not allow `rm` via the bash tool."
}
]
}
}
}presetsenables built-in policy IDs.customdefines repo-specific rules with exact argv-prefix matches.
Normalization before matching
- leading env assignments like
FOO=barare ignored - wrappers like
env,command,nohup, andsudoare stripped away - executable paths are reduced to the command name, so
/usr/bin/gitmatches asgit - chained commands split on shell operators like
|,&&,||,;, and& - nested commands passed through
nix ... -c,nix ... --command,sh -c, andbash -care checked too
Presets
The built-in preset catalog currently includes the following IDs:
forbid-git-allforbid-git-commituse-pnpm-over-npmuse-bun-over-npmuse-nix-flake-over-cargo
{
"$schema": "https://sce.crocoder.dev/config.json",
"policies": {
"bash": {
"presets": ["use-nix-flake-over-cargo"]
}
}
}That preset blocks direct cargo ... commands and tells the user to use the repository's Nix flake workflow instead.
Preset constraints
use-pnpm-over-npmanduse-bun-over-npmare mutually exclusiveforbid-git-allandforbid-git-commitcan be combined, but SCE flags that as redundant
Custom policies
Custom rules let you block narrower command shapes than the preset catalog.
{
"$schema": "https://sce.crocoder.dev/config.json",
"policies": {
"bash": {
"custom": [
{
"id": "use-nix-flake-check-over-cargo-test",
"match": {
"argv_prefix": ["cargo", "test"]
},
"message": "This repository prefers `nix flake check` over direct `cargo test` commands. Run `nix flake check` instead."
}
]
}
}
}That blocks cargo test specifically, without blocking every cargo command.
Custom rule requirements
- each rule must include
id,match, andmessage matchmust contain exactlyargv_prefixargv_prefixmust be a non-empty array of non-empty strings- custom IDs must be unique and must not collide with preset IDs
- duplicate custom
argv_prefixvalues are invalid
Matching and precedence
Matching is exact token-prefix matching only.
["git"]matchesgit status["git", "commit"]matchesgit commit -m "msg"["cargo", "fmt", "--check"]matches only that exact prefix.
If more than one policy matches, selection is deterministic:
- longest matching argv prefix
- custom policy over preset when prefix lengths tie
- earlier custom entry when multiple custom entries tie
- preset catalog order when multiple presets tie
This lets you keep broad presets while still overriding them with a narrower repo-specific custom rule.
Validation
After changing bash policy config, validate it before relying on the new rules.
sce config validateValidation checks for common problems such as unknown or duplicate preset IDs, duplicate custom IDs, duplicate customargv_prefixvalues, invalid schema shape, and mutually exclusive preset combinations.
Use sce config show when you want to inspect the resolved preset and custom rules with their source.
For broader Shared Context Engineering background, read Why SCE Exists. For setup and onboarding, continue with the Getting Started guide.