This document describes the security architecture of the nucleus Emacs configuration.
Nucleus implements a multi-layer security model for AI agent tool execution:
- ACL Router — Permission-based tool access control
- Sandbox — Restricted execution environment for untrusted operations
- Permit System — User-controlled tool authorization
Located in lisp/modules/gptel-ext-security.el, the ACL router intercepts tool creation via gptel-make-tool advice.
Tools matching deny rules are blocked from execution:
(defvar my/gptel-tool-deny-rules
'((:tool "Bash" :args (("command" . "rm\\(-rf\\|.*-rf\\)")))
(:tool "Bash" :args (("command" . "sudo")))
(:tool "Bash" :args (("command" . "chmod")))
(:tool "Bash" :args (("command" . "eval\\|exec")))
(:tool "Edit" :args (("file_path" . "\\.git/")))))Plan mode operates under stricter constraints than Agent mode:
| Mode | Allowed Toolsets | Restrictions |
|---|---|---|
| Plan | :readonly |
No file modification, no Bash |
| Agent | :nucleus |
Full tool access with confirmation |
The Programmatic tool (lisp/modules/gptel-sandbox.el) provides a restricted Lisp subset for tool orchestration:
;; Control flow
(if when unless)
;; Local binding
(let let*)
;; Data access
(plist-get alist-get assoc cons)
;; Tool invocation
(tool-call result)- Max tool calls: 20 per orchestration
- Timeout: 60 seconds
- Result truncation: 4000 chars for subagent results
The sandbox uses a whitelist approach — only explicitly allowed forms are evaluated. All other Lisp forms result in rejection.
Located in lisp/modules/gptel-ext-tool-permits.el, the permit system manages tool authorization.
| Level | Upstream | Behavior |
|---|---|---|
auto |
nil |
No confirmation ever |
normal |
'auto |
Confirm tools with :confirm t |
confirm-all |
t |
Confirm every tool call |
M-x my/gptel-toggle-confirm— Cycle through tiersM-x my/gptel-show-permits— Display permitted toolsM-x my/gptel-emergency-stop— Abort all requests, clear permits, lock down
During tool confirmation:
| Key | Action |
|---|---|
y |
Accept once |
n |
Defer (FSM stays paused) |
k |
Kill request |
a |
Accept and add to permits |
i |
Show tool info |
p |
Preview (for Edit/ApplyPatch) |
q |
Quit |
Located in lisp/modules/gptel-tools-preview.el, the preview system shows diffs before applying:
- Edit tool — Unified diff preview
- ApplyPatch tool — Patch preview with rejection handling
- Programmatic — Aggregate preview for multi-step plans
Preview is controlled by gptel-tools-preview-enabled (default: t).
- Start in Plan mode for exploration and analysis
- Switch to Agent mode only when changes are needed
- Use
M-x my/gptel-emergency-stopif the agent behaves unexpectedly - Review permits with
M-x my/gptel-show-permitsbefore long sessions - Enable confirmation with
M-x my/gptel-toggle-confirmfor untrusted contexts
User Input
│
▼
┌─────────────────┐
│ ACL Router │ ◄── Deny rules check
└────────┬────────┘
│
▼
┌─────────────────┐
│ Permit Check │ ◄── my/gptel-permitted-tools
└────────┬────────┘
│
▼
┌─────────────────┐
│ Confirmation UI │ ◄── Minibuffer/Overlay
└────────┬────────┘
│
▼
┌─────────────────┐
│ Tool Execution │
└─────────────────┘
| File | Purpose |
|---|---|
gptel-ext-security.el |
ACL router, deny rules |
gptel-ext-tool-permits.el |
Permit management, confirmation UI |
gptel-sandbox.el |
Restricted Lisp evaluation |
gptel-tools-preview.el |
Diff preview system |
nucleus-tools.el |
Toolset definitions |
nucleus-presets.el |
Mode presets, tool contracts |