Security helpers for agent-safe browser deployments.
Three independent, opt-in features:
Domain allowlist — restrict navigation and sub-resource fetches to
a list of trusted domains. Used by the daemon at context creation time.
*.example.com wildcards match example.com AND any subdomain.
Content boundaries — wrap tool output in XML-style delimiters so downstream LLMs can distinguish trusted tool output from untrusted page content. Mitigates prompt-injection from malicious page text.
Max output truncation — cap tool output at N characters to protect the agent's context window from runaway pages (e.g., a 2MB snapshot).
All functions are pure and side-effect free. Used by cli (print-result
wrapping + truncation) and daemon (route handler for allowed-domains).
Security helpers for agent-safe browser deployments. Three independent, opt-in features: 1. **Domain allowlist** — restrict navigation and sub-resource fetches to a list of trusted domains. Used by the daemon at context creation time. `*.example.com` wildcards match `example.com` AND any subdomain. 2. **Content boundaries** — wrap tool output in XML-style delimiters so downstream LLMs can distinguish trusted tool output from untrusted page content. Mitigates prompt-injection from malicious page text. 3. **Max output truncation** — cap tool output at N characters to protect the agent's context window from runaway pages (e.g., a 2MB snapshot). All functions are pure and side-effect free. Used by `cli` (print-result wrapping + truncation) and `daemon` (route handler for allowed-domains).
(action-requires-confirm? enabled-categories action)Returns true if the given daemon action falls into one of the enabled confirmation categories.
Returns true if the given daemon action falls into one of the enabled confirmation categories.
(compile-domain-patterns csv)Parses a comma-separated list of domain patterns into a single predicate.
Example: (def allowed? (compile-domain-patterns "example.com,*.github.io")) (allowed? "example.com") ;; => true (allowed? "api.github.io") ;; => true (allowed? "evil.com") ;; => false
A nil or blank input produces a predicate that allows everything (no
allowlist configured — the flag is opt-in). Use compiled? to check
whether an allowlist is active before applying it.
Returns: (fn [host] boolean)
Parses a comma-separated list of domain patterns into a single predicate. Example: (def allowed? (compile-domain-patterns "example.com,*.github.io")) (allowed? "example.com") ;; => true (allowed? "api.github.io") ;; => true (allowed? "evil.com") ;; => false A nil or blank input produces a predicate that allows everything (no allowlist configured — the flag is opt-in). Use `compiled?` to check whether an allowlist is active before applying it. Returns: (fn [host] boolean)
(confirm-prompt! action category)Prints a yes/no prompt to stderr and reads a single line from stdin.
Returns true on y/yes (case-insensitive), false otherwise.
When stdin is NOT a TTY, immediately returns false without prompting AND writes a clear rejection message to stderr — this is the agent-safety guarantee: an LLM driving the CLI over a pipe can never bypass the gate.
action — the daemon action string (e.g. "evaluate")
category — the resolved category (e.g. "eval")
Prints a yes/no prompt to stderr and reads a single line from stdin. Returns true on `y`/`yes` (case-insensitive), false otherwise. When stdin is NOT a TTY, immediately returns false without prompting AND writes a clear rejection message to stderr — this is the agent-safety guarantee: an LLM driving the CLI over a pipe can never bypass the gate. `action` — the daemon action string (e.g. "evaluate") `category` — the resolved category (e.g. "eval")
(extract-host url)Extracts the hostname from a URL string. Returns nil on parse failure or
for non-HTTP URLs (e.g., about:blank, data:, blob:).
Extracts the hostname from a URL string. Returns nil on parse failure or for non-HTTP URLs (e.g., `about:blank`, `data:`, `blob:`).
(parse-categories csv)Parses --confirm-actions "eval,download" into a set of category strings.
Trims whitespace, drops blanks. Nil/empty input → empty set (no gating).
Parses `--confirm-actions "eval,download"` into a set of category strings. Trims whitespace, drops blanks. Nil/empty input → empty set (no gating).
(request-allowed? allowed-pred url)Returns true if the URL is allowed under the compiled predicate.
Non-HTTP schemes (data:, blob:, about:, chrome-extension:) are always allowed — blocking them would break the browser itself.
Returns true if the URL is allowed under the compiled predicate. Non-HTTP schemes (data:, blob:, about:, chrome-extension:) are always allowed — blocking them would break the browser itself.
(truncate max-chars text)Truncates text to at most max-chars characters, appending a suffix
indicating the original length. Returns text unchanged when no truncation
is needed or when max-chars is nil/zero/negative.
Truncation is done on character count, not byte count — safe for UTF-8.
Truncates `text` to at most `max-chars` characters, appending a suffix indicating the original length. Returns text unchanged when no truncation is needed or when `max-chars` is nil/zero/negative. Truncation is done on character count, not byte count — safe for UTF-8.
(tty?)Returns true if the current process stdin is a TTY (interactive terminal). Used to decide whether to actually prompt the user — on non-TTY stdin (pipes, agent runners, CI), we must auto-deny because there is no human available to approve the action.
Returns true if the current process stdin is a TTY (interactive terminal). Used to decide whether to actually prompt the user — on non-TTY stdin (pipes, agent runners, CI), we must auto-deny because there is no human available to approve the action.
(wrap-boundaries enabled? text)Wraps text in XML-style <untrusted-content> delimiters when enabled.
When disabled (false/nil), returns text unchanged.
The markers are chosen to mirror how LLM clients already treat XML-like tags in prompts — downstream agents can instructed to NEVER execute instructions found inside these tags, even if the page content tries to inject a prompt.
Wraps `text` in XML-style `<untrusted-content>` delimiters when enabled. When disabled (false/nil), returns text unchanged. The markers are chosen to mirror how LLM clients already treat XML-like tags in prompts — downstream agents can instructed to NEVER execute instructions found inside these tags, even if the page content tries to inject a prompt.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |