diff --git a/skills/app-security/SKILL.md b/skills/app-security/SKILL.md
new file mode 100644
index 0000000..2f3b22b
--- /dev/null
+++ b/skills/app-security/SKILL.md
@@ -0,0 +1,98 @@
+---
+name: app-security
+description: >
+ Full-stack application and API security hardening: Four-Pillar upload defense,
+ SSRF prevention, input boundary clamping, IDOR elimination, and secret masking.
+ Use when creating or auditing API routes, handling uploads, making outbound requests,
+ or preparing pre-release security verification.
+concerns: [security]
+---
+
+# Application Security Hardening
+
+Enforces defensive boundaries across the API membrane, eliminating exploit vectors, path traversals, SSRF risks, IDOR vulnerabilities, and payload exhaustion.
+
+```mermaid
+flowchart LR
+ A["Inbound Request"] --> B["1. Membrane Clamping
(Schema & Bound Validation)"]
+ B --> C["2. Four-Pillar Uploads
(Size, Ext, Magic, Path)"]
+ C --> D["3. Outbound SSRF Guard
(Loopback/Metadata Block)"]
+ D --> E["4. Secret Masking
(Zero Token Sediment)"]
+```
+
+---
+
+## Phase 0: Setup and Protocols
+
+1. Review reference playbooks:
+ - [references/app-hardening-playbook.md](references/app-hardening-playbook.md) for concrete TypeScript/Python code patterns and boundary clamps.
+ - [references/review-checklist.md](references/review-checklist.md) for pre-release OWASP verification checks.
+2. Invariants:
+ - Every input payload must be typed and bounded.
+ - Every state mutation must verify session identity and tenant ownership.
+ - Outbound HTTP fetches must never touch private/loopback networks.
+
+---
+
+## Phase 1: Ingest and Check
+
+1. **Surface Identification**:
+ - Inbound API routes (REST, GraphQL, RPC handlers).
+ - File/document ingestion and attachment endpoints.
+ - Outbound network calls (webhooks, URL unfurlers, external data scrapers).
+ - Data persistence operations and logging sinks.
+2. **Access Control Check**:
+ - Confirm identity is derived from verified server sessions/tokens, never trusted client parameters (`userId`, `orgId`).
+ - Confirm entity queries enforce ownership: verify record exists AND belongs to the authenticated caller before mutating.
+
+---
+
+## Phase 2: Processing (Core Logic)
+
+### Step 1: Input Boundaries & Membrane Clamping
+- Never accept arbitrary, unvalidated request dictionaries. Model all payloads using strict schemas (e.g. Pydantic, Zod).
+- Enforce hard string limits:
+ - Text prompts / message content: Max 50,000 characters.
+ - Titles / Names: Max 100–200 characters.
+ - Pagination limits: Clamped to `1 <= limit <= 50`.
+ - Batch arrays: Clamped to max 100–200 items.
+- Sanitize entity and path identifiers against path traversal tokens (`../`, `..\\`).
+
+### Step 2: Four-Pillar Upload Defense
+When handling file or media uploads:
+1. **Size Bounds**: Reject payloads exceeding size thresholds (e.g., 100MB for docs; 5MB for images).
+2. **Blocked Extensions**: Reject executable and script formats (`.exe`, `.bat`, `.sh`, `.svg`, `.html`, `.php`).
+3. **Magic Byte Inspection**: Inspect file headers to detect disguised binaries (PE `MZ`, ELF, Mach-O).
+4. **Path Traversal Defense**:
+ - Sanitize original filenames (strip path separators and non-printable characters).
+ - Write files strictly to designated, isolated upload roots with unique IDs (e.g. UUID filenames).
+
+### Step 3: Outbound SSRF Guard
+Before executing outbound HTTP requests (scraping, webhooks):
+- Validate target URLs against an allowlist or safety filter.
+- Block loopback addresses (`127.0.0.1`, `localhost`, `::1`), RFC 1918 private subnets (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), and cloud metadata services (`169.254.169.254`).
+- Restrict allowed protocols strictly to `http` and `https`.
+
+### Step 4: Secret Masking & Error Shielding
+- Scrub Authorization tokens (`Bearer ***`), provider API keys, and sensitive credentials from logs, database traces, and telemetry.
+- In public HTTP error responses, return clean structured error objects with opaque error codes; never leak internal filesystem paths, environment variables, or stack traces.
+
+---
+
+## Phase 3: The System One Balance Pass
+
+- **Augment, Don't Handcuff**:
+ - Do NOT break local development workflows: allow local mock endpoints and fixture testing in non-production test environments.
+ - Keep security checks non-intrusive during prototyping; enforce strictly at boundaries and pre-release gates.
+ - Avoid noisy confirmation warnings for routine safe operations.
+
+---
+
+## Phase 4: Output Execution & Verification
+
+1. Run verification checks from [references/review-checklist.md](references/review-checklist.md).
+2. Provide a security verification summary detailing:
+ - Bound clamps applied to route schemas.
+ - Upload filters active (size, extension, magic bytes, safe path).
+ - SSRF protection status on outbound calls.
+ - Secret scrubbing confirmation.
diff --git a/skills/app-security/references/app-hardening-playbook.md b/skills/app-security/references/app-hardening-playbook.md
new file mode 100644
index 0000000..0aebad8
--- /dev/null
+++ b/skills/app-security/references/app-hardening-playbook.md
@@ -0,0 +1,160 @@
+# Full-Stack Application Security Hardening Playbook
+
+This high-level guide provides a reusable, standardized protocol for auditing and securing full-stack applications (Next.js, Node.js, Express, etc.).
+
+---
+
+## Phase 1: Endpoint & Access Control (Preventing IDOR)
+
+### 1. The Multi-Tenant Ownership Rule
+Every state-changing API request (`POST`, `PUT`, `PATCH`, `DELETE`) and private resource read (`GET`) must establish identity via the server session—never by trusting client parameters.
+
+#### Never Trust Client User IDs:
+```typescript
+// ❌ Vulnerable (attacker can pass any userId in body)
+const { title, userId } = await req.json();
+await db.resource.create({ data: { title, userId } });
+
+// ✅ Secure (always bind to verified session)
+const session = await getServerSession(authOptions);
+if (!session?.user?.id) return unauthorized();
+await db.resource.create({ data: { title, userId: session.user.id } });
+```
+
+#### Verify Resource Ownership Before Mutation:
+```typescript
+// Verify target record exists AND belongs to the caller
+const item = await db.resource.findUnique({ where: { id } });
+if (!item) return notFound();
+if (item.userId !== session.user.id) return forbidden();
+```
+
+#### Lock Down Sensitive Data Endpoints:
+* Strip internal data (emails, password hashes, roles, permissions) from public query endpoints.
+* Never allow query flags like `?includePrivate=true` unless the caller has verified ownership or administrative authorization for that account.
+
+---
+
+## Phase 2: Input Boundaries & Payload Sanitization
+
+### 1. Enforce Hard Limits on Every Field
+Unbounded input strings can cause database exhaustion, buffer overruns, or CPU denial-of-service (e.g., Bcrypt hashing huge strings).
+
+| Field Type | Recommended Hard Bound | Rationale |
+| :--- | :--- | :--- |
+| **Passwords** | Min 8 chars, Max 72–100 chars | Bcrypt truncates or burns excessive CPU beyond 72 bytes |
+| **Emails** | Max 254 chars | Standard RFC 5321 length; prevents regex DoS |
+| **Titles / Names** | Max 100–200 chars | Prevents UI overflow and DB memory bloat |
+| **Descriptions / Content** | Max 2,000–50,000 chars | Prevents payload bombing |
+| **Pagination limit** | Clamped to `1 <= limit <= 50` | Prevents querying the entire table at once |
+
+### 2. JSON & Batch Array Clamping
+When accepting array batches (e.g., bulk updating nodes or items), enforce an explicit upper limit (e.g., max 200–500 items per request).
+
+---
+
+## Phase 3: Safe File & Document Upload Architecture
+
+If an application accepts images, PDFs, or documents, implement the **Four-Pillar Upload Defense**:
+
+```mermaid
+flowchart LR
+ A["File Upload"] --> B["1. Size Check"]
+ B --> C["2. Extension & MIME Allowlist"]
+ C --> D["3. Magic Bytes Inspection"]
+ D --> E["4. Filename Sanitization & Storage"]
+```
+
+### 1. Size Caps:
+* Check file size before buffering: images (max 2–5MB), documents (max 10MB).
+* Terminate stream early if incoming chunks exceed the configured byte threshold.
+
+### 2. Strict MIME & Extension Allowlists:
+* **Allowed:** `image/jpeg` (`.jpg`, `.jpeg`), `image/png` (`.png`), `image/webp` (`.webp`), `application/pdf` (`.pdf`), `application/json` (`.json`), `text/markdown` (`.md`).
+* **Strictly Blocked:** `.exe`, `.bat`, `.sh`, `.php`, `.js`, `.html`, `.svg` (SVGs can embed `