falcosecurity/prempti/prempti-falco-rules
Claude Code and agent skill by falcosecurity/prempti
- community
Checking that the SKILL.md file is still in the repository.
Author custom Falco rules for Prempti — the policy and visibility layer for AI coding agents. Use this skill whenever the user asks to create, edit, or debug rules that control what coding agents (Claude Code, etc.) can do. Triggers on phrases like "add a rule", "block this tool", "deny access to", "allow writes to", "create a security policy", "custom Falco rule for coding agent", or any request to modify files under rules/user/. This skill covers the coding_agent plugin source and its specific fields — NOT syscall rules.
Install
npx vskill@latest install falcosecurity/prempti/prempti-falco-rulesSKILL.md
Prempti Falco Rules Author
Write custom Falco rules that govern what AI coding agents can do at runtime. These rules intercept tool calls (shell commands, file writes/reads, MCP calls) and enforce allow/deny/ask verdicts before execution.
Context: How This System Works
Prempti intercepts every tool call a coding agent makes. Each call becomes a Falco event with structured fields. Your rules evaluate these events and decide the verdict:
- deny — block the tool call entirely (the agent sees an explanation)
- ask — prompt the user for confirmation (they see your output message directly)
- allow — no tag needed; tool calls that match no deny/ask rule are allowed
The agent sees the verdict reason as: "Rule Name: <your output message> | For AI Agents: ... | correlation=<id>". For deny verdicts, the LLM reformulates this for the user. For ask verdicts, the user reads your output message directly in a permission prompt — so write it for a human audience.
Available Fields
Every tool call event exposes these fields for conditions and output:
| Field | Type | Description | |
|---|---|---|---|
correlation.id | u64 | Unique event ID (always > 0, auto-included in output_fields) | |
agent.name | string | Agent identifier (e.g., claude_code) | |
agent.os | string | Host OS: linux, macos, windows, or unknown | |
agent.pid | u64 | PID of the agent process that invoked the hook (auto-included in output_fields). 0 when the platform lookup fails. | |
agent.hook_event_name | string | Hook lifecycle point (e.g., PreToolUse) | |
agent.session_id | string | Session identifier | |
agent.model | string | Model identifier (Codex-only; empty for Claude Code) | |
agent.turn_id | string | Turn identifier within a session (Codex-only; empty for Claude Code) | |
agent.cwd | string | Working directory as reported by the agent | |
agent.real_cwd | string | Working directory resolved to absolute canonical path | |
agent.real_cwd_prefix | string | Resolved working directory with one trailing /; use for path containment checks | |
tool.name | string | Tool name: Bash, Write, Edit, Read, Glob, Grep, Agent, etc. | |
tool.use_id | string | Unique identifier for this tool call | |
tool.input | string | Full tool input as JSON | |
tool.input_command | string | Shell command (Bash tool only, empty otherwise) | |
tool.file_path | string | Target file path, raw (Write/Edit/Read only) | |
tool.file_name | string | Final component of the target path before symlink resolution | |
tool.real_file_path | string | Target file path resolved to absolute canonical path (Write/Edit/Read only) | |
tool.patch_op | string | Codex apply_patch operation: Add, Update, Delete, or Move (empty otherwise) | |
agent.permission_mode | string | Session permission mode: default, acceptEdits, plan, bypassPermissions (Codex also emits dontAsk) | |
agent.transcript_path | string | Session transcript file path (empty when the agent reports null) |
Path fields come in raw/real pairs. Use real_* for path policy matching (resolved, absolute). Use raw fields for display. For policies based on a file name, match tool.file_name or basename(tool.real_file_path) so both sensitive symlink aliases and sensitive canonical targets are covered.
Rule Structure
Every rule needs these fields:
Tags (verdict)
| Tag | Effect | Priority convention | |
|---|---|---|---|
coding_agent_deny | Block the tool call | CRITICAL or ERROR | |
coding_agent_ask | Require user confirmation | WARNING | |
(empty []) | Informational / audit only | NOTICE or INFORMATIONAL |
All Falco priorities are valid: EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFORMATIONAL (or INFO), DEBUG.
When multiple rules match the same event, verdicts escalate: deny > ask > {allow | defer}. The lowest tier is the no-rule-match floor (default_action: allow by default, or defer to defer to the agent's own permission system) — deny/ask rules are unaffected by it.
Output Convention
The output: field is the message the coding agent (or user) sees. Write it as a clear, self-contained sentence:
- Start with "Falco" to attribute the verdict
- Use
%fieldto interpolate resolved values (e.g.,%tool.real_file_path) - Do NOT include structured
key=valuepairs — those are handled automatically byappend_output - For deny rules: write for an LLM audience (it will rephrase for the user)
- For ask rules: write for a human audience (they read it directly in the permission prompt)
Condition Language Quick Reference
Operators
| Operator | Example | ||
|---|---|---|---|
=, != | tool.name = "Bash" | ||
contains | tool.input_command contains "rm -rf" | ||
icontains | tool.input_command icontains "password" — case-insensitive contains | ||
startswith, endswith | tool.real_file_path startswith "/etc/" | ||
in | tool.name in ("Write", "Edit") | ||
pmatch | tool.real_file_path pmatch (sensitive_paths) — prefix match against a list | ||
glob | tool.real_file_path glob "/home/*/secrets/*" — wildcard pattern matching | ||
regex | `tool.input_command regex "curl.*\ | .*sh"` — RE2 regular expression | |
exists | tool.file_path exists — field has a value (cleaner than != "") | ||
and, or, not | Boolean combinators |
Transformers
| Transformer | Usage | |
|---|---|---|
val() | Field-to-field comparison: tool.real_file_path startswith val(agent.real_cwd_prefix) | |
basename() | Extract the canonical target filename: basename(tool.real_file_path) = ".env" (POSIX split on /; real_file_path is normalized to forward slashes on every platform). Combine it with tool.file_name for alias-aware policies. | |
tolower() | Case-insensitive comparison: tolower(tool.input_command) startswith "sudo " | |
len() | String length: len(tool.input_command) > 1000 — detect anomalous inputs |
Transformers can be chained: basename(tolower(tool.real_file_path)).
Without val(), the right-hand side is a literal string, not a field reference.
Lists and Macros
Lists define reusable sets of values. Macros define reusable condition fragments.
Override and Append
The override key modifies existing rules, macros, and lists across files — essential for customizing defaults without editing them:
Appendable fields: condition, output, desc, tags, exceptions. Replaceable fields: all appendable fields plus priority, enabled.
Where to Put Rules
The Prempti rule layout has three locations:
- Default rules:
rules/default/coding_agents_rules.yaml— shipped with the project, overwritten on upgrade - User rules:
rules/user/*.yaml— preserved across upgrades, this is where custom rules belong - Seen rule:
rules/seen.yaml— DO NOT modify, required for verdict resolution
These paths exist in two contexts:
| Context | rules/default/ | rules/user/ | |
|---|---|---|---|
| Project repo | source-controlled defaults | empty (.gitkeep); contributors add new rules here | |
| Installed system | ~/.prempti/rules/default/ (Linux/macOS) or %LOCALAPPDATA%\prempti\rules\default\ (Windows) | corresponding rules/user/ under the same prefix |
Important constraint on the installed system: Prempti's self-protection rules block Write/Edit on any path under the install prefix while the service is running, and deny every premptictl invocation. The agent cannot directly install or apply a rule on a running Prempti — the user must perform the manual install workflow described in Applying Rules to a Running Prempti.
In the project repo, drafting into rules/user/ is fine because those paths aren't under the install prefix.
Before writing a new rule, read rules/default/coding_agents_rules.yaml to check for overlaps. The default ruleset is organized into seven sections covering common AI-agent attack surfaces:
- Working-directory boundary — monitor / ask on file access outside the session cwd
- Sensitive paths — deny reads and writes to
/etc/,~/.ssh/,~/.aws/,.envfiles, etc. - Sandbox disable — Claude Code / Codex / Gemini CLI sandbox-disable attempts (Write, Edit, and Bash variants)
- Threats — credential access, destructive shell commands, pipe-to-shell, encoded payloads, curl/wget exfiltration, IMDS access, credential archives, SSH covert tunnels, cron persistence, history wipe, package publish, shell startup files, agent instruction files outside cwd, cross-agent auth file reads, MCP installs from untrusted hosts, MCP execution from temp dirs, credential glob patterns
- MCP and skill content — MCP config poisoning (
.mcp.json), slash-command and skill file injection (.claude/commands/,.claude/skills/), Claude Code subagent and plugin storage (.claude/agents/,.claude/plugins/), settings backups (.claude/backups/) - Persistence vectors — settings hooks, settings-level mcpServers, git hooks, package registry redirects,
.envAPI base-URL overrides, AI API keys in env files - Self-protection — block agent attempts to disable Prempti: every
premptictlinvocation, platform service-stop alternatives (systemctl / launchctl / taskkill / pkill), writes under the install prefix, and writes to Claude Code config files (~/.claude/settings.json,policy-limits.json)
The file also exposes reusable lists (sensitive_paths, sensitive_file_names, shell_startup_files, agent_instruction_files, env_file_names, registry_config_files) and macros (is_sensitive_path, is_outside_cwd, is_claude_data_path, is_write_tool, contains_ioc_domain, cmd_contains_ioc_domain) that user rules can extend via override: append.
If the user's request overlaps with an existing rule, prefer extending it via override: append rather than creating a duplicate. If the new rule is more restrictive (e.g., deny where the default only asks), explain the interaction to the user.
Applying Rules to a Running Prempti
The agent cannot install or apply a rule on a running Prempti by itself. Two self-protection rules make this a user-driven operation:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/prempti-falco-rules/SKILL.md
Popularity
- Repository stars
- 180
- Repository forks
- 22
- 7-day trend score
- 26
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/falcosecurity/prempti/prempti-falco-rules)