Claude
Skills
Sign in
Back

security-patterns

Included with Lifetime
$97 forever

Security patterns for authentication, defense-in-depth, input validation, OWASP Top 10, LLM safety, and PII masking. Use when implementing auth flows, security layers, input sanitization, vulnerability prevention, prompt injection defense, or data redaction.

AI Agentssecurityauthenticationauthorizationdefense-in-depthowaspinput-validationllm-safetypii-maskingscripts

What this skill does


# Security Patterns

Comprehensive security patterns for building hardened applications. Each category has individual rule files in `rules/` loaded on-demand.

## Quick Reference

| Category | Rules | Impact | When to Use |
|----------|-------|--------|-------------|
| [Authentication](#authentication) | 3 | CRITICAL | JWT tokens, OAuth 2.1/PKCE, RBAC/permissions |
| [Defense-in-Depth](#defense-in-depth) | 2 | CRITICAL | Multi-layer security, zero-trust architecture |
| [Input Validation](#input-validation) | 3 | HIGH | Schema validation (Zod/Pydantic), output encoding, file uploads |
| [OWASP Top 10](#owasp-top-10) | 2 | CRITICAL | Injection prevention, broken authentication fixes |
| [LLM Safety](#llm-safety) | 3 | HIGH | Prompt injection defense, output guardrails, content filtering |
| [PII Masking](#pii-masking) | 2 | HIGH | PII detection/redaction with Presidio, Langfuse, LLM Guard |
| [Scanning](#scanning) | 3 | HIGH | Dependency audit, SAST (Semgrep/Bandit), secret detection |
| [Advanced Guardrails](#advanced-guardrails) | 2 | CRITICAL | NeMo/Guardrails AI validators, red-teaming, OWASP LLM |

**Total: 20 rules across 8 categories**

## Quick Start

```python
# Argon2id password hashing
from argon2 import PasswordHasher
ph = PasswordHasher()
password_hash = ph.hash(password)
ph.verify(password_hash, password)
```

```python
# JWT access token (15-min expiry)
import jwt
from datetime import datetime, timedelta, timezone
payload = {
    'sub': user_id, 'type': 'access',
    'exp': datetime.now(timezone.utc) + timedelta(minutes=15),
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
```

```typescript
// Zod v4 schema validation
import { z } from 'zod';
const UserSchema = z.object({
  email: z.email(),
  name: z.string().min(2).max(100),
  role: z.enum(['user', 'admin']).default('user'),
});
const result = UserSchema.safeParse(req.body);
```

```python
# PII masking with Langfuse
import re
from langfuse import Langfuse

def mask_pii(data, **kwargs):
    if isinstance(data, str):
        data = re.sub(r'\b[\w.-]+@[\w.-]+\.\w+\b', '[REDACTED_EMAIL]', data)
        data = re.sub(r'\b\d{3}-\d{2}-\d{4}\b', '[REDACTED_SSN]', data)
    return data

langfuse = Langfuse(mask=mask_pii)
```

## Authentication

Secure authentication with OAuth 2.1, Passkeys/WebAuthn, JWT tokens, and role-based access control.

| Rule | Description |
|------|-------------|
| `auth-jwt.md` | JWT creation, verification, expiry, refresh token rotation |
| `auth-oauth.md` | OAuth 2.1 with PKCE, DPoP, Passkeys/WebAuthn |
| `auth-rbac.md` | Role-based access control, permission decorators, MFA |

**Key Decisions:** Argon2id > bcrypt | Access tokens 15 min | PKCE required | Passkeys > TOTP > SMS

## Defense-in-Depth

Multi-layer security architecture with no single point of failure.

| Rule | Description |
|------|-------------|
| `defense-layers.md` | 8-layer security architecture (edge to observability) |
| `defense-zero-trust.md` | Immutable request context, tenant isolation, audit logging |

**Key Decisions:** Immutable dataclass context | Query-level tenant filtering | No IDs in LLM prompts

### `sandbox.network.deniedDomains` (CC 2.1.113+)

Network-layer blocklist enforced before Bash/WebFetch egress — pair with the hook-layer `DENY_PATTERNS` for defense in depth. Settings example:

```json
"sandbox": {
  "network": {
    "deniedDomains": ["*.evil.com", "pastebin.com", "transfer.sh"]
  }
}
```

Wildcards supported (`*.example.com`, `evil.com/*/malicious/*`). Plugins ship a baseline list in `src/settings/ork.settings.json`; project settings can extend it. Use for: prompt-injection exfil sinks, known-bad registries, paste services that bypass audit.

## Input Validation

Validate and sanitize all untrusted input using Zod v4 and Pydantic.

| Rule | Description |
|------|-------------|
| `validation-input.md` | Schema validation with Zod v4 and Pydantic, type coercion |
| `validation-output.md` | HTML sanitization, output encoding, XSS prevention |
| `validation-schemas.md` | Discriminated unions, file upload validation, URL allowlists |

**Key Decisions:** Allowlist over blocklist | Server-side always | Validate magic bytes not extensions

## OWASP Top 10

Protection against the most critical web application security risks.

| Rule | Description |
|------|-------------|
| `owasp-injection.md` | SQL/command injection, parameterized queries, SSRF prevention |
| `owasp-broken-auth.md` | JWT algorithm confusion, CSRF protection, timing attacks |

**Key Decisions:** Parameterized queries only | Hardcode JWT algorithm | SameSite=Strict cookies

## LLM Safety

Security patterns for LLM integrations including context separation and output validation.

| Rule | Description |
|------|-------------|
| `llm-prompt-injection.md` | Context separation, prompt auditing, forbidden patterns |
| `llm-guardrails.md` | Output validation pipeline: schema, grounding, safety, size |
| `llm-content-filtering.md` | Pre-LLM filtering, post-LLM attribution, three-phase pattern |

**Key Decisions:** IDs flow around LLM, never through | Attribution is deterministic | Audit every prompt

### Context Separation (CRITICAL)

Sensitive IDs and data flow AROUND the LLM, never through it. The LLM sees only content — mapping back to entities happens deterministically after.

```python
# CORRECT: IDs bypass the LLM
context = {"user_id": user_id, "tenant_id": tenant_id}  # kept server-side
llm_input = f"Summarize this document:\n{doc_text}"       # no IDs in prompt
llm_output = call_llm(llm_input)
result = {"summary": llm_output, **context}               # IDs reattached after
```

### Output Validation Pipeline

Every LLM response MUST pass a 4-stage guardrail pipeline before reaching the user:

```python
def validate_llm_output(raw_output: str, schema, sources: list[str]) -> str:
    # 1. Schema — does it match expected structure?
    parsed = schema.parse(raw_output)
    # 2. Grounding — are claims supported by source documents?
    assert_grounded(parsed, sources)
    # 3. Safety — toxicity, PII leakage, prompt leakage
    assert_safe(parsed, max_toxicity=0.5)
    # 4. Size — prevent token-bomb responses
    assert len(parsed.text) < MAX_OUTPUT_CHARS
    return parsed.text
```

## PII Masking

PII detection and masking for LLM observability pipelines and logging.

| Rule | Description |
|------|-------------|
| `pii-detection.md` | Microsoft Presidio, regex patterns, LLM Guard Anonymize |
| `pii-redaction.md` | Langfuse mask callback, structlog/loguru processors, Vault deanonymization |

**Key Decisions:** Presidio for enterprise | Replace with type tokens | Use mask callback at init

## Scanning

Automated security scanning for dependencies, code, and secrets.

| Rule | Description |
|------|-------------|
| `scanning-dependency.md` | npm audit, pip-audit, Trivy container scanning, CI gating |
| `scanning-sast.md` | Semgrep and Bandit static analysis, custom rules, pre-commit |
| `scanning-secrets.md` | Gitleaks, TruffleHog, detect-secrets with baseline management |

**Key Decisions:** Pre-commit hooks for shift-left | Block on critical/high | Gitleaks + detect-secrets baseline

## Advanced Guardrails

Production LLM safety with NeMo Guardrails, Guardrails AI validators, and DeepTeam red-teaming.

| Rule | Description |
|------|-------------|
| `guardrails-nemo.md` | NeMo Guardrails, Colang 2.0 flows, Guardrails AI validators, layered validation |
| `guardrails-llm-validation.md` | DeepTeam red-teaming (40+ vulnerabilities), OWASP LLM Top 10 compliance |

**Key Decisions:** NeMo for flows, Guardrails AI for validators | Toxicity 0.5 threshold | Red-team pre-release + quarterly

## Managed Hook Hierarchy (CC 2.1.49)

Plugin settings follow a 3-tier precedence:

| Tier | Source | Overridable? |
|------|--------|-------------|
| 1. Managed (plugin `settings.json`) | Plugin author ships defaults | Yes, by user |
| 2. Project (`.claude/settings.json`) | Repository config | Yes, by user |
| 3. User (`~/.

Related in AI Agents