You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: harden path sandboxing with symlink protection, safe defaults, and sensitive file guards
- Add `Filesystem.containsReal()` with `realpathSync` to prevent symlink escape attacks
(same class of bug as Codex GHSA-w5fx-fh39-j5rw and Claude Code CVE-2025-54794)
- Add `isAbsolute(rel)` check to `Filesystem.contains()` for Windows cross-drive bypass
- Update `Instance.containsPath()` to use symlink-aware `containsReal()`
- Add safe permission defaults: deny `rm -rf`, `git push --force`, `git reset --hard`,
`DROP DATABASE`, `TRUNCATE` out of the box
- Add `Protected.isSensitiveWrite()` to detect writes to `.git/`, `.ssh/`, `.aws/`,
`.env*`, credential files even inside the project boundary
- Add `assertSensitiveWrite()` guard to write, edit, and apply_patch tools
- Remove resolved TODO comments from `file/index.ts`
- Update SECURITY.md, permissions docs, and security FAQ with practical guidance
- Add 94 tests including 62 e2e tests covering symlink attacks, path traversal,
sensitive file detection, and combined attack scenarios
Closes#202
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: SECURITY.md
+12-5Lines changed: 12 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,22 +12,29 @@ submit one that will be an automatic ban from the project.
12
12
13
13
Altimate Code is an AI-powered data engineering coding assistant that runs locally on your machine. It provides an agent system with access to powerful tools including shell execution, file operations, and web access.
14
14
15
-
### No Sandbox
15
+
### Permission System
16
16
17
-
Altimate Code does **not** sandbox the agent. The permission system exists as a UX feature to help users stay aware of what actions the agent is taking - it prompts for confirmation before executing commands, writing files, etc. However, it is not designed to provide security isolation.
17
+
Altimate Code includes a permission system that prompts for confirmation before the agent executes commands, writes files, or accesses resources outside your project. You can configure each tool as `"allow"`, `"ask"`, or `"deny"` — and use pattern-based rules to fine-tune behavior (e.g., allow `dbt run` but deny `rm *`).
18
18
19
-
If you need true isolation, run Altimate Code inside a Docker container or VM.
19
+
The permission system is designed to keep you informed and in control of what the agent does. It includes:
20
+
21
+
-**Per-tool and per-pattern controls** with wildcard matching
22
+
-**Per-agent permission overrides** (e.g., restrict `analyst` to read-only)
23
+
-**External directory detection** that prompts when the agent accesses files outside your project
24
+
-**Path traversal protection** that blocks attempts to escape the project directory
25
+
-**Doom loop detection** that alerts you when the agent repeats failed actions
26
+
27
+
However, the permission system operates at the application level. It does not provide OS-level sandboxing — the process runs with your user permissions. For high-security environments or when working with sensitive production systems, we recommend running Altimate Code inside a Docker container or VM for additional isolation.
20
28
21
29
### Server Mode
22
30
23
-
Server mode is opt-in only. When enabled, set `OPENCODE_SERVER_PASSWORD` to require HTTP Basic Auth. Without this, the server runs unauthenticated (with a warning). It is the end user's responsibility to secure the server - any functionality it provides is not a vulnerability.
31
+
Server mode is opt-in only. When enabled, set `OPENCODE_SERVER_PASSWORD` to require HTTP Basic Auth. Without this, the server runs unauthenticated (with a warning). It is the end user's responsibility to secure the server — any functionality it provides is not a vulnerability.
Copy file name to clipboardExpand all lines: docs/docs/configure/permissions.md
+123-1Lines changed: 123 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,7 @@ For tools that accept arguments (like `bash`), use pattern matching:
49
49
}
50
50
```
51
51
52
-
Patterns are matched in order -- first match wins. Use `*` as a wildcard.
52
+
Patterns are matched in order — last matching rule wins. Use `*` as a wildcard. Place your most specific rules first and your catch-all `"*"` rule last.
53
53
54
54
## Per-Agent Permissions
55
55
@@ -104,3 +104,125 @@ Set permissions via environment variable:
A good starting point for most data engineering workflows. Allows safe read operations, prompts for writes and commands:
113
+
114
+
```json
115
+
{
116
+
"permission": {
117
+
"read": "allow",
118
+
"glob": "allow",
119
+
"grep": "allow",
120
+
"list": "allow",
121
+
"edit": "ask",
122
+
"write": "ask",
123
+
"bash": {
124
+
"dbt *": "allow",
125
+
"git status": "allow",
126
+
"git diff *": "allow",
127
+
"git log *": "allow",
128
+
"ls *": "allow",
129
+
"cat *": "allow",
130
+
"rm *": "deny",
131
+
"DROP *": "deny",
132
+
"DELETE *": "deny",
133
+
"TRUNCATE *": "deny",
134
+
"*": "ask"
135
+
},
136
+
"external_directory": "ask"
137
+
}
138
+
}
139
+
```
140
+
141
+
### Strict (Production-Adjacent Work)
142
+
143
+
When working near production systems. Blocks destructive operations entirely and requires confirmation for everything else:
144
+
145
+
```json
146
+
{
147
+
"permission": {
148
+
"read": "allow",
149
+
"glob": "allow",
150
+
"grep": "allow",
151
+
"list": "allow",
152
+
"edit": "ask",
153
+
"write": "ask",
154
+
"bash": {
155
+
"dbt *": "ask",
156
+
"git status": "allow",
157
+
"rm *": "deny",
158
+
"DROP *": "deny",
159
+
"DELETE *": "deny",
160
+
"TRUNCATE *": "deny",
161
+
"ALTER *": "deny",
162
+
"git push *": "deny",
163
+
"git reset *": "deny",
164
+
"*": "ask"
165
+
},
166
+
"external_directory": "deny"
167
+
}
168
+
}
169
+
```
170
+
171
+
### Per-Agent Lockdown
172
+
173
+
Give each agent only the permissions it needs:
174
+
175
+
```json
176
+
{
177
+
"agent": {
178
+
"analyst": {
179
+
"permission": {
180
+
"write": "deny",
181
+
"edit": "deny",
182
+
"bash": {
183
+
"SELECT *": "allow",
184
+
"dbt docs *": "allow",
185
+
"*": "deny"
186
+
}
187
+
}
188
+
},
189
+
"builder": {
190
+
"permission": {
191
+
"bash": {
192
+
"dbt *": "allow",
193
+
"git *": "ask",
194
+
"DROP *": "deny",
195
+
"*": "ask"
196
+
}
197
+
}
198
+
}
199
+
}
200
+
}
201
+
```
202
+
203
+
## How Permissions Work
204
+
205
+
When the agent wants to use a tool, the permission system evaluates your rules in order:
206
+
207
+
1.**Config rules** — from `altimate-code.json`
208
+
2.**Agent-level rules** — per-agent overrides
209
+
3.**Session approvals** — patterns you've approved with "Allow always" during the current session
210
+
211
+
If a rule matches, it applies. If no rule matches, the default is `"ask"` — you'll be prompted.
212
+
213
+
When prompted, you have three choices:
214
+
215
+
| Choice | Effect |
216
+
|--------|--------|
217
+
|**Allow once**| Approves this single action |
218
+
|**Allow always**| Approves this pattern for the rest of the session |
219
+
|**Reject**| Blocks the action (optionally with feedback for the agent) |
220
+
221
+
"Allow always" approvals persist for your current session only. They reset when you restart Altimate Code.
222
+
223
+
## Tips
224
+
225
+
-**Start with `"ask"` and relax as you build confidence.** You can always approve patterns with "Allow always" during a session.
226
+
-**Use `"deny"` for truly dangerous commands** like `rm *`, `DROP *`, `git push --force *`, and `git reset --hard *`. These are blocked even if other rules would allow them.
227
+
-**Use per-agent permissions** to enforce least-privilege. An analyst doesn't need write access. A builder doesn't need `DROP`.
228
+
-**Review the prompt before approving.** The TUI shows you exactly what will run — including diffs for file edits and the full command for bash operations.
Copy file name to clipboardExpand all lines: docs/docs/security-faq.md
+42Lines changed: 42 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -198,6 +198,48 @@ For additional safety:
198
198
- Run against a **staging environment** before production
199
199
- Use the `analyst` agent with restricted permissions for ad-hoc queries
200
200
201
+
## What protections does Altimate Code have for file access?
202
+
203
+
Altimate Code includes several layers of protection to keep the agent within your project:
204
+
205
+
-**Project boundary enforcement** — File operations check that paths stay within your project directory (or git worktree for monorepos). Attempts to read or write outside the project trigger an `external_directory` permission prompt.
206
+
-**Path traversal blocking** — Paths containing `../` sequences that would escape the project are rejected with an "Access denied" error.
207
+
-**Bash command analysis** — The bash tool parses commands with tree-sitter to detect file operations (`rm`, `cp`, `mv`, etc.) targeting paths outside your project, and prompts for permission.
208
+
-**Non-git project safety** — For projects outside a git repository, the boundary is strictly the working directory (not the entire filesystem).
209
+
210
+
These protections operate at the application level. For additional isolation, you can run Altimate Code inside a Docker container or VM.
211
+
212
+
## Best practices for staying safe
213
+
214
+
1.**Review before approving.** The permission prompt shows you exactly what will happen — diffs for file edits, the full command for bash. Take a moment to read it.
215
+
216
+
2.**Deny destructive commands.** Add these to your `altimate-code.json` to block the most dangerous operations regardless of other rules:
217
+
218
+
```json
219
+
{
220
+
"permission": {
221
+
"bash": {
222
+
"rm -rf *": "deny",
223
+
"DROP *": "deny",
224
+
"DELETE *": "deny",
225
+
"git push --force *": "deny",
226
+
"git reset --hard *": "deny",
227
+
"*": "ask"
228
+
}
229
+
}
230
+
}
231
+
```
232
+
233
+
3. **Use per-agent permissions.** Give each agent only what it needs. The `analyst` agent doesn't need write access. See [Permissions](configure/permissions.md) for examples.
234
+
235
+
4. **Use read-only database credentials for exploration.** When using the agent for analysis or ad-hoc queries, connect with a read-only database user.
236
+
237
+
5. **Work on a branch.** Let the agent work on a feature branch so you can review changes before merging. Git gives you a full safety net.
238
+
239
+
6. **Back up before large operations.** If the agent is about to make sweeping changes, commit your current state first. You can always `git stash` or revert.
240
+
241
+
7. **Use Docker for sensitive environments.** If you're working with production systems or sensitive data, running Altimate Code in a container provides OS-level isolation on top of the permission system.
242
+
201
243
## Where should I report security vulnerabilities?
202
244
203
245
**Do not open public GitHub issues for security vulnerabilities.** Instead, email **security@altimate.ai** with a description, reproduction steps, and your severity assessment. You'll receive acknowledgment within 48 hours. See the full [Security Policy](https://github.com/AltimateAI/altimate-code/blob/main/SECURITY.md) for details.
0 commit comments