AIShell-Gate — Getting Started Guide  ·  v28

Getting Started Guide

A practical guide to building, configuring, and running the two-program system that puts a deterministic policy layer between shell commands and Unix execution — for AI agents and human operators alike.

aishell-gate-policy  ·  aishell-gate-exec  ·  aishell-gate-mcp

Copyright © 2026 AIShell Labs LLC Winston-Salem NC USA. All Rights Reserved. Use of this software requires a valid license. — www.aishellgate.com  ·  www.aishell.org

New to AIShell-Gate? Read the Interface Guide first — it tells you which path applies to your environment and which sections of this guide to read. Three levels, not nine.
!! BETA RELEASE — PLEASE READ BEFORE USE !! This is a beta release. Do not use on production systems. Best tested on a clean, isolated OS instance. We strongly recommend running all commands with --dry-run before live execution. --dry-run performs full policy evaluation and fires all confirmation gates but does not execute anything — it is the safest way to validate your configuration before committing to live runs.

./aishell-gate-exec --policy-preset ops_safe --dry-run

Report issues to [email protected].
!! RISK REDUCTION TOOL — NOT A GUARANTEE !! AIShell-Gate is a risk reduction tool. It raises the cost and visibility of unsafe AI-generated commands; it does not guarantee total protection. Review §14 What the Policy Engine Will Not Do before production deployment.
How to Read This Guide

This guide covers AIShell-Gate's interactive mode end to end. You start at a terminal with the policy engine — no execution, no network, nothing runs — and learn how decisions work by watching them happen. Then you extend the same gate to the executor: same typed-command feel, now commands actually run, under full policy enforcement and audit. That two-step arc is the foundation of everything else the system does.

When you're ready to extend the gate to a remote AI agent over SSH, the Remote Deployment Guide picks up where this one ends. The same policy, the same decisions, now applied to a connection from somewhere else. The final section of this guide points you there.

Using Claude Code or Cursor? You can skip the learning arc. See the Using MCP guide for two-file configuration that gets the AI calling evaluate_plan and execute_plan against the gate in ten minutes.

01 What This Is

This guide assumes familiarity with Unix command-line environments and basic JSON structure.

AIShell-Gate is two C programs that work together to put a deterministic policy gate between shell commands and Unix execution. It serves two distinct user populations from a single unified policy engine.

AI agents submit structured JSON execution plans. Every command in the plan is evaluated against policy before anything runs. The AI never receives direct shell access; it submits requests and receives decisions.

Human operators work interactively at a terminal. The same policy engine, the same confirmation gates, and the same audit chain apply to commands typed by a human as to commands proposed by an AI. For human operators the system functions as three things simultaneously: a safety net that catches dangerous commands before execution, a teaching tool that explains why each flag raises the risk profile it does, and a disciplined workflow that provides compliance-grade audit accountability for shell activity.

The two programs:

aishell-gate-policy is the policy engine. It receives a proposed command, normalizes it, evaluates it against the loaded policy stack, computes a risk score, and emits a structured JSON decision. It has no ability to execute anything. Its interactive mode is purely educational — it assesses commands and explains every flag with its documented reasoning. It never executes.

aishell-gate-exec is the execution gateway. It accepts a JSON plan from an AI agent, or reads commands typed interactively at a terminal, submits each through the policy engine, collects human confirmation where required, and calls execve() with the validated argument array. It contains no policy logic — it cannot approve or deny anything. Every execution decision is made by the policy engine in a separate process across a hard OS boundary.

That separation is the security property the system depends on. A compromised executor cannot grant itself permission to run a command the policy engine has denied.

AI agent path:

AI Agent JSON plan { goal, actions: [ {cmd: ...}, ... ] } aishell-gate-exec (no policy logic) aishell-gate-policy (policy engine, separate process) ALLOW / DENY + confirmation level + flag assessment execve() (validated argv only, no shell)

Human operator path:

Human operator command typed at terminal (or JSON plan file) aishell-gate-exec --interactive (reads from /dev/tty) aishell-gate-policy (same policy engine, same rules) ALLOW / DENY + confirmation gate + flag explanation execve() (validated argv only — or educational assessment only)

Both paths use the same policy file. There is no separate human-mode configuration.

02 The Launcher Script

aishell-gate is the stable user-facing entry point to the entire system — present and future. Today it is a thin pre-flight wrapper around aishell-gate-exec. In v2 it becomes the multi-agent, multi-operator broker: session coordination, multi-agent routing, multi-operator confirmation. Because all invocations already flow through aishell-gate, the v2 transition will require no changes to deployed SSH forced commands, MCP configurations, or user muscle memory.

Use aishell-gate in preference to calling aishell-gate-exec directly. It runs pre-flight checks, injects --policy-binary automatically, and hands off to the executor via exec(). All flags pass through unchanged.

Synopsis:

aishell-gate [exec-flags] [policy-flags] [-- other-policy-flags]
aishell-gate --policy-preset ops_safe --audit-log ./exec.jsonl
echo '<json-plan>' | aishell-gate --policy-preset dev_sandbox

What it does before handing off:

Default binary paths (system install):

/usr/bin/aishell-gate-exec
/usr/bin/aishell-gate-policy

Environment overrides for non-standard installations or testing:

VariableDefaultPurpose
AISHELL_EXEC_BIN/usr/bin/aishell-gate-execPath to aishell-gate-exec
AISHELL_POLICY_BIN/usr/bin/aishell-gate-policyPath to aishell-gate-policy

For local use without a system install, set both variables to point at your local binaries:

AISHELL_EXEC_BIN=./aishell-gate-exec \
AISHELL_POLICY_BIN=./aishell-gate-policy \
./aishell-gate --policy-preset ops_safe

03 Editions

AIShell-Gate is available in two editions: Standard and Enterprise. Both editions share the same policy engine, execution gateway, built-in presets, confirmation gates, interactive mode, audit logging, and jail-root enforcement. Enterprise adds cryptographic audit chain integrity and full policy inspection tooling.

To check which edition you have:

./aishell-gate-policy --version
./aishell-gate-exec   --version

The version output identifies the edition explicitly — for example: aishell-gate-policy standard or aishell-gate-policy enterprise.

FeatureStandardEnterprise
Policy evaluation engine
Execution gateway
Built-in presets (all 7)
Confirmation gates (none / plan / action / typed)
Interactive mode (educational, never executes)
Audit logging (JSON Lines)
Jail-root path enforcement
Session policy gating
Custom policy files (base / project / user layers)
--dump-standard-template — export editable policy template
--dump-policy — dump fully resolved effective policy as JSON
HMAC-SHA256 tamper-evident exec audit chain
--audit-verify — verify exec audit log chain integrity
--audit-key — keyed HMAC exec audit chain
Cryptographic session ID in audit and confirmation
Standard edition behaviour: If you invoke an enterprise-only flag on a standard binary, the binary emits a clear not available in standard edition message and exits cleanly — it does not silently ignore the flag or produce a generic unknown-option error.
Audit logging note Both editions write a JSON Lines audit log when --audit-log is supplied. The standard edition log records every decision and is append-only. The enterprise edition log additionally carries an HMAC-SHA256 chain — each entry is cryptographically linked to the previous one, sequence-numbered, and tied to a cryptographic session ID. Only the enterprise binary can verify its own chain with --audit-verify. Do not feed a standard-edition log to enterprise --audit-verify or vice versa.

Contact [email protected] or visit www.aishellgate.com to upgrade from standard to enterprise.

04 First Run: Policy Engine Interactive

AIShell-Gate has two interactive modes. This section covers the first — the policy engine's educational mode, which assesses commands and explains its reasoning but never executes. The second — the executor's interactive mode, where the same decisions are enforced against commands that actually run — is introduced later in this guide and walked through end-to-end in the Beta Tester Guide (Path A).

Run the policy engine at a terminal with no arguments:

./aishell-gate-policy
aishell-gate-policy  [educational mode]
Preset: ops_safe       Default-deny: yes  Net-default-deny: yes
Source: human          User: alice  CWD: /home/alice

This tool assesses commands and explains every flag.
It does NOT execute. To execute, pipe through aishell-gate-exec.
────────────────────────────────────────────────

policy> git status

  ALLOW  git status
  Confirmation required: none  (no prompt needed)
  Flag analysis: all flags are known-safe.

  To execute through the gateway:
    echo 'git status' | aishell-gate-exec --source human

policy> rm -rf /var/log

  DENY   rm -rf /var/log
  Reason: -rf flag denied by arg_rules
  Fix:    Remove or replace the denied argument.

policy> ls -la

  ALLOW  ls -la
  Confirmation required: none  (no prompt needed)
  Flag analysis: all flags are known-safe.

  To execute through the gateway:
    echo 'ls -la' | aishell-gate-exec --source human

policy> quit

The default preset is ops_safe, which allows a conservative set of read-only and repository inspection commands. You will see this behavior without any configuration files in place.

Type json after any command to see the full JSON decision record for the previous evaluation. Type quit or exit to leave.

A note on how this is supposed to feel The interactive policy engine takes no flags, needs no config files, and creates no files. Run the binary, type any command, learn by watching. This is deliberate. Software that asks you to understand it before it lets you use it wastes the user's time — we have spent enough hours of our own lives on that kind of software to want the opposite here.

Why a Human Would Use This

The policy engine's flag catalog carries a documented reason for every flag that raises risk — not a generic label, a specific plain-English explanation:

An unknown flag is explicitly labelled "risk unassessed, not evaluated as safe" — the system never implies it checked something and found it safe when it did not. For a junior operator, this is instruction delivered in context at the moment of the command. For an experienced operator, it is a disciplined workflow with confirmation gates and full audit trail on every command run.

05 Choosing a Preset

A preset selects a named command allow/deny configuration for the builtin policy layer. You select one with --policy-preset. Presets replace the builtin layer's cmd_allow and cmd_deny lists while leaving arg_rules, path_rules, and net_rules unchanged. Seven presets are built in:

If you are just starting: use ops_safe for read-only exploration or dev_sandbox for hands-on code work. The CI presets require specific runtime conditions (--jail-root, batch mode) and are not meant for interactive evaluation.
PresetDescription
read_onlyAllows inspection commands only: ls, cat, grep, find, ps, df, git status, git log, and similar. Denies everything that writes, deletes, or escalates privilege. Use this when you want to let an AI agent observe a system without being able to change anything.
dev_sandboxAllows developer workflow commands: git, make, compilers, package managers (pip, cargo, go, npm). Blocks disk destructors and privilege escalation. A reasonable starting point for AI-assisted coding workflows.
ops_safeThe default. A small conservative set of read and repository commands. Denies shells, interpreters, most write operations, and all privilege commands.
ci_buildUnattended build and test pipeline. All allowed commands carry CONFIRM_NONE — confirmation prompts would hang a headless CI runner. Safety comes from the allow list boundary and --jail-root. Requires --jail-root to constrain file operations.
ci_deployUnattended deployment pipeline. Superset of ci_build adding remote transfer, container operations, Kubernetes, Helm, Terraform, and service restart. Destructive operations (kubectl delete, helm uninstall, terraform destroy) remain in deny.
ci_adminCI/CD infrastructure management with mixed confirmation levels. Reads and inspections at CONFIRM_NONE; writes and destructive operations at CONFIRM_ACTION; terraform destroy and interactive shells at CONFIRM_TYPED. Intended for supervised admin sessions.
danger_zoneMinimal restrictions. A wildcard allow rule permits most commands, but the built-in deny list (shells, interpreters, disk destructors, privilege escalation) still applies. Use cautiously and only when you have a good reason. All commands require typed confirmation.

Whatever preset you choose, confirmation levels and risk scoring always apply on top of it. A high-risk command does not bypass confirmation just because the preset allows it.

06 Risk and Confirmation

When the policy engine allows a command, it also assigns a confirmation level that tells the executor how much human review is required before the command actually runs. There are four levels:

LevelMeaning
noneProceed immediately — no human review needed.
planShow the plan to a human before executing; review is suggested.
actionRequire explicit per-command human approval.
typedThe human must type a confirmation code derived from the exact command text.

Your policy rules can set a confirmation level for any allowed command. But the engine also scores every command for risk on a scale of 0 to 100, and will automatically raise the confirmation level if the score is high enough:

Risk-based escalation is strictly one-way. The risk score can only raise a confirmation level, never lower it. Within a single policy layer, the flag catalog similarly only raises. Cross-layer behaviour is different: policy layers are scanned highest-authority first, and the first layer that produces any match wins outright — lower-authority layers are not consulted for their allow rules, their deny rules, or their confirmation levels. A user-layer allow rule with confirm: none therefore takes effect even if a base-layer rule would have required typed, because the base layer is not read. See §09 for the layering model and how to position rules that must not be overridden.

Some representative scores: ls and cat score 0–5 and require no confirmation. git scores 20 and requires a plan-level review. curl and wget score 60 and require action confirmation. rm scores 80 and requires typed confirmation. dd, parted, mkfs, and wipefs score 95–98, also requiring typed confirmation. Arguments make the score worse: targeting a system path adds 15 points, a recursive flag on a destructive command adds 10, --force with rm or mv adds 10.

07 Running a Plan Through the Executor

For real use, you do not call the policy engine directly. You pass a JSON plan to aishell-gate-exec, and it handles the rest. The plan format is simple: a goal description, an optional source label, an optional strategy, and an array of commands.

echo '{
  "protocol": {"name": "aishell-gate-exec-input", "version": "1.0"},
  "goal":     "check repository state",
  "source":   "ai",
  "strategy": "fail_fast",
  "actions": [
    {"cmd": "git pull"},
    {"cmd": "git status"},
    {"cmd": "npm test"}
  ]
}' | ./aishell-gate --policy-preset dev_sandbox

The executor submits each command to the policy engine in sequence, reads the JSON verdict back, collects human confirmation if the confirmation level requires it, and calls execve() with the validated argument array from the verdict. The raw command string never touches a shell.

The strategy field controls what happens when a command is denied or fails. fail_fast stops at the first problem. best_effort continues through failures and reports what happened.

Keep it simple: When aishell-gate, aishell-gate-exec, and aishell-gate-policy all live in the same directory and you run from that directory, no --policy-binary flag is ever needed. The executor locates the policy engine at ./aishell-gate-policy by default, and the launcher handles co-location automatically. You only pass --policy-binary explicitly when binaries are installed elsewhere and you are calling aishell-gate-exec directly rather than via the launcher.

Connecting an AI Model

Because the executor reads a JSON plan from standard input, connecting a real AI model is a pipe — the model generates the plan, the gate evaluates and executes it. For a worked example using a local inference backend, see the AI Pipeline Script section of the Remote Deployment Guide.

In practice you want the model to generate commands appropriate for a goal you describe, not repeat back a fixed structure. A system prompt that instructs the model to return only JSON — no explanation, no markdown — is the integration point. The minimal working system prompt:

You are a Unix operations assistant. When given a goal, respond with ONLY
a valid JSON object — no explanation, no markdown, no code fences.

Format:
{
  "goal": "the goal as stated",
  "source": "ai",
  "strategy": "fail_fast",
  "actions": [
    {"type": "command", "cmd": "command here"}
  ]
}

Rules: use only simple Unix commands. No shell pipelines, semicolons, or
redirects. One command per action. No text outside the JSON object.

The script bin/aishell-pipe.sh in the distribution wraps this with pre-flight checks and exit code reporting. Adapt the model invocation to your inference backend — any command that writes a valid JSON plan to stdout works in its place.

Why this works without a framework. The executor does not know or care whether the JSON plan came from a hand-written file, a shell variable, an AI model, a CI system, or a test harness. It reads stdin. Anything that can write a valid JSON plan to stdout can drive AIShell-Gate. The gate is the boundary; what is on the other side of it is your choice.

08 Evaluating a Single Command

You can pipe a single command to the policy engine directly, without using the executor or writing a JSON plan. This is useful for scripting, testing, or integrating the policy check into other tools.

echo "git status" | ./aishell-gate-policy --policy-preset dev_sandbox

Add --json to get the full machine-readable output:

echo "git status" | ./aishell-gate-policy --policy-preset dev_sandbox --json

The JSON output includes the overall decision, the confirmation level, the matched rule, the policy layer that matched it, the validated argument array, the risk score and flags, the blast radius classification, and a short plain-text summary suitable for display to a human.

If you are integrating this into a script, the exit code from the policy engine is always 0 when it runs without internal error — regardless of whether the decision was ALLOW or DENY. The decision itself lives in the JSON output. Exit code 1 means an internal error; exit code 2 means a usage problem. This allows the policy engine to be used in pipelines without being mistaken for a command failure. The calling script reads the JSON to determine what happened.

A scripting hook worth noticing This mode — single command in, JSON decision out, exit code reserved for internal errors — is the integration point for CI pipelines, test harnesses, pre-commit hooks, and policy regression suites. Any wrapper that needs a policy decision without actually running anything can shell out to aishell-gate-policy with --json and parse the result. If the thought had not occurred yet: this is how you bolt the gate's reasoning into systems that do their own execution.

09 Writing Your First Policy File

Presets are a starting point. For real use you will want to layer your own rules on top. Three optional JSON files are evaluated on top of the selected preset:

By default the engine looks for all three files in the current directory. You can point to different paths with --policy-base, --policy-project, and --policy-user. If a file is absent it is silently ignored. If it exists but cannot be parsed, the engine fails closed and reports the problem.

Layer precedence. Authority runs user > project > base > preset. Layers are scanned highest-authority first, and the first layer that produces any matching rule — allow or deny — wins outright. Lower-authority layers are not consulted once a higher-authority layer has matched. Within the winning layer, deny rules are evaluated before allow rules. This means a higher-authority layer can override a lower-authority layer in both directions: it can allow what a lower layer would have denied, and it can deny what a lower layer would have allowed. The "base" layer is a starting baseline, not an unoverridable floor. If you need a rule that cannot be relaxed by a higher layer, the layer that carries it must sit at or above every layer operators are permitted to modify — which for single-operator deployments typically means placing non-negotiable rules in the user layer, or locking down file-system access to the higher-authority layer files in multi-tenant deployments.

Here is a minimal project policy that allows a few specific git commands without confirmation, requires action confirmation for npm publish, and blocks curl entirely:

{
  "cmd_allow": [
    { "pattern": "git status",  "confirm": "none",   "reason": "safe read" },
    { "pattern": "git diff",    "confirm": "none",   "reason": "safe read" },
    { "pattern": "npm test",    "confirm": "plan",   "reason": "run tests" },
    { "pattern": "npm publish", "confirm": "action", "reason": "publish step" }
  ],
  "cmd_deny": [
    { "pattern": "curl", "reason": "no outbound network in this env" }
  ],
  "writable_dirs": [ "/home/user/myproject" ]
}

Save this as aishell-gate-policy_project.json in your working directory. It will be picked up automatically on the next run.

A few things worth knowing. Rule lists append to the preset by default. If you want your project policy to replace the preset's cmd_allow list entirely rather than extend it, add "cmd_allow_replace": true alongside your cmd_allow array. Unknown keys in a policy file are an immediate hard error, not a silent no-op — a typo like "cmd_denny" will fail the load and tell you what went wrong. A failed load has zero effect on the running policy; the engine restores the previous state atomically.

Run --help-policy at any time to print the complete policy format reference:

./aishell-gate-policy --help-policy

10 Argument and Path Rules

Beyond allowing or denying commands by name, you can write rules that match on specific arguments or on the paths a command targets. These let you allow a command in general while blocking specific dangerous invocations of it.

An argument rule matches a glob pattern against each argument of a given command. This example denies rm with the -rf flag regardless of what the preset would otherwise say:

{
  "arg_rules": [
    { "cmd_pattern": "rm", "arg_glob": "-rf", "decision": "deny",
      "reason": "rm -rf blocked by project policy" }
  ]
}

A path rule matches against the canonicalized path of any argument. Path rules apply only to commands that the engine classifies as write-capable — read-only commands like ls or cat are not subject to path rule evaluation. This example denies any write command that targets the /etc tree:

{
  "path_rules": [
    { "path_glob": "/etc/*", "decision": "deny",
      "reason": "writes to /etc are not permitted" }
  ]
}

Network rules work the same way but match against the hostname extracted from URL arguments. The built-in default base policy already denies 169.254.* and metadata.google.internal to block cloud metadata endpoint access. AIShell-Gate enforces a network default-deny model in ops_safe, read_only, and dev_sandbox presets: any command with a detected network target must have an explicit net_rules allow entry, or it is denied. Add a "net_default_deny": false key to your policy file to opt out for CI pipelines that need unrestricted registry access.

11 Enabling Audit Logging

Every evaluation can be written to a tamper-evident JSON Lines audit log. Add --audit-log with a path to the policy engine to enable it:

./aishell-gate-policy --policy-preset ops_safe --audit-log ./policy.jsonl

Each log entry carries a sequence number, session identifier, the full decision context, and a SHA-256 hash that links it to the previous entry. A gap in sequence numbers or a hash mismatch identifies deleted or altered entries. Verify the chain at any time without interrupting operation:

./aishell-gate-policy --audit-verify ./policy.jsonl

For environments that need authenticated audit trails, generate a key and enable HMAC-SHA256 mode:

head -c 64 /dev/urandom > audit.key && chmod 640 audit.key
./aishell-gate-policy --audit-key audit.key \
  --audit-log ./policy.jsonl \
  --policy-preset ops_safe

With a key, only a holder of that key can forge valid chain hashes. The policy key file contains 64 raw binary bytes. The audit log file is append-only; the engine does not rotate it. Protect it with appropriate filesystem permissions.

Two separate audit logs. The policy engine and the executor each write their own independent audit log in a different internal format. The key points are tabulated below. Never point both programs at the same log file, and verify each log only with the binary that wrote it.
 Policy logExec log
Chain field in JSONentry_hashchain_hmac
Chain algorithmSHA-256 sentinel-substitutionHMAC-SHA256
Verifieraishell-gate-policy --audit-verifyaishell-gate-exec --audit-verify
Default log pathnone (off unless --audit-log passed)/var/log/aishell/audit.log
Env var for log pathnoneAISHELL_EXEC_AUDIT_LOG
HMAC key file format64 raw binary bytes64 ASCII hex characters (32 bytes)
Generate keyhead -c 64 /dev/urandomdd if=/dev/urandom bs=32 count=1 | xxd -p | tr -d '\n'

The two HMAC key file formats are not interchangeable. A policy key fed to the executor (or vice versa) will fail key validation at load time.

The executor has its own separate audit log for the execution side. Add --audit-log to the launcher invocation to enable it:

./aishell-gate \
  --policy-preset ops_safe \
  --audit-log ./exec.jsonl

12 Confining Commands to a Directory

The --jail-root flag tells the policy engine to enforce path containment during evaluation. Any write-like command whose path arguments fall outside the jail root will be denied, regardless of what the policy rules say:

./aishell-gate-policy --jail-root /home/user/myproject --policy-preset dev_sandbox

This is the only sandbox enforcement that happens inside the policy engine itself. The other sandbox modes (chroot, container, userns) are advisory hints that are passed through to the executor in the JSON output, where the surrounding infrastructure can act on them.

The jail root check is strict about directory boundaries. A jail root of /tmp/jail will not accidentally allow /tmp/jailbreak/x — the path must be actually inside the named directory, not merely share its prefix.

13 A Complete Example

Here is what a full setup looks like for a developer workflow: a project policy file, an audit log, a jail root, and a plan passed through the executor.

First, create the project policy file:

# aishell-gate-policy_project.json
{
  "cmd_allow": [
    { "pattern": "git status", "confirm": "none" },
    { "pattern": "git diff",   "confirm": "none" },
    { "pattern": "git pull",   "confirm": "plan" },
    { "pattern": "make",       "confirm": "plan" },
    { "pattern": "npm test",   "confirm": "plan" }
  ],
  "cmd_deny": [
    { "pattern": "curl", "reason": "no outbound network" },
    { "pattern": "wget", "reason": "no outbound network" }
  ],
  "writable_dirs": [ "/home/user/myproject" ]
}

Then run a plan through the launcher with audit logging:

echo '{
  "goal":     "pull latest and run tests",
  "source":   "human",
  "strategy": "fail_fast",
  "actions": [
    {"cmd": "git pull"},
    {"cmd": "make clean"},
    {"cmd": "npm test"}
  ]
}' | ./aishell-gate \
  --policy-preset dev_sandbox \
  --audit-log ./exec.jsonl

The executor will submit each command to the policy engine. git pull scores in the plan-level range — the executor pauses and shows the plan for human review. After confirmation, it executes via execve(). If any action is denied, fail_fast stops the sequence immediately. A tamper-evident audit entry is written for each decision.

What the Confirmation Prompt Looks Like

When the executor reaches a command that requires human approval, it pauses and prints a prompt to your terminal. The exact text depends on the confirmation level.

At the plan level — an entire plan that contains one or more plan-level actions is displayed as a numbered list, followed by a single yes-or-no gate:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  PLAN REVIEW  (3 actions)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [1] ALLOW  git pull
  [2] ALLOW  make clean
  [3] ALLOW  npm test

  Proceed with this plan? [y/N] 

Type y (or yes) and press Enter to proceed. Anything else — empty input, n, Ctrl-C — is treated as a refusal and no commands run.

At the action level — each such action fires its own approval prompt after the plan evaluation summary:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  CONFIRMATION REQUIRED  (action 2)
  Level:   action
  Command: curl https://example.com/install.sh
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ⚠  Explicit operator approval required.
  Review the evaluation summary above carefully.

  Approve? [yes/NO] 

Only the literal string yes is accepted as approval at this level. Anything else is refusal.

At the typed level — the highest tier, used for truly destructive operations — the prompt displays a challenge code derived from the exact command text. The operator must type that code back:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  CONFIRMATION REQUIRED  (action 1)
  Level:   typed
  Command: rm -rf /home/user/myproject/build
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ⚠  HIGH-RISK — Command-specific typed confirmation required.
  Carefully read the command above, then type the code below.
  This code is derived from the exact command text.

  Challenge code:  A7K2-9QWM

  Type code: 

A mismatch between what the operator types and the challenge code is treated as refusal. The code is a friction-on-purpose mechanism: it cannot be muscle-memory approved, and it forces visual confirmation that the command about to run is the command intended.

14 What the Policy Engine Will Not Do

A few things are worth being explicit about, especially if you are coming from a security background.

No quoted arguments. Quotes are shell syntax, and the engine deliberately rejects all shell metacharacters before tokenization. This is intentional: supporting shell quoting would require implementing a shell grammar subset, introducing the same parsing ambiguity and injection surface the system is designed to eliminate. A command like grep 'hello world' file.txt cannot be expressed; the single quotes are rejected outright. Arguments with spaces are not supported.

Network rules match hostnames, not resolved IPs. A rule blocking example.com will not catch a URL that resolves to the same IP through a different hostname. Network rules capture intent, not strong enforcement — use firewall rules for that.

The engine is not a sandbox. It decides whether a command should run before it runs. It does not intercept what the command does while running. It complements OS-level access controls, kernel sandboxing, and proper permission management; it does not replace them.

The engine does not guarantee security against a determined attacker with local system access. It raises the cost and visibility of unsafe AI-generated actions and ensures that every attempt is recorded. That is what it is designed to do.

15 Session Policy

Before the engine evaluates any command at all, it checks whether the current session is permitted to make requests. Session policy can gate evaluation on the caller's uid or gid, their username, whether they are in an SSH session, whether stdin is a TTY, the session mode (interactive, batch, or daemon), and the time of day.

Session constraints go in the "session" key of any policy file. Here is an example that restricts operation to two specific users and denies access from SSH sessions:

{
  "session": {
    "allow_users": ["alice", "bob"],
    "deny_ssh": true
  }
}

Session evaluation happens before any command rule is checked. If the session does not satisfy policy, the engine returns a denial without evaluating the command at all. This makes session policy a hard outer gate on the entire system.

16 Where to Go Next

You now know how to use AIShell-Gate interactively at a terminal: the policy engine explains its decisions; the executor enforces them. The same gate, the same policy file, and the same audit chain extend to two further deployment shapes:

The arc continues Interactive mode is the foundation. Remote deployment is the same foundation applied to a distant actor. MCP is a fast track that delivers the same foundation to an AI coding environment without the intervening setup. Same gate, same decisions, same audit — three surfaces onto one policy boundary.

17 Quick Reference

Policy engine interactive (no execution)

./aishell-gate-policy

Run a plan through the launcher

./aishell-gate --policy-preset ops_safe --audit-log ./exec.jsonl
echo '<json-plan>' | ./aishell-gate --policy-preset dev_sandbox

Evaluate a single command (no executor, no plan)

echo "git status" | ./aishell-gate-policy --policy-preset dev_sandbox --json

Run a plan from a file

cat plan.json | ./aishell-gate \
  --policy-preset dev_sandbox \
  --audit-log ./exec.jsonl

Inspect a plan without executing (dry-run JSON)

cat plan.json | ./aishell-gate \
  --policy-preset ops_safe \
  --dry-run-json

Run a policy test suite

./aishell-gate-policy --policy-preset ops_safe --test-plan tests/policy_tests.json

Verify an audit log

./aishell-gate-policy --audit-verify ./policy.jsonl

Read the policy format reference

./aishell-gate-policy --help-policy

For complete option documentation, policy file syntax, session policy fields, exit codes, and known limitations, see the man page: aishell-gate-policy(1). For connecting a local inference model as a source of JSON plans, see the AI Pipeline Script section of the Remote Deployment Guide. For the security architecture and design rationale, see the AIShell-Gate white paper.