Permissions
Cyberstrike uses a permission system to control which tools the AI agent can execute. This provides security boundaries while maintaining productivity.
Permission Model
flowchart TD ToolCall([Tool Called]) --> CheckConfig{Check\nConfig} CheckConfig -->|allow| Execute[Execute Tool] CheckConfig -->|deny| Block[Block Tool] CheckConfig -->|ask| CheckApproved{Previously\nApproved?} CheckApproved -->|Yes| Execute CheckApproved -->|No| AskUser[Prompt User] AskUser -->|Once| Execute AskUser -->|Always| Remember[Remember + Execute] AskUser -->|Reject| Block Remember --> ExecutePermission Modes
| Mode | Behavior | Use Case |
|---|---|---|
ask | Prompt for approval | Default for sensitive tools |
allow | Auto-approve | Trusted tools, automation |
deny | Block execution | Restricted operations |
Configuring Permissions
Global Configuration
Set permissions in ~/.config/cyberstrike/cyberstrike.json:
{ "permission": { "read": "allow", "glob": "allow", "grep": "allow", "edit": "ask", "bash": "ask", "websearch": "ask" }}Project Configuration
Override permissions per-project in cyberstrike.json:
{ "permission": { "bash": "allow", "edit": "allow", "external_directory": "deny" }}Project settings override global settings.
Permission Types
File Operations
| Permission | Tools | Default | Description |
|---|---|---|---|
read | Read | ask | Read file contents |
edit | Write, Edit | ask | Modify files |
glob | Glob | allow | Find files by pattern |
grep | Grep | allow | Search file contents |
Command Execution
| Permission | Tools | Default | Description |
|---|---|---|---|
bash | Bash | ask | Execute shell commands |
task | Task | ask | Create sub-agents |
Web Operations
| Permission | Tools | Default | Description |
|---|---|---|---|
websearch | WebSearch | ask | Search the web |
webfetch | WebFetch | ask | Fetch web content |
codesearch | CodeSearch | ask | Search code repositories |
Special Permissions
| Permission | Description |
|---|---|
external_directory | Access files outside project |
lsp | Language server operations |
doom_loop | Detect and break infinite loops |
Permission Patterns
Permission patterns give fine-grained control by matching a tool’s argument (a command string, a file path) against a glob and mapping it to an action.
Pattern Format
A permission entry is either a single action, or a map of glob → action. The tool key groups its patterns:
{ "permission": { "bash": { "*": "ask", "ls *": "allow", "git status": "allow", "rm -rf *": "deny" }, "edit": { "reports/**": "allow", ".env*": "deny" } }}The glob matches the tool’s argument: for bash it’s the command string, for edit/read it’s the file path.
Wildcards
Only two wildcards are supported:
| Token | Matches |
|---|---|
* | any sequence of characters (including /) |
? | any single character |
Caution
* and ? are the only wildcards. Characters like [, ], {, }, (, ), and | are matched literally. There is no ** (it behaves the same as *), and negation (!pattern) is not supported.
A pattern that ends in a space + * also matches the bare command with no arguments — so "ls *" matches both ls and ls -la.
Pattern Precedence
When several patterns match, the more specific (longer) pattern wins. Patterns are evaluated shortest-first, and the last match applies — so a broad "*": "ask" can be overridden by a longer "git status": "allow":
{ "permission": { "bash": { "*": "ask", "npm *": "allow", "npm publish*": "deny" } }}Here npm test is allowed, but npm publish is denied.
Pattern Examples
Allow a toolchain, block the dangerous parts
{ "permission": { "bash": { "*": "ask", "git *": "allow", "git push*": "ask", "rm -rf *": "deny" } }}Restrict edits to a directory
{ "permission": { "edit": { "*": "deny", "src/**": "allow", "src/secrets/**": "deny" } }}Agent Permissions
Configure permissions per-agent:
{ "agent": { "web-application": { "permission": { "bash": "allow", "browser": "allow", "edit": "ask" } }, "code-review": { "permission": { "read": "allow", "glob": "allow", "grep": "allow", "edit": "deny", "bash": "deny" } } }}Interactive Approval
When a tool requires permission, Cyberstrike prompts for approval.
Response Options
| Option | Behavior |
|---|---|
| Once | Approve this specific call |
| Always | Approve all similar calls in session |
| Reject | Block this call |
Keyboard Shortcuts
| Key | Action |
|---|---|
y | Approve once |
a | Approve always |
n | Reject |
Esc | Reject |
Session Approval Memory
When you select “Always”, Cyberstrike remembers the approval pattern for the session:
- User approves
git pushwith “Always” - Pattern
git *is stored for session - Future
git pull,git commit, etc. auto-approve - Memory resets when session ends
External Directory Access
By default, Cyberstrike restricts access to the project directory.
Allowing External Access
{ "permission": { "external_directory": "ask" }}Specific External Paths
{ "permission": { "external_directory": { "/home/user/shared/**": "allow", "/tmp/**": "allow", "/etc/**": "deny" } }}Permission Hooks
Use plugin hooks for programmatic permission control:
const hooks: Hooks = { "permission.ask": async (input, output) => { if (input.type === "read" && input.path?.startsWith("src/")) { output.status = "allow" return }
if (input.path?.includes("secret") || input.path?.includes(".env")) { output.status = "deny" return }
output.status = "ask" },}See Hooks & Plugins for the full hook system.
Permission Priority
Permissions are evaluated in order:
- Agent-specific permissions (highest priority)
- Project
cyberstrike.json - Global
~/.config/cyberstrike/cyberstrike.json - Default built-in values (lowest priority)
More specific patterns take precedence over broader ones.
Automation
In non-interactive runs (cyberstrike run), there is nobody to answer permission prompts — so any tool that would prompt is auto-rejected. To let a pipeline do real work, pre-approve the tools it needs.
Pre-Approving Tools
Grant permissions two ways:
1. CYBERSTRIKE_PERMISSION env var — a JSON permission map (same shape as the config permission field):
export CYBERSTRIKE_PERMISSION='{"bash":"allow","read":"allow","edit":{"reports/**":"allow"}}'cyberstrike run "scan this codebase for security issues" --format json > report.json2. Config permission — commit safe defaults, deny the dangerous bits:
{ "permission": { "read": "allow", "bash": { "*": "allow", "rm -rf *": "deny", "sudo *": "deny" }, "edit": { "reports/**": "allow", ".env*": "deny" } }}Output goes to stdout; use --format json for machine-readable results.
GitHub Actions
name: Security Scanon: pull_request: branches: [main]
jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - run: npm install -g @cyberstrike-io/cyberstrike@latest - name: Run Security Scan env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} CYBERSTRIKE_PERMISSION: '{"bash":"allow","read":"allow","edit":{"reports/**":"allow"}}' run: cyberstrike run "scan this codebase for security vulnerabilities" --format json > security-report.json - uses: actions/upload-artifact@v4 with: name: security-report path: security-report.jsonGitLab CI
security-scan: image: node:20 variables: CYBERSTRIKE_PERMISSION: '{"bash":"allow","read":"allow"}' script: - npm install -g @cyberstrike-io/cyberstrike@latest - cyberstrike run "analyze code for vulnerabilities" --format json > report.json artifacts: paths: - report.jsonBatch & Scheduled Runs
#!/bin/bashexport CYBERSTRIKE_PERMISSION='{"bash":"allow"}'while read -r target; do cyberstrike run "scan $target for open ports and services" --format json > "reports/${target}.json"done < targets.txtExit Codes & Output
cyberstrike run writes results to stdout (--format json for JSON) and returns 0 on success, a non-zero code on error or interruption.
Automation Security
- Least privilege — only
allowthe tools the job needs; keep an explicitdenyforrm -rf *,sudo *, and secret paths. - Secrets — inject API keys from your CI secret store, never commit them.
- Isolation — run in a container with a constrained network where possible.
Caution
Always keep deny rules for destructive commands when pre-approving bash in automation.
Security Best Practices
Development Environment
{ "permission": { "read": "allow", "glob": "allow", "grep": "allow", "edit": "ask", "bash": "ask" }}Production/CI Environment
{ "permission": { "read": "allow", "glob": "allow", "grep": "allow", "edit": "allow", "bash": { "npm test": "allow", "npm run build": "allow", "*": "deny" } }}Security Audit Mode
{ "permission": { "read": "allow", "glob": "allow", "grep": "allow", "lsp": "allow", "websearch": "allow", "edit": "deny", "bash": "deny" }}Web Security Testing
{ "permission": { "bash": { "nmap *": "allow", "nikto *": "allow", "sqlmap *": "allow", "nuclei *": "allow" }, "browser": "allow", "websearch": "allow", "edit": "ask" }}Tip
Start with restrictive permissions and relax them as needed. It’s safer to approve individual actions than to grant blanket access.