Skip to main content
The Base Profile (00-base.sb) provides the foundational layer for all Agent Safehouse policies. It defines the HOME_DIR replacement token, helper macros for path operations, and establishes the default-deny security posture.

Security Model

The Base Profile implements a zero-trust security model with explicit denies:
(deny default)
This single line ensures that all operations are blocked by default. Every permission must be explicitly granted through subsequent profile layers.
The (deny default) rule is critical for security. Without it, the sandbox would operate in permissive mode, defeating the purpose of Agent Safehouse.

HOME_DIR Replacement Token

Agent Safehouse uses a placeholder token that gets replaced at policy assembly time with the actual user’s home directory:
;; HOME_DIR starts as an explicit replacement placeholder.
;; Safehouse policy assembly (bin/safehouse.sh via bin/lib/policy.sh)
;; replaces this token with the resolved HOME path.
;;
;; Manual policy-only example (no generator):
;;   Replace the next line with:
;;     (define HOME_DIR "/Users/alice")
(define HOME_DIR "__SAFEHOUSE_REPLACE_ME_WITH_ABSOLUTE_HOME_DIR__")

How It Works

  1. Assembly Time: When bin/safehouse.sh generates a policy, it reads 00-base.sb
  2. Token Replacement: The __SAFEHOUSE_REPLACE_ME_WITH_ABSOLUTE_HOME_DIR__ placeholder is replaced with the actual home path (e.g., /Users/alice)
  3. Policy Generation: The resulting policy contains (define HOME_DIR "/Users/alice") ready for use
This approach allows policies to be user-agnostic until assembly time, making them portable across different systems and users.

Helper Macros

The Base Profile defines three helper macros that other profiles use extensively for path-based permissions:

home-subpath

Creates a recursive path matcher starting from a home-relative path:
(define (home-subpath rel) (subpath (string-append HOME_DIR rel)))
Usage Example:
(allow file-read* (home-subpath "/.config/git"))
;; Grants recursive read access to ~/.config/git and all subdirectories

home-literal

Creates an exact path matcher for a home-relative path:
(define (home-literal rel) (literal (string-append HOME_DIR rel)))
Usage Example:
(allow file-read* (home-literal "/.gitconfig"))
;; Grants read access to ~/.gitconfig only (not ~/.gitconfig.local)

home-prefix

Creates a prefix matcher that matches paths starting with the given home-relative path:
(define (home-prefix rel) (prefix (string-append HOME_DIR rel)))
Usage Example:
(allow file-read* (home-prefix "/.gitconfig"))
;; Matches ~/.gitconfig, ~/.gitconfig.local, ~/.gitconfig.backup, etc.

Path Matcher Comparison

literal

Exact path match onlyExample: ~/.npmrcMatches: ~/.npmrcDoesn’t match: ~/.npmrc.backup

prefix

Matches paths starting with prefixExample: ~/.gitconfigMatches: ~/.gitconfig, ~/.gitconfig.localDoesn’t match: ~/.git

subpath

Recursive directory matchExample: ~/.config/gitMatches: All files under ~/.config/git/Doesn’t match: ~/.config/github

Complete Source

(version 1)

;; ---------------------------------------------------------------------------
;; Base Profile
;; Core definitions, HOME_DIR replacement token, and helper macros shared by all modules.
;; Source: 00-base.sb
;; ---------------------------------------------------------------------------

;; HOME_DIR starts as an explicit replacement placeholder.
;; Safehouse policy assembly (bin/safehouse.sh via bin/lib/policy.sh)
;; replaces this token with the resolved HOME path.
;;
;; Manual policy-only example (no generator):
;;   Replace the next line with:
;;     (define HOME_DIR "/Users/alice")
(define HOME_DIR "__SAFEHOUSE_REPLACE_ME_WITH_ABSOLUTE_HOME_DIR__")

(define (home-subpath rel) (subpath (string-append HOME_DIR rel)))
(define (home-literal rel) (literal (string-append HOME_DIR rel)))
(define (home-prefix rel) (prefix (string-append HOME_DIR rel)))

(deny default)

Best Practices

  • Use home-literal for single files: ~/.npmrc, ~/.gitconfig
  • Use home-prefix for file variants: ~/.gitconfig* pattern
  • Use home-subpath for directories: ~/.config/git/, ~/.npm/
  • literal is most restrictive (safest)
  • prefix can accidentally match more than intended
  • subpath grants recursive access (use carefully)
Always test that your path matchers work as expected. A common mistake is using literal when you need prefix, or vice versa.

System Runtime

Core system paths and runtime permissions built on Base Profile helpers

Toolchains

Language-specific profiles using Base Profile macros

Build docs developers (and LLMs) love