igni follows a defense-in-depth approach. Multiple independent layers of protection ensure that even if one layer is bypassed, others still guard against harm.
igni is an AI agent that reads, writes, and executes code on behalf of the user. The primary threats:
| Threat | Risk | Mitigation |
|---|---|---|
| Destructive commands | Agent runs rm -rf /, DROP TABLE, force-push |
Blocked patterns, confirmation prompts |
| Sensitive file access | Agent reads/writes .env, credentials, private keys |
Protected paths list, file guards |
| Prompt injection | Malicious content in files/URLs tricks the agent | Tool output filtering, agent isolation |
| Runaway recursion | Agents spawn infinite sub-teams | Depth limits, agent caps, timeouts |
| Data exfiltration | Agent sends code to external services | Network restrictions, web access controls |
| Supply chain | Malicious agents or MCP servers | Agent loading from trusted directories, MCP approval |
| Cost runaway | Agent makes excessive API calls | Token limits, rate limiting, max tool calls |
Every tool call goes through permission checks before execution.
Permission levels:
| Level | Behavior | When to Use |
|---|---|---|
allow |
Auto-approve, no prompt | Read-only operations, safe commands |
ask |
Prompt user for approval | File writes, shell commands, git push |
deny |
Block entirely | Web access in sensitive projects |
Default permissions:
permissions:
file_read: "allow"
file_write: "ask"
shell_execute: "ask"
shell_restricted: "allow" # read-only commands (rg, find, tree)
web_search: "deny"
web_fetch: "deny"
git_push: "ask"
git_destructive: "ask" # force-push, reset --hard, etc.Approval prompts:
When a tool call requires approval (ask level), the user sees the full command and chooses a response:
◆ editor wants to run: npm test
[y] Yes, allow once — approve this specific invocation
[a] Always allow — permanently allow "npm test"
[s] Allow similar — permanently allow "npm *" (pattern)
[n] No, deny — block this invocation
Choice:
| Response | Persists | What It Does |
|---|---|---|
| Allow once | No | Approves only this exact call |
| Always allow | Yes | Adds this exact command to the allowlist |
| Allow similar | Yes | Adds a pattern (e.g., npm *, pytest *) to the allowlist |
| Deny | No | Blocks this call, agent can try alternatives |
Permanent rules are saved to ~/.ember/permissions.yaml:
# Auto-generated from approval prompts — edit to adjust
allowlist:
shell_execute:
- "npm test" # from "always allow"
- "pytest *" # from "allow similar"
- "ruff check *" # from "allow similar"
file_write:
- "src/**"
- "tests/**"Pattern matching uses glob syntax. Exact entries come from "always allow", pattern entries from "allow similar". When a new command comes in, it checks the allowlist first, then falls back to the permission level from config.
Permission modes (CLI shortcuts):
| Mode | What It Does |
|---|---|
ignite-ember (default) |
Asks for writes and shell commands |
ignite-ember --accept-edits |
Auto-approves file edits, asks for shell |
ignite-ember --strict |
Asks for everything including reads |
ignite-ember --read-only |
No file modifications allowed |
ignite-ember --auto-approve |
Auto-approves everything (use with caution) |
Files matching these patterns cannot be written to, regardless of permission level:
safety:
protected_paths:
- ".env"
- ".env.*"
- "*.pem"
- "*.key"
- "credentials.*"
- "secrets.*"
- "id_rsa*"
- "*.p12"
- "*.pfx"Protected paths are enforced at the tool layer — even if an agent tries to write to .env, the tool refuses. The agent is informed why and can suggest alternatives.
Add project-specific protected paths:
# .ember/config.yaml
safety:
protected_paths:
- ".env"
- "production.config.yaml"
- "terraform/*.tfstate"
- "keys/"Blocked commands (always blocked):
safety:
blocked_commands:
- "rm -rf /"
- ":(){ :|:& };:" # fork bomb
- "mkfs"
- "dd if=/dev/"
- "> /dev/sda"Confirmation-required commands:
safety:
require_confirmation:
- "git push"
- "git push --force"
- "npm publish"
- "pip install"
- "docker run"
- "terraform apply"
- "kubectl apply"
- "kubectl delete"Each agent only gets the tools declared in its .md definition:
# explorer.md — read-only tools only
tools: Glob, Grep, LS, Read, WebSearchAn explorer agent cannot call Write, Edit, or Bash — even if it tries. The tool registry enforces this at instantiation time. This means:
- A compromised agent prompt can't escalate to destructive tools
- Read-only agents are genuinely read-only
- You control the blast radius per agent
Recursive sub-team spawning has configurable limits:
orchestration:
max_nesting_depth: 5 # max recursive sub-team levels
max_total_agents: 20 # max agents per request
sub_team_timeout: 120 # seconds before sub-team times outIf limits are reached, the agent is informed and must proceed without sub-teams. These prevent:
- Infinite recursion (agent spawns agent spawns agent...)
- Resource exhaustion (too many concurrent agents)
- Hanging sub-teams (timeout kills stalled work)
Every tool execution is logged:
storage:
audit_log: "~/.ember/audit.log"Log format:
2026-03-13T10:30:00Z | session:abc123 | agent:editor | tool:Edit | path:/src/auth.py | status:success
2026-03-13T10:30:01Z | session:abc123 | agent:editor | tool:Bash | cmd:pytest | status:success
2026-03-13T10:30:02Z | session:abc123 | agent:editor | tool:Write | path:.env | status:BLOCKED (protected)
Audit logs are useful for:
- Post-incident investigation
- Compliance requirements
- Understanding what the agent did and why
- Detecting anomalous tool usage patterns
As server (IDE integration):
- stdio only — no network exposure; only the parent process connects
- Permission system applies to all MCP tool calls
- Audit logging covers MCP calls
- MCP servers igni consumes are NOT exposed to IDE clients (no passthrough)
As client (consuming external servers):
- Project-scoped servers require approval on first use
- Environment variables keep secrets out of config files
- Tool filtering limits which agents access which MCP tools
- Each MCP server runs in its own process (isolation)
Hooks extend the security model — they can add custom validation:
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": ".ember/hooks/security-check.sh",
"matcher": "Write|Edit|Bash"
}
]
}
}See Hooks for examples: blocking destructive commands, protecting sensitive paths, enforcing test execution.
Built-in safety guardrails run as Agno pre-hooks before each agent turn, catching problems before they reach the model:
| Guardrail | What It Does | When It Triggers |
|---|---|---|
| PII Detection | Scans prompts for personally identifiable information (emails, phone numbers, SSNs, etc.) | Before model call — flags PII so the agent can redact or warn |
| Prompt Injection | Detects injection attempts in user input and tool output (e.g., "ignore previous instructions") | Before model call — blocks the injected content |
| Moderation | Content moderation via OpenAI's moderation API | Before model call — flags harmful content |
guardrails:
pii_detection: true # detect and flag PII in prompts
prompt_injection: true # detect injection attempts
moderation: true # OpenAI moderation APIGuardrails are applied via AgnoFeatures.apply_to_agent() — they attach as pre-hooks that execute before the model is called. If a guardrail triggers, the agent is informed and can adjust its approach. Guardrails work alongside (not instead of) the permission system and protected paths.
Enterprise use: Guardrails are especially valuable for teams where agents process user-provided content (URLs, files, pasted text) that could contain injection attempts or sensitive data.
For organizations, administrators can enforce security policies that individual users cannot override:
// /Library/Application Support/EmberCode/managed-settings.json (macOS)
// /etc/ignite-ember/managed-settings.json (Linux)
{
"permissions": {
"web_search": "deny",
"web_fetch": "deny",
"git_destructive": "deny"
},
"safety": {
"protected_paths": [
".env*",
"*.pem",
"*.key",
"terraform/*.tfstate"
],
"blocked_commands": [
"curl",
"wget",
"nc"
]
},
"models": {
"allowed": ["MiniMax-M2.7"]
}
}Managed settings:
- Cannot be overridden by user or project config
- Applied before any other config layer
- Set by IT/security teams via MDM or system configuration
Control which MCP servers are allowed or required:
{
"mcp": {
"required": ["corporate-tools"],
"allowed": ["corporate-tools", "playwright", "github"],
"denied": ["*-untrusted-*"]
},
"mcpServers": {
"corporate-tools": {
"type": "http",
"url": "https://tools.internal.corp.com/mcp"
}
}
}safety:
network:
allowed_domains:
- "api.ignite-ember.sh" # All Ember services (models, CodeIndex, embeddings)
- "github.com"
block_all_other: true # deny-by-default for network accessFor teams that can't send code to the cloud, self-hosted CodeIndex is planned for a future release. This will allow all code analysis and embeddings to stay on your infrastructure. See CodeIndex for details.
| Security Feature | Claude Code | igni |
|---|---|---|
| Permission tiers | allow / ask / deny per tool | Same, plus category-based presets |
| Protected paths | Via deny rules | Dedicated protected_paths list |
| Command blocking | macOS sandbox (Seatbelt) | Blocked patterns, confirmation prompts |
| Audit logging | Not built-in | Built-in to ~/.ember/audit.log |
| Agent isolation | Tools per agent definition | Same — tools declared in .md |
| Depth limits | Sub-agents capped at 1 level | Configurable: depth, agent count, timeout |
| Managed settings | Enterprise policy files | Same — managed-settings.json |
| MCP security | Approval prompts, no passthrough | Same + tool filtering per agent |
| Hooks | PreToolUse/PostToolUse/Stop | Same events, same format |
| Guardrails | Not built-in | PII detection, prompt injection, moderation pre-hooks |
| Network control | Not built-in | allowed_domains, deny-by-default |
| CodeIndex | N/A | Self-hosting planned for data residency |
- Review default permissions — tighten if working with sensitive code
- Add project-specific protected paths for credentials, configs, state files
- Enable
require_confirmationfor destructive operations - Review MCP servers before approving — understand what tools they provide
- Check audit log periodically:
~/.ember/audit.log
- Commit
.ember/config.yamlwith team-agreed permission levels - Add protected paths for production configs, secrets, infrastructure state
- Set up hooks for additional validation (security scanning, test enforcement)
- Use agent evals to verify agents don't escalate permissions after changes
- Deploy managed-settings.json via MDM/configuration management
- Self-host CodeIndex for code data residency (planned — coming soon)
- Restrict allowed MCP servers to approved list
- Enable network deny-by-default with whitelisted domains
- Review blocked command lists and confirmation requirements
- Set up audit log aggregation for compliance