Generate, scaffold, or refactor code so it embodies FIASSE v1.0.4 SSEM qualities by default — 10 attributes, Transparency and Least-Astonishment principles, ASVS-aligned controls, defensive boundary handling. Trigger on "secure/securable/FIASSE-compliant code", "harden", "secure-by-default", "audit-ready", or security-sensitive components (auth, file upload, password reset, input validation, API endpoints, queries) — even when those words are not explicit. For requirements use prd-securability-enhancement; for review use securability-engineering-review. The full PRD→generate→review→enhance loop is opt-in via "--full-loop" or "end-to-end securable".
How this skill is triggered — by the user, by Claude, or both
Slash command
/securable-claude-plugin:securability-engineeringThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill augments the built-in code generation capability by applying FIASSE v1.0.4 SSEM principles as engineering constraints. It does **not** perform full SSEM scoring (use `securability-engineering-review` for that).
This skill augments the built-in code generation capability by applying FIASSE v1.0.4 SSEM principles as engineering constraints. It does not perform full SSEM scoring (use securability-engineering-review for that).
The end-to-end PRD-enhance → generate → review → enhance → report loop is opt-in, not the default. See "Full Loop Mode" below.
Reference data: data/fiasse/ (especially S2.1–S2.6 foundational principles, S3.2.1–S3.2.3 SSEM attributes including S3.2.1.4 Observability, S2.5 Transparency, S4.3 Boundary Control, S4.4 Resilient Coding, S4.4.1 Canonical Input Handling, S4.6 Dependency Stewardship) and data/asvs/ for feature-level requirements.
Trigger this skill when the user asks to:
Watch for adjacent phrasings: "make this safe", "harden this endpoint", "I'm exposing this to the internet, can you...", "write the production version of...", "audit-ready", "production-grade".
Produce securable code from the user's request directly, applying SSEM constraints. Most invocations land here. The output is code + a Securability Notes block.
Run the full PRD-enhance → generate → review → enhance → report workflow. Activate only when the user:
--full-loop flag or argumentOtherwise stay in Default Mode. Do not invent a PRD for a small one-shot generation request.
When Full Loop Mode is active, follow plays/code-generation/securable-generation.md. When Default Mode is active, follow this file alone.
Before generating any code, apply these FIASSE v1.0.4 principles:
Every code generation output must satisfy these ten attributes. Read data/fiasse/ sections for definitions when context is needed.
| Attribute | Enforcement |
|---|---|
| Analyzability (FIASSE v1.0.4 S3.2.1.1) | Methods ≤ 30 LoC. Cyclomatic complexity < 10. Clear, descriptive naming. No dead code. Comments only at trust boundaries and complex logic, explaining why — not what. |
| Modifiability (FIASSE v1.0.4 S3.2.1.2) | Loose coupling via interfaces / dependency injection. No static mutable state. Security-sensitive logic (auth, crypto, validation) centralized in dedicated modules, not scattered across call sites. Configuration externalized. |
| Testability (FIASSE v1.0.4 S3.2.1.3) | All public interfaces testable without modifying code under test. Dependencies injectable / mockable. Security controls isolated for dedicated test suites. |
| Observability (FIASSE v1.0.4 S3.2.1.4) | Code-level instrumentation, not external tooling alone. Structured logs with sufficient context (who/what/where/when/outcome) at trust boundaries and security-sensitive operations. Health and performance metrics exposed through a standardized API. Failure paths produce observable signals; no silent exception swallowing. UI/operator feedback surfaces meaningful state without leaking internals. |
| Attribute | Enforcement |
|---|---|
| Confidentiality (FIASSE v1.0.4 S3.2.2.1) | Sensitive data classified at the type level. Least-privilege data access. No secrets in code, logs, or error messages. Encryption at rest and in transit where applicable. Data minimization. |
| Accountability (FIASSE v1.0.4 S3.2.2.2) | Security-sensitive actions logged with structured data (who, what, where, when). Audit trails append-only. Auth events (login, logout, failure) and authz decisions (grant, deny) recorded. No sensitive data in logs. |
| Authenticity (FIASSE v1.0.4 S3.2.2.3) | Use established authentication mechanisms. Verify token/session integrity (signed JWTs with pinned algorithm, secure cookies). Mutually authenticate service-to-service calls. Support non-repudiation. |
| Attribute | Enforcement |
|---|---|
| Availability (FIASSE v1.0.4 S3.2.3.1) | Enforce resource limits (memory, connections, file handles). Configure timeouts for all external calls. Rate-limit where appropriate. Thread-safe design for concurrent code. Graceful degradation for non-critical failures. |
| Integrity (FIASSE v1.0.4 S3.2.3.2) | Validate input at every trust boundary: canonicalize → sanitize → validate (FIASSE v1.0.4 S4.4.1). Output-encode when crossing trust boundaries. Use parameterized queries exclusively. Apply Derived Integrity (FIASSE v1.0.4 S4.4.1.2) and Request Surface Minimization (FIASSE v1.0.4 S4.4.1.1). |
| Resilience (FIASSE v1.0.4 S3.2.3.3) | Defensive coding: anticipate out-of-bounds input. Specific exception handling — no bare catch-all. Sandbox null checks to input/DB boundaries. Use immutable data structures in concurrent code. Deterministic disposal patterns (with, using, RAII). Graceful and secure failure: error messages don't leak internals. |
Apply the Boundary Control Principle (the "turtle analogy"): hard shell at trust boundaries, flexible interior.
Boundary input is hostile until proven otherwise — and "hostile" includes well-meaning but unusual, not just attacker-crafted. Real protocols and formats have edge cases that naive parsers fail on. Before writing any boundary-parsing code, think through these classes of variation explicitly:
Bearer, bearer, BEARER per RFC 6750/7235); leading/trailing whitespace; multiple values; comma-separated lists; non-ASCII; missing entirely./a/./b → /a/b), traversal (..), trailing slash, mixed-case schemes, IDN/punycode, repeated query keys.CON, PRN on Windows), traversal segments.Infinity/NaN, locale-specific separators, "yes"/"true"/"1"/"on" boolean variants.; charset=utf-8), spoofed declared type vs sniffed type."123" vs 123).Bearer already stripped or not.Don't enumerate all of these in code — pick the ones that matter for this boundary and handle them deliberately. The default for any RFC-defined token is "follow the RFC, don't reject the spec-compliant variant just because your prototype only saw one shape."
data/asvs/README.md and the relevant data/asvs/V*.md chapters to identify the security requirements applying to the feature being generated.data/fiasse/S3.2.1.md–S3.2.3.md for umbrella definitions.The code itself is the primary deliverable. After the code, append a short Securability Notes block:
## Securability Notes
- **SSEM attributes enforced**: [the 2–4 that actually shape this code, named briefly]
- **ASVS references**: [V-chapter.section IDs that apply]
- **Trust boundaries**: [where input is canonicalized/validated]
- **Dependencies**: [package@version — only when something non-trivial was introduced]
- **Trade-offs**: [decisions a reviewer needs to know — e.g., "in-process rate limit; switch to shared store for multi-instance"]
Skip bullets that have nothing material to say. For tiny edits with no boundary crossing, a single sentence is enough. The point of this block is to make review faster, not to perform thoroughness.
User request: "Write a Python FastAPI endpoint that lets a logged-in user fetch one of their own orders by ID."
Sloppy default (what to avoid):
@app.get("/orders/{order_id}")
def get_order(order_id: str, current_user=Depends(get_user)):
order = db.query("SELECT * FROM orders WHERE id = '" + order_id + "'")
return order
Issues: SQL injection (string concatenation), missing ownership check (any user can read any order — IDOR), broad return shape leaks fields, no logging, no input validation, no error handling.
Securable version:
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from uuid import UUID
import structlog
router = APIRouter()
log = structlog.get_logger()
class OrderView(BaseModel):
id: UUID
placed_at: str
status: str
total_cents: int
@router.get("/orders/{order_id}", response_model=OrderView)
def get_order(
order_id: UUID, # canonicalized: must parse as UUID or 422
current_user = Depends(get_authenticated_user), # auth at the boundary
orders = Depends(get_orders_repo), # injectable for tests
):
order = orders.find_owned_by(order_id, current_user.id) # ownership enforced server-side
if order is None:
log.info("order_lookup.denied",
user_id=current_user.id, order_id=str(order_id), reason="not_found_or_not_owned")
raise HTTPException(status_code=404, detail="Order not found")
log.info("order_lookup.granted",
user_id=current_user.id, order_id=str(order_id))
return OrderView.model_validate(order)
What changed and why:
order_id: UUID canonicalizes input at the boundary (Integrity, FIASSE v1.0.4 S4.4.1).find_owned_by(order_id, user_id) enforces ownership server-side — current_user.id is server-owned state, never trusted from the client (Derived Integrity, FIASSE v1.0.4 S4.4.1.2).OrderView projection limits the response to expected fields (Confidentiality; Request Surface Minimization, FIASSE v1.0.4 S4.4.1.1).Depends(get_orders_repo) is injectable, so tests can run without a real DB (Testability, Modifiability).These are the patterns to not emit during generation. Each row pairs the bad shape with the principle it would violate, so when you find yourself about to write one, you know what's going wrong and what the correct shape looks like.
| Pattern to avoid emitting | Principle / attribute violated | Tag | Correct shape instead |
|---|---|---|---|
| String-built SQL / shell / format strings touching user input | Integrity — input handling at boundary (FIASSE v1.0.4 S4.4.1, S4.3) | "Trust boundary input handling" | Parameterized query / subprocess arg list / format with placeholders |
Trusting req.body.user_id, X-Tenant-ID, JWT claims for authorization decisions | Integrity — Derived Integrity (FIASSE v1.0.4 S4.4.1.2) | "Derived Integrity violation" | Look up user/tenant from authenticated session; never client-asserted |
Spreading req.body / **request.json directly into ORM update | Integrity — Request Surface Minimization (FIASSE v1.0.4 S4.4.1.1) | "Mass assignment" | Explicit allow-list of named fields → typed DTO → mapped update |
os.path.join(base, user_input) / template path concatenation | Integrity — boundary canonicalization (FIASSE v1.0.4 S4.4.1) | "Path canonicalization gap" | Resolve absolute path, assert it's under base, reject otherwise |
jwt.decode(token) with default algorithms / no aud / no iss | Authenticity (FIASSE v1.0.4 S3.2.2.3) | "Token verification under-specified" | jwt.decode(token, key, algorithms=['RS256'], audience=..., issuer=...) |
print(...) / console.log(...) / fmt.Println(...) for security events | Accountability + Observability (FIASSE v1.0.4 S2.5, S3.2.1.4) | "Unstructured audit trail" | Structured logger emitting {event, actor, target, outcome, request_id} |
try: ... except: pass / silent failure paths | Observability (FIASSE v1.0.4 S3.2.1.4); Resilience (FIASSE v1.0.4 S3.2.3.3) | "Silent failure" | Specific exception types; log with context; re-raise or return typed error |
Bare except: / catch (e) returning raw exception text | Resilience; Confidentiality (FIASSE v1.0.4 S3.2.3.3, S3.2.2.1) | "Specific exception handling missing" | Named exception types, generic public message, internal log with detail |
| Module-level globals (DB connection, app, config) created at import | Modifiability + Testability (FIASSE v1.0.4 S3.2.1.2, S3.2.1.3) | "Import-time side effects" | Factory function / DI container / fixture-injected dependencies |
request.body.read() / ioutil.ReadAll(r.Body) with no size cap | Availability + Resilience (FIASSE v1.0.4 S3.2.3.1, S3.2.3.3) | "Unbounded resource consumption" | Bounded reader; explicit max_size; 413 on overflow |
password == request.password / non-constant-time secret comparison | Authenticity; Confidentiality | "Timing-side-channel comparison" | hmac.compare_digest / language equivalent |
| Hardcoded secrets, connection strings, or API keys | Confidentiality (FIASSE v1.0.4 S3.2.2.1) | "Secret in code" | Env var / secret manager; pass via injected config |
any / interface{} / dynamic on the trust-boundary surface | Analyzability + Integrity | "Trust-boundary type erasure" | Concrete typed DTO / Pydantic model / typed struct |
setTimeout / time.sleep as a substitute for actual rate limiting | Availability (FIASSE v1.0.4 S3.2.3.1) | "Sleep-based throttling" | Real rate limiter (token bucket / fixed window) keyed by actor |
External call without timeout (requests.get(url), http.Client{}) | Availability + Resilience | "Unbounded external call" | Explicit timeout= / configured Client with timeouts |
| Logging the full request body / response body / token by default | Confidentiality + Accountability (sensitive data in audit) | "PII in audit log" | Log structured event with IDs only; redact body and credential fields |
If you catch yourself emitting one of these, stop and rewrite.
Maintainability:
Trustworthiness:
ASVS feature requirements:
Reliability:
Dependency hygiene:
Transparency:
Anti-patterns avoided:
Output format:
try/except.data/asvs/README.md — ASVS chapter indexdata/asvs/V*.md — ASVS 5.0 feature requirements by chapterdata/fiasse/S2.1.md–S2.6.md — Foundational Principles (incl. Transparency S2.5 and Least Astonishment S2.6)data/fiasse/S3.2.1.md–S3.2.3.md — SSEM attribute umbrellas (Maintainability, Trustworthiness, Reliability)data/fiasse/S3.2.1.4.md — Observabilitydata/fiasse/S4.3.md — Boundary Control Principledata/fiasse/S4.4.md — Resilient Codingdata/fiasse/S4.4.1.md — Canonical Input Handlingdata/fiasse/S4.4.1.1.md — Request Surface Minimization Principledata/fiasse/S4.4.1.2.md — Derived Integrity Principledata/fiasse/S4.5.md / S4.6.md — Dependency Management and StewardshipProvides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub securability-engineering/securable-claude-plugin --plugin securable-claude-plugin