Configuration Schema
This page documents every field available in runok.yml. Each option is described using a consistent format: name, description, type, default value, and example.
File Format
Section titled “File Format”runok configuration is written in YAML. The configuration file is named runok.yml (or runok.yaml) and placed at the project root or in the global config directory. See File Discovery and Merging for details on where runok looks for configuration files.
A minimal configuration file looks like this:
rules: - allow: 'git *' - ask: 'npm *'The top-level keys are required_runok_version, extends, defaults, rules, definitions, audit, and tests. All are optional.
JSON Schema
Section titled “JSON Schema”runok provides a JSON Schema for configuration file validation and editor autocompletion. The schema file is available at schema/runok.schema.json in the repository.
To enable autocompletion in your editor, add a # yaml-language-server directive at the top of your configuration file:
# yaml-language-server: $schema=https://raw.githubusercontent.com/fohte/runok/main/schema/runok.schema.jsonrules: - allow: 'git *'Top-Level Fields
Section titled “Top-Level Fields”required_runok_version
Section titled “required_runok_version”Minimum runok version required to load this file. The value is a semver requirement expression such as ">=0.3.0", "^0.3", or ">=0.3, <0.5". If the current runok binary does not satisfy the requirement, loading fails with a clear error that names the file and the constraint.
This field is checked on every file that runok loads — the project runok.yml, any file pulled in via extends, and every transitively extended preset — so preset authors can guard files that depend on newer runok features.
Type: str
Default: None
Required: No
required_runok_version: '>=0.3.0'rules: - allow: 'echo *'# Preset authors pin the minimum runok version that their file needs.# Older runok binaries will refuse to load this preset instead of silently# ignoring newer fields.required_runok_version: '>=0.3.0'definitions: flag_groups: field-flag: ['-f', '--field']extends
Section titled “extends”List of configuration files to inherit from. Supports local paths and remote Git repositories.
Type: list[str]
Default: []
Required: No
extends: - ./base.yml - github:example-org/example-presets@v1.0.0 - github:example-org/runok-presets/readonly-unix@v1See Extends (Presets) for full details on local paths, GitHub shorthand, and Git URLs. For the official preset collection, see Official Presets (runok-presets).
defaults
Section titled “defaults”Default settings applied when no rule matches a command.
Type: object
Default: { action: "ask" }
Required: No
defaults: action: allow sandbox: strictdefaults.action
Section titled “defaults.action”Action to take when no rule matches.
Type: "allow" | "ask" | "deny"
Default: "ask"
| Value | Behavior |
|---|---|
allow | Permit the command without prompting. |
ask | Prompt the user for confirmation. |
deny | Reject the command. |
defaults.sandbox
Section titled “defaults.sandbox”Name of a sandbox preset (defined in definitions.sandbox) to apply by default. See Sandbox for how sandboxing works.
Type: str
Default: None
defaults: sandbox: standardOrdered list of permission rules evaluated top-to-bottom against each command. The first matching rule wins. See Rule Evaluation for how rules are matched and prioritized.
Type: list[RuleEntry]
Default: []
Required: No
rules: - allow: 'git *' - deny: 'rm -rf /' message: Dangerous operation - ask: 'docker *' sandbox: container-safeRule Entry
Section titled “Rule Entry”Each rule entry must have exactly one of deny, allow, or ask set.
deny / allow / ask
Section titled “deny / allow / ask”Command pattern that triggers this rule. Only one of the three may be specified per rule. See Pattern Syntax for the pattern matching language.
Type: str
Required: Exactly one
# deny rule- deny: 'rm -rf /'
# allow rule- allow: 'git status'
# ask rule- ask: 'docker run *'CEL (Common Expression Language) expression that must evaluate to true for this rule to apply. If omitted, the rule always applies when the pattern matches. See Rule Evaluation for details on condition evaluation.
Type: str
Default: None
- allow: 'npm publish' when: "env.CI == 'true'"message
Section titled “message”Message shown to the user when the rule matches. Primarily useful for deny rules to explain why a command is blocked. See Denial Feedback for usage examples.
Type: str
Default: None
- deny: 'rm -rf /' message: This operation is too dangerous to allow.fix_suggestion
Section titled “fix_suggestion”Suggested alternative command shown when a deny rule matches. Helps users find a safer alternative. See Denial Feedback for usage examples.
Type: str
Default: None
- deny: 'rm -rf *' message: Use trash instead of rm for safety. fix_suggestion: 'trash *'sandbox
Section titled “sandbox”Name of a sandbox preset (defined in definitions.sandbox) to apply when this rule matches. Not allowed on deny rules. See Sandbox for how sandboxing works.
Type: str
Default: None
- allow: 'node *' sandbox: strictInline test cases for this rule. Each entry specifies the expected decision and the command to evaluate. Used by runok test to verify the rule behaves as expected.
Type: list[TestEntry]
Default: []
- allow: 'git status' tests: - allow: 'git status' - ask: 'git status --short'definitions
Section titled “definitions”Reusable definitions for paths, variables, sandbox presets, and wrappers.
Type: object
Default: {}
Required: No
definitions.paths
Section titled “definitions.paths”Named path lists that can be referenced by <path:name> in sandbox fs.deny rules.
Type: map[str, list[str]]
Default: {}
definitions: paths: secrets: - ~/.ssh - ~/.gnupg - ~/.aws/credentialsThe name is referenced via <path:name> syntax:
definitions: sandbox: secure: fs: deny: - <path:secrets>definitions.sandbox
Section titled “definitions.sandbox”Named sandbox presets that define filesystem and network restrictions. See Sandbox for details on how sandbox policies are enforced.
Type: map[str, SandboxPreset]
Default: {}
definitions: sandbox: strict: fs: writable: - ./src - ./tests deny: - <path:secrets> network: allow: falseSandbox Preset Fields
Section titled “Sandbox Preset Fields”Filesystem access policy with read and write sub-sections.
Type: object
Default: None
fs.read.deny
Section titled “fs.read.deny”Paths the sandboxed process cannot read. These paths become completely inaccessible (both read and write are blocked). Supports glob patterns and <path:name> references.
Type: list[str]
Default: []
fs.write.allow
Section titled “fs.write.allow”Directories the sandboxed process is allowed to write to.
Type: list[str]
Default: []
fs.write.deny
Section titled “fs.write.deny”Paths the sandboxed process cannot write to, even within writable directories. Supports glob patterns (*, **, ?, [...], {a,b}) and <path:name> references.
Type: list[str]
Default: []
network
Section titled “network”Network access policy.
Type: object
Default: None
network.allow
Section titled “network.allow”Whether network access is allowed.
Type: bool
Default: true
Sandbox Merge Strategy (Strictest Wins)
Section titled “Sandbox Merge Strategy (Strictest Wins)”When multiple sandbox presets apply to a command, they are merged using a Strictest Wins strategy. See Sandbox Overview for the merge rules and examples.
definitions.wrappers
Section titled “definitions.wrappers”Wrapper command patterns for recursive rule evaluation. When a command matches a wrapper pattern, the inner <cmd> is extracted and evaluated against the rules independently. See Rule Evaluation for details on wrapper processing.
Type: list[str]
Default: []
definitions: wrappers: - 'sudo <cmd>' - 'env * <cmd>'definitions.vars
Section titled “definitions.vars”Typed variable definitions referenced by <var:name> in rule patterns. Each variable has a type (controlling how values are matched) and a list of values.
Type: map[str, VarDefinition]
Default: {}
definitions: vars: instance-ids: values: - i-abc123 - i-def456 test-script: type: path values: - ./tests/run runok: values: - runok - 'cargo run --' - type: path value: target/debug/runokVariable Definition Fields
Section titled “Variable Definition Fields”Controls how the variable’s values are matched against command arguments. This is the definition-level default; individual values can override it with per-value type.
Type: "literal" | "path"
Default: "literal"
| Type | Matching behavior |
|---|---|
literal | Exact string match |
path | Canonicalize both sides before comparison, fallback to path normalization |
values
Section titled “values”List of allowed values for this variable. Each element can be either a plain string (inherits the definition-level type) or an object with explicit type and value fields.
Type: list[str | { type: "literal" | "path", value: str }]
Required: Yes
values: - runok # plain string, inherits definition-level type - 'cargo run --' # multi-word value - type: path # per-value type override value: target/debug/runokdefinitions.flag_groups
Section titled “definitions.flag_groups”Named flag alias groups referenced by <flag:name> in rule patterns. Each group lists every flag spelling that shares semantic meaning (e.g. -f, -F, --field, --raw-field for gh api’s field flag). When a <flag:name> placeholder matches a command, every occurrence of any aliased flag is captured into the flag_groups[name] list available in when clauses.
Type: map[str, list[str]]
Default: {}
definitions: flag_groups: field-flag: ['-f', '-F', '--field', '--raw-field'] header-flag: ['-H', '--header']Validation rules
Section titled “Validation rules”- Each entry must contain at least one flag.
- Every flag name must start with
-(long flags use--). The bare--separator is rejected because it is positional. - Rules referencing
<flag:name>must reference a group defined here; undefined references are rejected at config load time.
See <flag:name> and When Clauses — flag_groups for details on how the captured values are exposed to when expressions.
Audit log settings. Controls whether command evaluations are recorded and where log files are stored. Audit settings can only be configured in the global runok.yml — audit sections in project or local override configs are silently ignored.
Type: object
Default: { enabled: true }
Required: No
audit: enabled: true path: ~/.local/share/runok/ rotation: retention_days: 30audit.enabled
Section titled “audit.enabled”Whether audit logging is enabled.
Type: bool
Default: true
audit.path
Section titled “audit.path”Directory path for audit log files.
Type: str
Default: ~/.local/share/runok/ (or $XDG_DATA_HOME/runok/)
audit.rotation
Section titled “audit.rotation”Log rotation settings.
Type: object
Default: {}
audit.rotation.retention_days
Section titled “audit.rotation.retention_days”Number of days to retain log files. Files older than this are automatically deleted during log writes.
Type: int
Default: 7
Top-level test section for cross-rule test cases and test-only configuration. Used by runok test.
Type: object
Default: {}
Required: No
tests: extends: - ./test-fixtures/extra-rules.yml cases: - allow: 'git push origin main' - deny: 'git push --force origin main'tests.extends
Section titled “tests.extends”Additional configuration files to merge only during test execution. These files are not loaded during normal runok check or runok exec.
Type: list[str]
Default: []
tests.cases
Section titled “tests.cases”Test cases to evaluate. Each entry specifies the expected decision (allow, ask, or deny) and the command to evaluate.
Type: list[TestEntry]
Default: []
Complete Example
Section titled “Complete Example”extends: - github:example-org/example-presets@v1.0.0
defaults: action: ask sandbox: standard
definitions: paths: secrets: - ~/.ssh - ~/.gnupg vars: safe-scripts: type: path values: - ./tests/run - ./scripts/lint.sh sandbox: standard: fs: read: deny: - <path:secrets> write: allow: - . deny: - <path:secrets> network: allow: true strict: fs: read: deny: - <path:secrets> write: allow: - ./src deny: - <path:secrets> network: allow: false wrappers: - 'sudo <cmd>'
audit: enabled: true rotation: retention_days: 30
rules: - allow: 'git *' - allow: 'cargo test *' sandbox: strict - deny: 'rm -rf /' message: This operation is too dangerous. fix_suggestion: 'trash /' - ask: 'docker *' sandbox: standard