Agent skill
security
Enforce Elixir/Phoenix security — auth, OAuth, sessions, CSRF, XSS, SQL injection, input validation, secrets. Use when editing auth files, login flows, RBAC, or API keys.
Install this agent skill to your Project
npx add-skill https://github.com/oliver-kriska/claude-elixir-phoenix/tree/main/plugins/elixir-phoenix/skills/security
SKILL.md
Elixir/Phoenix Security Reference
Quick reference for security patterns in Elixir/Phoenix.
Iron Laws — Never Violate These
- VALIDATE AT BOUNDARIES — Never trust client input. All data through changesets
- NEVER INTERPOLATE USER INPUT — Use Ecto's
^operator, never string interpolation - NO String.to_atom WITH USER INPUT — Atom exhaustion DoS. Use
to_existing_atom/1 - AUTHORIZE EVERYWHERE — Check in contexts AND re-validate in LiveView events
- ESCAPE BY DEFAULT — Never use
raw/1with untrusted content - SECRETS NEVER IN CODE — All secrets in
runtime.exsfrom env vars
Quick Patterns
Timing-Safe Authentication
def authenticate(email, password) do
user = Repo.get_by(User, email: email)
cond do
user && Argon2.verify_pass(password, user.hashed_password) ->
{:ok, user}
user ->
{:error, :invalid_credentials}
true ->
Argon2.no_user_verify() # Timing attack prevention
{:error, :invalid_credentials}
end
end
LiveView Authorization (CRITICAL)
# RE-AUTHORIZE IN EVERY EVENT HANDLER
def handle_event("delete", %{"id" => id}, socket) do
post = Blog.get_post!(id)
# Don't trust that mount authorized this action!
with :ok <- Bodyguard.permit(Blog, :delete_post, socket.assigns.current_user, post) do
Blog.delete_post(post)
{:noreply, stream_delete(socket, :posts, post)}
else
_ -> {:noreply, put_flash(socket, :error, "Unauthorized")}
end
end
SQL Injection Prevention
# ✅ SAFE: Parameterized queries
from(u in User, where: u.name == ^user_input)
# ❌ VULNERABLE: String interpolation
from(u in User, where: fragment("name = '#{user_input}'"))
Quick Decisions
What to validate?
- All user input → Ecto changesets
- File uploads → Extension + magic bytes + size
- Paths →
Path.safe_relative/2for traversal - Atoms →
String.to_existing_atom/1only
What to escape?
- HTML output → Auto-escaped by default (
<%= %>) - User HTML → HtmlSanitizeEx with scrubber
- Never →
raw/1with untrusted content
Anti-patterns
| Wrong | Right |
|---|---|
"SELECT * FROM users WHERE name = '#{name}'" |
from(u in User, where: u.name == ^name) |
String.to_atom(user_input) |
String.to_existing_atom(user_input) |
<%= raw @user_comment %> |
<%= @user_comment %> |
| Hardcoded secrets in config | runtime.exs from env vars |
| Auth only in mount | Re-auth in every handle_event |
References
For detailed patterns, see:
${CLAUDE_SKILL_DIR}/references/authentication.md- phx.gen.auth, MFA, sessions${CLAUDE_SKILL_DIR}/references/authorization.md- Bodyguard, scopes, LiveView auth${CLAUDE_SKILL_DIR}/references/input-validation.md- Changesets, file uploads, paths${CLAUDE_SKILL_DIR}/references/security-headers.md- CSP, CSRF, rate limiting, headers${CLAUDE_SKILL_DIR}/references/oauth-linking.md- OAuth account linking, token management${CLAUDE_SKILL_DIR}/references/rate-limiting.md- Composite key strategies, Hammer patterns${CLAUDE_SKILL_DIR}/references/advanced-patterns.md- SSRF prevention, secrets management, supply chain
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
lab:autoresearch
Self-improving loop for plugin skills. Reads program.md, proposes one mutation per iteration, evaluates against deterministic scorer, keeps improvements via git, reverts failures. Targets weakest skill+dimension. Use with /loop for overnight runs.
promote
Generate X/Twitter release promotion posts with ASCII tables and CodeSnap rendering. Use when writing release posts, promotion tweets, plugin announcements, or preparing social media content for new versions.
skill-monitor
Analyze skill effectiveness across sessions. Computes per-skill metrics (action rate, friction, outcomes), identifies degrading skills, and generates improvement recommendations. Requires session-scan data in metrics.jsonl.
session-trends
Analyze trends across session metrics. Computes windowed aggregates, deltas, and compares against MEMORY.md findings. Use periodically for progress tracking.
cc-changelog
CONTRIBUTOR TOOL - Track CC changelog, extract new versions since last check, analyze impact on plugin (breaking changes, opportunities, deprecations). Run periodically or before releases. NOT part of the distributed plugin.
session-scan
Compute metrics for Claude Code sessions. Discovers via ccrider, filters trivial, computes friction/opportunity/fingerprint scores. Use for broad session triage.
Didn't find tool you were looking for?