HushSpec Core Specification#
The full normative specification is at spec/hushspec-core.md. This page summarizes HushSpec 1.0.0.
Document Structure#
A HushSpec document is a YAML file with these top-level fields:
| Field | Type | Required | Description |
|---|---|---|---|
hushspec | string | Yes | Spec version (e.g., "1.0.0"). Engines accept every patch version of a supported minor version. |
name | string | No | Human-readable policy name; nonempty when present |
description | string | No | Policy description |
extends | string | No | Base policy reference. Never present in a resolved document. |
merge_strategy | string | No | replace, merge, or deep_merge (default). Never present in a resolved document. |
rules | object | No | Security rule declarations |
extensions | object | No | Optional extension modules |
metadata | object | No | Governance metadata (author, approver, lifecycle state, version, dates). Has no effect on evaluation. |
YAML Profile#
Documents use YAML 1.2 Core: only true/false are booleans (yes/no/on/off are rejected where a boolean is required), one document per file, duplicate keys rejected, anchors/aliases/merge keys rejected, and engines enforce size, depth, and node-count limits.
Quote the version and strings that resemble booleans, dates, or numbers. The
portable numeric domain is IEEE-754 binary64 with safe integers; author integer
limits no larger than 9007199254740991. See canonical numeric
constraints before hashing arbitrary metadata.
Minimal Valid Document#
hushspec: "1.0.0"
name: minimalThis parses, but an empty policy is not a sandbox. Start with the tested first policy for concrete restrictions and a full example.
Design Principles#
A policy declares permissions. The evaluator computes a decision. The runtime owns the side effect and must enforce that decision before dispatch. Evidence records the policy identity and decision; it cannot prove that an uninstrumented tool was never called. See runtime integration.
Validation Rules#
The normative requirements are core sections 2.4 and 7.
- The
hushspecfield MUST be present and be a string - Unknown fields MUST be rejected at every nesting level (fail-closed)
- Path fields (
forbidden_paths,path_allowlist,skip_paths) use the path-glob class; egress and browser domain fields use the host-pattern class; tool names are exact strings - All patterns in
secret_patterns,patch_integrity,shell_commands, andextra_credential_patternsmust conform to the HushSpec regex profile (RE2 subset, ASCII\d \w \s \band ASCII-only(?i), named groups but no backreferences or lookaround, no POSIX classes, at most 2048 bytes) - Secret pattern
namefields MUST be unique within the array - Every
whencondition is validated at parse time
12 Core Rules#
- forbidden_paths: Block access to sensitive filesystem paths
- path_allowlist: Allowlist-based path access control
- egress: Network egress control by host
- secret_patterns: Detect secrets in content
- patch_integrity: Validate patch/diff safety
- shell_commands: Block dangerous shell commands
- tool_access: Control tool/MCP invocations
- computer_use: Control computer use agent actions
- remote_desktop_channels: Control remote desktop side channels
- input_injection: Control input injection capabilities
- browser_automation: Control browser automation verbs, hosts, and typed credentials
- code_execution: Control sandboxed interpreter language, modules, network, and time
Every rule block accepts enabled and an optional when condition that gates the block on a time window or runtime context.
See the Rules Reference for detailed field documentation.
Resolution, Enforcement, and Panic Mode#
- Resolution (Section 2.6):
extendsacceptsbuiltin:names, filesystem paths, andhttps:URLs, each optionally pinned by digest. A chain is limited to 32 hops, cycles are rejected, and any loader failure refuses the resolution rather than evaluating the leaf alone. - Enforcement (Section 6.2): an enforcement point runs in
enforceormonitormode with per-rule-path overrides. Monitor mode is refused without a receipt sink or observer, and a panic denial or a refused-policy denial is always enforced. - Panic mode (Section 6.3): a latch, set programmatically or by a sentinel file, that denies every action with
__hushspec_panic__. Checking the sentinel fails closed, and absence of the file never disarms the latch.
Decision Types and Precedence#
All applicable rules participate. deny outranks warn, which outranks allow;
the first block in evaluation order with the winning decision that named a
matched_rule supplies it; otherwise it is absent. A tool allowlist never bypasses content scanning.
In enforce mode, warn requires positive confirmation. Without a confirmation
channel, or after refusal, the action is blocked. This is a requirement of
core section 6, not a recommendation.
Extensions#
Posture gates capabilities and budgets; origins narrows policy using trusted source context; detection adds content-analysis contributions. The twelve rules, conditional blocks, and extensions are one evaluation, not independent permissions that can override a denial.
Versioning#
The policy document version is 1.0.0. Receipt and signature envelopes remain
0.2; logs and bundles remain 0.1. See versioning
and migration. Changing a package version does not
rewrite these wire identifiers.