Expand description
openmoat-core: the trusted decision core of OpenMoat.
This crate is pure: it performs no I/O and makes no OS calls. Callers
(the CLI, host adapters) read files, resolve the environment and pass
everything in. That keeps the security-relevant logic small, testable and
portable (it also builds for wasm32).
Pipeline: an Action is classified into AtomicActions, each atomic
action is evaluated deny → allow → review → defaults by a CompiledPolicy,
and the strictest verdict across them becomes the Decision. Facts that
need the filesystem reach the engine through ProgramResolver and
PathResolver. The policy compiler (ir::lower()) derives from the same
policy what an operating-system layer can enforce (ADR-019).
Modules§
- attribution
- Agent provenance for commits (ADR-056): which files of a commit an agent session wrote, and, where the record allows, which added lines.
- diffscan
- What the added lines of a change do (ADR-055): the content checks of
openmoat policy check-diff, on top of its path checks (ADR-050). - ir
- The policy compiler’s intermediate representation (ADR-019).
- lint
- Policy warnings: valid policies that probably do not mean what they say.
- mcp_
flow - MCP cross-server data flow (ADR-058): text one MCP server returned that then shows up in the arguments of another server’s tool that writes or sends.
- token
- Well-known token formats with a vendor prefix, and the services they belong to.
- yaml
- The one place OpenMoat reads and writes YAML (ADR-024).
Structs§
- Compiled
Policy - A policy with all patterns compiled for one evaluation context.
- Decision
- A verdict with the rule ids and human-readable reasons that produced it.
- Eval
Context - Everything the engine needs from the environment. Supplied by the caller.
- Injected
Map - An in-memory
InjectedLookup: tokens and the first source of each. The CLI keeps fingerprints instead; tests and the SDK can keep this. - Injected
Token - One distinctive part of untrusted content, normalised so a later call’s own parts compare equal to it.
- MapPath
Resolver - In-memory resolver for tests and conformance fixtures: symlink path → target, and the files that exist. The longest link that is the path itself or one of its ancestors is replaced by its target.
- MapResolver
- In-memory resolver for tests and conformance fixtures.
- McpSettings
- The
mcp:section (ADR-032). - NoResolver
- Resolver for callers without a search path (tests,
policy checkwithout state). - Notice
- The words of the block message for one decision (ADR-059): filled by the
program that answers the host from the deciding rule’s
titleandwhyand the call, already made safe to show (secrets masked, one line each). - OldNames
- Where a policy still uses
ask, the old name ofreview. - Patch
Replayed - One file the patch adds or updates and the content it leaves there:
Nonewhen that cannot be worked out (the file to update cannot be read, or a hunk is not found in it). - Policy
- The policy document (
policy.yaml), as written by users. - Push
- A command that publishes local commits.
- Repo
Policy - A repository policy. Only rules and a protection requirement:
defaults,executablesandsandboxstay the user’s, so any other key is a parse error. - Request
Path - The path of a request, decoded segment by segment, and whether its query names a method override.
- Require
- The
require:section of a policy, a repository policy or a pack. - Requirement
- The level an agent must be at, and which policy asks for it.
- Rule
Group - One named group of patterns. A group matches when any of its patterns matches the atomic action of the corresponding kind.
- Sandbox
Settings - The
sandbox:section (ADR-018, ADR-019). - Secret
- One brokered secret. Its
Debugoutput names only the id: where the value lives and where it goes say which secrets exist. - Secret
Route - One
METHOD /pathrule. - Staging
- What one session collected outside the project, folded from its calls.
- Staging
Settings - The
staging:section. Absent in policies written before it existed. - Taint
- What earlier calls of one session exposed it to.
- Taint
Secret - Where secret material in a session came from.
- Taint
Settings - The
taint:section. Absent in policies written before it existed. - Unknown
Kind - A name that is not one of
Kind::ALL. - Unknown
Verdict - A name that is not
allow,defer,review(or its old nameask) ordeny.
Enums§
- Action
- A tool call as seen from a host, before classification.
- Atomic
Action - The primitive operations an
Actiondecomposes into. - Browser
Open mcp.browser_open: the kind a read-only page open of an MCP tool is decided as.- Defaults
- Fallback verdicts when no rule matches: one verdict for everything, or a map
from action kind (
shell,fs.read,fs.write,net,fetch,web.search,tool.unknown,env.read,env.set,mcp, or"*") to a verdict; afetchwithout its own entry takes thenetone. This is how “outbound network is deny-by-default” is expressed, because deny rules are absolute and cannot be punched through by allow rules (ADR-002). - Injected
Token Kind - What a token is, which decides the atoms of a later call it is compared with.
- Kind
- One kind of atomic action. Ordered as policy files list them.
- Path
Refusal - Why a request’s path is refused rather than matched.
- Permit
- What a secret’s
allowrules say about one request. - Policy
Error - Why a policy file cannot be used. Any of these keeps
guardfrom deciding. - Required
By - Where a requirement in force comes from.
- Required
Level - A protection level a policy can require, weakest first, so the derived order is “at least as protected as”.
- Secret
Source - Where OpenMoat reads a secret’s value. The agent should not be able to read it
there;
moat policy lintwarns when no deny rule covers the source. - Secret
Tls - How a brokered secret reaches HTTPS requests.
- Untrusted
Kind - Where untrusted content a session read came from: the one list of what
injected input reads (ADR-057) and, less the metadata tools
(
taint.metadata_tools), of what taints a session, whichCompiledPolicy::exposureand the provenance report (ADR-056) both use. - Verdict
- Outcome of evaluating one or more atomic actions.
Constants§
- BUILTIN_
METADATA_ SERVER - The MCP server whose tab and window tools are the built-in metadata tools:
Claude in Chrome, which Claude Code provides itself (
claude --chrome, the browser extension), not a server any MCP configuration file defines. A server a configuration or a pin defines under this name is another program that took the name, and the built-in list does not apply to it (TaintSettings::defined_servers, ADR-069). - DEFAULT_
OUTSIDE_ FOLDERS - Outside folders read after which a send with a body carries the atom, by default.
- DEFAULT_
OUTSIDE_ READS - Outside reads after which a send with a body carries the atom, by default.
- DEFAULT_
POLICY - The shipped default policy, as YAML: what
moat initinstalls and what the conformance suite pins. Parse it withPolicy::parse. - HOLDS_
PROTECTED_ RULE - The rule id of a review for a folder that holds paths a deny rule names.
- INJECTED_
RULE - The rule id a decision tightened by injected input carries.
- MAX_
DNS_ LABEL_ LEN - Longest label of a DNS name (RFC 1035 §2.3.4).
- MAX_
DNS_ NAME_ LEN - Longest DNS name in text form, without the trailing dot (RFC 1035 §2.3.4).
- MAX_
INJECTED_ SCAN_ BYTES - The most bytes of one output that are scanned.
- MAX_
INJECTED_ TOKENS_ PER_ OUTPUT - The most tokens one output is reduced to; past it the rest are not kept.
- METHOD_
OVERRIDE_ HEADERS - Headers some frameworks read as the request’s real method. A request that carries one is refused for a secret with rules: the server would run a method the rules never saw.
- OLD_
REVIEW - The name
reviewhad before ADR-053. Audit rows, policies and SDK callers written before then use it; it is read asreviewand never written. - REPO_
RULE_ PREFIX - Prefix of every rule id a repository policy contributes, so decisions and
the audit log say where a rule came from, and a repository rule can never
pass for one of the user’s (
kernel-self) or collide with it. - SECRET_
RULE_ PREFIX - What a brokered secret’s id is prefixed with where it stands for a rule id
(
secrets.<id>): lint warnings, policy errors and sandbox losses. - STAGING_
ATOM - First word of the atom a send carries after the session collected or packed files outside the project.
- SUPPORTED_
VERSION - The policy schema version (
version:) this build reads; any other is an error. - TAINT_
RULE - The rule id a decision tightened by session taint carries.
- TITLE_
MAX_ CHARS - The longest
titlea group may have, in characters: the first line of the message, which hosts show in a prompt or a one-line notice. - UNCHECKED_
RULE - The rule id of a call the hook payload shows only in part
(
Action::Unchecked): it needs review whatever else it is decided. - WHY_
MAX_ CHARS - The longest
whya group may have, in characters.
Traits§
- Injected
Lookup - Where the tokens of earlier untrusted content came from, as the caller keeps them.
- Path
Resolver - Resolves symlinks in normalised, slash-separated absolute paths.
- Program
Resolver - Resolves program names using a search path the kernel controls.
Functions§
- evaluate
- Compile
policyforctxand decide a single action. - file_
url_ path - The local path a
file:URL names (file:///p,file://localhost/p,FILE:/p), percent-decoded, also as the value of--opt=URL. Programs that fetch URLs (curl,wget,git) read that file. - leaves_
unknown_ directory - Whether
command, run in a shell that stays open for later commands (an agent host’s persistent shell session), may leave that shell in a directory that cannot be known from the command alone: acdorpushdto a target that is not written out (cd "$X",cd -),popd, oreval, outside a subshell.sourceand.are not counted: what a sourced file runs is unchecked anyway, as any script’s commands are, and counting them would hold on everysource .venv/bin/activate. A later command in that shell would then be checked against the wrong directory. A command line that cannot be read counts as such a move. Acdto a written-out target is checked by the classifier itself, as a read of that directory. - literal_
shell_ pattern - A shell pattern that matches
commandtoken for token and nothing wider. - malformed_
port_ pattern - Whether a
netorfetchpattern reads ashost:portbut its port is not oneport_patternaccepts (example.com:*,example.com:0,example.com:08443), or names an IPv6 address with a port ([::1]:8443): such a pattern matches no host the hook or the proxy sees. A pattern whose part before the one:is hex digits and globs (fe80:*) is an IPv6 glob. - package_
near_ misses - Each
@package-near-miss <ecosystem> <name> <popular>atomcommandgives, as one line, wherever on the line the install is (cd app && pip install …,sh -c '…'): whatmoat allow --alwaysadds to its rule so the install a person approved is not held for review again. Package names are not paths, so the directories the command runs in do not matter here. - patch_
replay - The content the patch
textleaves in every file it adds or updates, in the order it names them,readgiving a file’s content as it is now (Nonewhen it cannot be read). A file the patch touches twice is replayed in order. Deleted files and a move’s source are left out: they hold nothing afterwards. - patch_
writes - Every file the patch
textwrites, in the order it names them. - port_
pattern - The host part and port of a
netorfetchpattern writtenhost:port(api.example.com:8443,*.example.com:8443,10.0.0.5:5432): exactly one:, then a port of 1 to 65535 in decimal digits with no sign and no leading zero.Nonefor any other pattern: one without a port, an IPv6 address (more than one:, which takes no port), or a port written another way (malformed_port_pattern). A leading!(an exclusion) is not part of it. - resolve_
path normalisefor a word a shell will expand, against a working directory that may be unknown (None).Nonewhen the result depends on a directory that is not known: a relative path and an unknowncwd,~-, or a~nameof another user (OpenMoat cannot know where other users’ homes live, so a cross-user path is unresolvable; a shell token with it needs review throughunparseable).