HushSpec/Docs
HUSHED · MMXXVI
Documentation v1.0
v1.0.0referencestable

Rules Reference#

This page documents all 12 core HushSpec rules. For full normative semantics, see the core specification.

All rules share two common fields: enabled (boolean, default varies by rule) and when (optional condition object, see Conditional blocks). When enabled is false or the when condition is not met, the rule is inert.

Every applicable rule for an action is evaluated; an allow from one rule never skips another. The most restrictive decision wins.

Use the action-to-rule table to see which blocks apply and in what order. A rule's absence does not activate its defaults: defaults apply inside a present block. Validate all fragments below inside a complete document with hushspec: "1.0.0".

matched_rule identifies the winning restriction, such as rules.tool_access.block or rules.browser_automation.allowed_domains. Each field's exact decision path and precedence are specified in core section 3. The first participating rule with the winning decision and a named match supplies the summary; receipt traces retain the remaining checks. Reserved stages such as panic and invalid-policy refusal use the rule-path registry.


1. forbidden_paths#

Block access to sensitive filesystem paths using path globs.

FieldTypeDefaultDescription
enabledbooleantrueWhether this rule is active
patternsarray of string[]Glob patterns matching forbidden paths
exceptionsarray of string[]Glob patterns that override matches

A path is forbidden if it matches a patterns entry and does not match any exceptions entry. Targets are normalized before matching (NFC, \ to /, . and .. collapsed, trailing slash stripped); * and ? never cross /; [ and { are literal.

yaml
rules:
  forbidden_paths:
    patterns:
      - "**/.ssh/**"
      - "**/.env"
    exceptions:
      - "**/.env.example"

2. path_allowlist#

Allowlist-based path access control. When enabled, only matching paths are permitted.

FieldTypeDefaultDescription
enabledbooleanfalseWhether this rule is active
readarray of string[]Glob patterns allowed for reads
writearray of string[]Glob patterns allowed for writes
patcharray of string[]Glob patterns allowed for patches (falls back to write)

A match allows the path for this rule only; secret_patterns and patch_integrity still run on the content.

yaml
rules:
  path_allowlist:
    enabled: true
    read:
      - "/home/user/project/**"
    write:
      - "/home/user/project/src/**"

3. egress#

Network egress control by host.

FieldTypeDefaultDescription
enabledbooleantrueWhether this rule is active
allowarray of string[]Host patterns to allow
blockarray of string[]Host patterns to block
defaultstring"block"Default decision: "allow" or "block"

Block takes precedence over allow. The target is reduced to a host first: scheme, userinfo, port, path, and query are stripped, the host is lowercased, a trailing dot is removed, and non-ASCII labels are converted to punycode. * matches exactly one label; ** matches one or more labels; the apex host is never implied. IP literals match only exact entries.

yaml
rules:
  egress:
    allow:
      - "api.openai.com"
      - "**.googleapis.com"
    default: "block"

4. secret_patterns#

Detect secrets in content before it is written or transmitted.

FieldTypeDefaultDescription
enabledbooleantrueWhether this rule is active
patternsarray of SecretPattern[]Named regex patterns for detection
skip_pathsarray of string[]Glob patterns of paths to skip

SecretPattern fields:

FieldTypeRequiredDescription
namestringYesUnique identifier
patternstringYesRegular expression (HushSpec regex profile)
severitystringYes"critical", "error", or "warn"
descriptionstringNoHuman-readable description

Content is scanned on file_write and patch_apply, and on egress and tool_call when the action carries content. All patterns are tested and the highest matched severity decides: critical and error deny, warn warns.

yaml
rules:
  secret_patterns:
    patterns:
      - name: aws_access_key
        pattern: "AKIA[0-9A-Z]{16}"
        severity: critical
      - name: generic_api_key
        pattern: "(?i)api[_-]?key[ \\t]*[=:][ \\t]*[a-z0-9]{32,}"
        severity: error

5. patch_integrity#

Validate the safety and size of patch/diff content.

FieldTypeDefaultDescription
enabledbooleantrueWhether this rule is active
max_additionsinteger1000Max added lines
max_deletionsinteger500Max deleted lines
forbidden_patternsarray of string[]Regex patterns forbidden in patch content
require_balancebooleanfalseWhether additions/deletions must be balanced
max_imbalance_rationumber10.0Max ratio of additions to deletions (or vice versa)

With require_balance: true, a patch where one count is zero and the other is not is always denied.

yaml
rules:
  patch_integrity:
    max_additions: 500
    max_deletions: 200
    forbidden_patterns:
      - "eval\\("
      - "exec\\("

6. shell_commands#

Block dangerous shell commands before execution.

FieldTypeDefaultDescription
enabledbooleantrueWhether this rule is active
forbidden_patternsarray of string[]Regex patterns forbidden in commands

Patterns match against the complete command string including arguments and pipes.

yaml
rules:
  shell_commands:
    forbidden_patterns:
      - "rm[ \\t]+-rf[ \\t]+/"
      - "curl.*\\|.*sh"
      - "chmod[ \\t]+777"

7. tool_access#

Control tool and MCP invocations.

FieldTypeDefaultDescription
enabledbooleantrueWhether this rule is active
allowarray of string[]Tool name allowlist
blockarray of string[]Tool name blocklist
require_confirmationarray of string[]Tools requiring approval
defaultstring"allow"Default decision: "allow" or "block"
max_args_sizeinteger--Max argument payload size in bytes

Evaluation order: max_args_size (deny) > block (deny) > require_confirmation (warn) > allow (allow). When allow is non-empty, any unlisted tool is denied and default is ignored; default applies only when allow is empty. Tool names are exact, case-sensitive strings; * has no special meaning.

yaml
rules:
  tool_access:
    block:
      - dangerous_tool
    require_confirmation:
      - deploy
      - database_write
    default: allow

8. computer_use#

Control computer use agent (CUA) actions.

FieldTypeDefaultDescription
enabledbooleanfalseWhether this rule is active
modestring"guardrail""observe", "guardrail", or "fail_closed"
allowed_actionsarray of string[]Permitted action identifiers

In observe mode, all actions are logged but allowed. In guardrail and fail_closed mode, unlisted actions are denied; the two modes have identical semantics.

yaml
rules:
  computer_use:
    enabled: true
    mode: guardrail
    allowed_actions:
      - "remote.session.connect"
      - "clipboard.read"

9. remote_desktop_channels#

Control side-channel capabilities in remote desktop sessions.

FieldTypeDefaultDescription
enabledbooleanfalseWhether this rule is active
clipboardbooleanfalseAllow clipboard sharing
file_transferbooleanfalseAllow file transfer
audiobooleantrueAllow audio redirection
drive_mappingbooleanfalseAllow drive/filesystem mapping

Channels are addressed by the computer_use targets remote.clipboard, remote.file_transfer, remote.audio, and remote.drive_mapping.

yaml
rules:
  remote_desktop_channels:
    enabled: true
    clipboard: false
    file_transfer: false
    audio: true
    drive_mapping: false

10. input_injection#

Control input injection capabilities in CUA environments.

FieldTypeDefaultDescription
enabledbooleanfalseWhether this rule is active
allowed_typesarray of string[]Permitted input types (e.g., "keyboard", "mouse", "touch")
require_postcondition_probebooleanfalseWhether postcondition verification is required

When enabled, only listed input types are allowed. Empty allowed_types denies all injection (fail-closed).

yaml
rules:
  input_injection:
    enabled: true
    allowed_types:
      - keyboard
      - mouse
    require_postcondition_probe: true

11. browser_automation#

Control browser automation steps (browser_action actions).

FieldTypeDefaultDescription
enabledbooleanfalseWhether this rule is active
allowed_domainsarray of string[]Host patterns the agent may navigate to
blocked_domainsarray of string[]Host patterns always denied (checked first)
allowed_verbsarray of string[]Permitted verbs; empty means any verb
credential_detectionbooleantrueScan typed input for credential-shaped secrets
extra_credential_patternsarray of string[]Additional credential regexes

The action's target is the verb; navigation verbs carry url and input verbs carry content.

yaml
rules:
  browser_automation:
    enabled: true
    allowed_domains:
      - "*.example.com"
    blocked_domains:
      - "evil.com"
    allowed_verbs:
      - navigate
      - screenshot

12. code_execution#

Control sandboxed interpreter invocations (code_exec actions).

FieldTypeDefaultDescription
enabledbooleanfalseWhether this rule is active
language_allowlistarray of string[]Allowed languages; empty means any
module_denylistarray of string[]Modules whose use in the code body is denied (whole-word match)
network_accessbooleanfalsePermit calls that request network access
max_execution_time_msinteger--Maximum requested execution time
max_scan_bytesinteger--Maximum bytes of code scanned for modules

The action's target is the language and content is the code body.

yaml
rules:
  code_execution:
    enabled: true
    language_allowlist:
      - python
    module_denylist:
      - subprocess
      - socket
    network_access: false
    max_execution_time_ms: 5000

Conditional blocks (when)#

Any rule block may carry a when condition. When it evaluates to false the block is inert. Fields on one condition combine with AND; all_of, any_of, and not compose sub-conditions up to 8 levels deep.

FieldDescription
time_window{start: "HH:MM", end: "HH:MM", timezone: "IANA or +HH:MM", days: [mon, ...]}; half-open, wraps midnight when start > end
contextMap of dot-delimited runtime-context paths to required values (user.role: admin, environment: production)
all_of / any_of / notBoolean composition of conditions
capabilityThe effective posture state must grant this capability (capability: shell); unevaluable without a posture extension, so the block stays active
rate{counter: "shell_commands", threshold: 5, comparison: gte} compared against the engine-supplied counters map in the runtime context; unevaluable when the counter is absent

Invalid times, time zones, day names, unknown keys, or excessive nesting are parse errors. A time zone the engine cannot resolve at evaluation time leaves the block active.

yaml
rules:
  shell_commands:
    when:
      context:
        environment: production
      time_window:
        start: "22:00"
        end: "06:00"
        timezone: "America/New_York"
    forbidden_patterns:
      - "rm[ \\t]+-rf[ \\t]+/"

Loading documentation index…

↑↓ navigate↵ openesc close