Skip to content
Back to skills

Appsec Implementer

ASecurity

MANUAL-ONLY; never auto-invoke. Implement a named, already-decided application security (AppSec) control in code, such as input validation, output encoding, parameterized queries, authorization, safe sessions/files, or server-side request forgery (SSRF) and redirect allowlists. Prove it test-first with a failing-then-passing negative test and no scope creep. Use when the user or an approved review has named the exact control to build. Side-effecting and manual-only. Do NOT use to choose contr...

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 11, 2026
securitygotestinggitapidatabasesecurity

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add ModernNomad-98/Project-Aegis --skill appsec-implementer --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Appsec Implementer?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Appsec Implementer
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/modernnomad-98-appsec-implementer/badge)](https://www.skillsdirectory.com/skills/modernnomad-98-appsec-implementer)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: appsec-implementer
description: MANUAL-ONLY; never auto-invoke. Implement a named, already-decided application security (AppSec) control in code, such as input validation, output encoding, parameterized queries, authorization, safe sessions/files, or server-side request forgery (SSRF) and redirect allowlists. Prove it test-first with a failing-then-passing negative test and no scope creep. Use when the user or an approved review has named the exact control to build. Side-effecting and manual-only. Do NOT use to choose controls (threat-modeler), review a diff (security-pr-reviewer), harden identity broadly (secrets-identity-hardener), or author row-level security (RLS) policies (rls-policy-auditor).
disable-model-invocation: true
---

# AppSec Implementer

Here, **AppSec** means application security, **API** means application programming interface, **ORM** means
object-relational mapper, **UX** means user experience, and **authz** means
authorization. The `§` symbol denotes a section.

## Purpose

Turn a named security control into a small, tested, reviewable code change.
The control is proven by a negative test that fails before the change and
passes after — an assertion that the abuse case is now denied — not by
"looks secure now". The deliverable is a scoped diff plus the test evidence
(commands run and their real output), touching only the files the control
requires. This skill builds one decided control at a time; it does not decide
what to build and it does not opportunistically refactor.

## Use When

- Use when: a threat model, `security-pr-reviewer` finding, or the user has
  NAMED the control — "add server-side authorization to this endpoint",
  "parameterize this query", "validate and length-cap this input", "set
  HttpOnly/Secure/SameSite on the session cookie", "allowlist the redirect
  target".
- Use when: fixing a specific known vulnerability with a regression test that
  pins the fix.
- Do NOT use when: it is not yet decided which controls are needed — run
  `threat-modeler` first; implementing undecided controls is guessing.
- Do NOT use when: reviewing a diff for security — `security-pr-reviewer`.
- Do NOT use when: the work is broad secrets/identity hardening across the
  app — `secrets-identity-hardener` *(manual-only)*.
- Do NOT use when: the control is a database row-level security (RLS) policy — author/audit via
  `rls-policy-auditor`.
- Do NOT use when: the ask is a sweeping "make the app secure" — that is not
  one control; decompose it via `threat-modeler` first.

## Inputs to Inspect

1. The control specification: the exact threat/finding it closes, from
   `threat-modeler`, `security-pr-reviewer`, or the user's request. No named
   control → Stop Conditions.
2. The code at the boundary being hardened: the handler, query, template,
   session config, or file path involved — and its callers.
3. The project's existing security utilities: validators, sanitizers, the ORM
   / query builder, the auth/session middleware — reuse them; do not
   hand-roll crypto or a second validation layer.
4. The test suite and its runner: where security/negative tests live and how
   they run, so the new test fits the project's conventions.
5. Framework/library versions (via lockfile) for the security API being used
   — behavior differs across versions; consult `docs-first-implementer` *(manual-only)*
   discipline rather than assuming an API exists.

## Workflow

1. **Confirm the control is decided and singular.** Restate the one control
   and the abuse case it closes. If undecided or plural, stop and route to
   `threat-modeler`.
   If the chosen control still leaves a user-facing implementation choice,
   explain each viable path in plain terms, why it applies to this abuse
   case, security benefits and residual risks, money/setup/upkeep or unknowns,
   and a recommendation with its reason and the fact that could change it.
   Ask one decision question before taking that path; a choice alone grants
   no new execution authority.
2. **Classify the change** (`change-classification-gate`) and confirm the
   approval path — security-control code changes need review; production
   config/secret changes cross `human-approval-boundary`.
3. **Write the negative test first.** Encode the abuse case as a test that
   attempts the forbidden action and asserts denial/failure. Run it; confirm
   it FAILS for the intended reason (the vulnerability is real), not a typo
   or setup error. This is the `tdd-engineer` red step for security.
4. **Implement the minimal control** using existing project utilities at the
   correct boundary (server-side, not just the client). No unrelated edits.
5. **Run the negative test; confirm it now passes.** Then run the full
   relevant suite to confirm no regression. Record exact commands + output.
6. **Add positive-path coverage** if the control could over-block (a
   validator that rejects legitimate input is a new bug).
7. **Stage exactly the intended files** (`reviewable-diff-discipline` *(manual-only)*);
   verify the staged set equals the control's footprint — no drive-by changes.
8. **Report** the control, the before/after test evidence, the files touched,
   residual risk, and any follow-up the control does NOT cover, so a reviewer
   (`security-pr-reviewer`) can verify it.

## Output Format

```
APPSEC CONTROL IMPLEMENTED — <control name>
Closes: <threat/finding id + abuse case>
Change class: <class> — approval: <path / obtained?>
Choice, if needed: <paths and reasons; costs/risks; recommendation + why +
  what could change it; one decision question>
Negative test (red→green):
  command: <cmd>
  before: FAIL — <intended failure reason>
  after:  PASS
Full suite: <command> — <result>
Files changed: <exact paths — control footprint only>
Boundary: <where the control sits — confirmed server-side>
Reused utilities: <existing validators/ORM/middleware used>
Does NOT cover: <residual risk / adjacent controls still open>
Handoff: security-pr-reviewer to verify the diff.
```

## Validation Checklist

- [ ] The control was named/decided before implementation — not invented here.
- [ ] Any user-facing implementation choice was explained with viable paths,
      costs and risks, a reasoned recommendation, and one question.
- [ ] A negative test was written first and confirmed failing for the right
      reason before the fix.
- [ ] The same test passes after the change; full relevant suite still green;
      real commands and output recorded.
- [ ] The control sits at a server-side/authoritative boundary, not only the
      client or user interface (UI).
- [ ] Existing project security utilities reused; no hand-rolled crypto or
      duplicate validation layer.
- [ ] Staged set equals the control footprint; no unrelated refactors.
- [ ] Residual/adjacent risk stated for the reviewer.

## Security Rules

- No security control ships without a negative test that fails before it and
  passes after — an untested control is unverified (the repository's
  [historical master prompt, section 6](../../../docs/prompts/claude-skills-master-generation-prompts-v4.md)).
- Controls are enforced server-side / authoritatively; client-side checks are
  UX, never the security boundary.
- Never hand-roll cryptography, token generation, or password hashing — use
  the platform/library primitive; flag if none is available and stop.
- Do not weaken or delete an existing control to make a test pass; if a
  control conflicts with the change, surface it via `human-approval-boundary`.
- Fixing one instance of a class (one unparameterized query) requires noting
  the sibling instances for a follow-up pass — do not imply the class is closed.

## Gotchas

- Adding validation only on the client leaves the server endpoint exploitable;
  the API is the boundary, the form is not.
- A negative test that passes on the FIRST run (before the fix) is testing the
  wrong thing — the vulnerability wasn't reproduced; fix the test before the code.
- Over-strict validators become availability bugs: a regex that rejects valid
  emails/names/unicode is a new defect — add positive cases.
- Encoding at the wrong layer (escaping in the database instead of at render, or
  double-encoding) neutralizes the control or corrupts data.
- Security "fixes" that touch many files invite rubber-stamping and hide the
  one line that matters — keep the diff to the control.

## Stop Conditions

- No specific control is named, or the ask is "make it secure" broadly →
  stop; decompose via `threat-modeler` first.
- The change touches production config, secrets, or a security policy whose
  blast radius is unclear → stop for `human-approval-boundary`.
- The negative test cannot be made to fail before the fix → stop; the
  vulnerability is not reproduced and the control may be unnecessary or
  misplaced — reconfirm the threat.
- Implementing the control requires a schema/RLS change → that is
  `rls-policy-auditor` / `secure-migration-reviewer` territory; hand off.
- The only correct fix is a dependency upgrade with breaking changes → stop
  and surface the tradeoff rather than silently pinning or forcing it.
  Explain that a breaking upgrade changes an API or behavior callers rely on.
  Compare the viable paths for this finding: upgrade and adapt callers now,
  use a supported compatible security release if one actually closes the
  issue, or contain exposure temporarily with a named owner and deadline
  when neither can land immediately. For each, state the security coverage
  and residual risk, compatibility/regression cost, money or vendor cost,
  setup time, and ongoing maintenance; mark unknowns and verify current
  support/prices. Recommend the path that closes the named vulnerability
  without unacceptable breakage, explain why, then ask one scoped decision
  question. A preference is not approval to change production dependencies
  or policy; follow the existing approval path before acting.

## Supporting Files

- [references/control-implementation-patterns.md](references/control-implementation-patterns.md)
  — per-control implementation checklists (validation, encoding, authz,
  session, file handling, server-side request forgery (SSRF)/redirect) and the negative-test shape for each.
- `evals/evals.json` — trigger + behavior cases.
- `evals/trigger-evals.json` — discrimination against `threat-modeler`,
  `secrets-identity-hardener`, and `security-pr-reviewer`.

Files in this skill

  • SKILL.md8.5 KB
  • evals/evals.json2.6 KB
  • evals/trigger-evals.json1.9 KB
  • references/control-implementation-patterns.md3.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…