Truestack application security
Skill adtn0810/truestack/skills/truestack-application-security
Honesty-first coding skill set for Claude Code — 21 skills behind an orchestrate router with an enforced governance gate, a code↔memory tally, and auto-research. Built for self-hosted work.
npx -y skills add adtn0810/truestack --skill truestack-application-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Design and harden the security of a self-hosted app — authentication (OAuth2/OIDC, MFA, passkeys/WebAuthn), authorization (RBAC/ABAC, deny-by-default, IDOR/BOLA/broken-access-control), the OWASP Top 10 (injection, SSRF, misconfiguration), input validation + output encoding, CSRF, password/credential storage (argon2id/bcrypt), security headers/CSP/HSTS, and STRIDE threat modeling. Use whenever the user asks "is this secure" / "secure this app" / "security review", builds a login / sign-in / sign-up / OIDC auth flow, weighs session vs JWT, adds MFA/2FA/passkeys, sets up RBAC/roles/permissions, mentions IDOR/SSRF/CSRF/XSS/SQLi/injection, hashes passwords, manages the app's runtime secrets/API keys/.env (not CI workflow or deploy-pipeline secrets), sets CSP/security headers, threat-models / sizes an attack surface, or asks how to store passwords or credentials safely (storage, retention, or encryption-at-rest of PII/personal data routes to truestack-data-privacy). The DESIGN discipline.
SKILL.md
11.5 KB, as published. Nobody here has run it
truestack-application-security
Security is a design property, not a checklist you bolt on at the end. The job is to make the safe path the only path: authorization that denies by default, injection that's structurally impossible, credentials that survive a database leak. On a self-hosted single server there's no WAF, no managed identity, no cloud security team — the app is the perimeter. Accuracy and honesty over a green-looking dashboard: name the real risk, don't hand-wave it.
Read project memory first — CLAUDE.md is auto-loaded (Principles + Boundaries); consult
.ai/memory/ for the stack, auth model, framework, and recorded security decisions. If none
exists, run truestack-project-memory. Keep the code↔memory tally balanced: an auth model, a CSP, a
session strategy, a threat-model decision are architecture — record them in the same change.
Auto-research, don't recall. OWASP Top 10 rankings, NIST password/MFA minimums, CVEs, and GDPR/CCPA specifics change and are version- and date-specific — ground every such claim in an authoritative source (OWASP Cheat Sheets, NIST SP 800-63B, the current Top 10, the CVE record) before asserting it. Abstain when you can't verify; never quote a parameter or regulation from memory.
A new auth model, a session/JWT switch, or a credential-handling change is high-risk,
security-touching design — route it through truestack-architecture-planning's approval gate before
code. The PreToolUse gate in hooks/ is a different layer: it governs agent actions
(destructive / secret / outbound calls at run time), not the app's security design — don't
confuse the two.
Where this skill sits: this skill owns the security design and discipline — the threat
model, the auth/authz architecture, the standing controls. It is not the one-shot SAFETY
pass truestack-quality-control runs on a specific change (QC enforces per-change; here you set what QC
checks against). Untrusted tool/MCP output is truestack-mcp-integration's boundary; the agent-action
gate is hooks/. truestack-observability redacts PII from telemetry but defers the privacy
policy to truestack-data-privacy. truestack-ci-and-delivery SHA-pins actions and runs the scan in CI,
while truestack-dependency-management owns the ongoing dependency policy/lifecycle.
truestack-backend-development implements the API; truestack-api-design owns the contract;
truestack-architecture-planning does system design. State which seam you're on and stay on it.
1. Authorization: deny by default, on the server, scoped to the subject
Broken Access Control is currently the #1 risk (A01:2021 — confirm the live ranking, don't quote it from memory; found in ~100% of tested apps). SSRF was its own category in the 2021 list (A10:2021); recent revisions fold it into Broken Access Control — verify the current list before citing any number. Default-deny every route, and derive the subject from the session/token, never from request input.
- IDOR/BOLA is the failure most teams miss. Any time the client names a resource
(
/orders/123,?user_id=), re-check ownership at the data layer for that exact record on every path — read and write — even when the user is authenticated and the UI hid the link. ConcretelyWHERE id=:id AND owner_id=:current_userfrom the session: the authenticated subject (sub) from a verified session/token is authoritative, but never trust a client-influenceduser_id/org_id/tenant_idfrom the request body (or a user-settable claim) as the resource scope. - Centralize the check so non-controller paths — background jobs, GraphQL resolvers, bulk endpoints — can't bypass it. A check that lives only in the controller is a hole everywhere else.
2. Authentication: prefer server-side sessions on one box
JWT's only real win is stateless horizontal scale you don't have on a single server, and its
weakness is you can't instantly revoke a stolen token without a server-side denylist — at which
point you've rebuilt sessions with worse ergonomics. Default to opaque-cookie → server-store
sessions. If you must use JWTs, keep access tokens short-lived (minutes) with refresh-token
rotation. Either way: cookies HttpOnly; Secure; SameSite=Lax (or Strict) with the __Host-
prefix; never store tokens in localStorage (XSS-readable). Invalidate server-side on
logout and on password/MFA change.
3. MFA: phishing-resistant by design
TOTP and push are phishable via real-time reverse-proxy (AiTM) kits that relay the code. Only FIDO2/WebAuthn passkeys (and PKI smartcards) are phishing-resistant — the signature is cryptographically bound to the real origin and can't be replayed to a fake domain. Support passkeys as the strong factor, keep TOTP as fallback, not primary. Syncable passkeys meet NIST AAL2; hardware-bound keys are needed for AAL3.
4. Passwords & credential storage
Hash with Argon2id at the current OWASP minimum (parameter examples →
references/hardening-reference.md; re-verify the live figure) — not plain bcrypt unless legacy,
never SHA-256/MD5. The bcrypt footgun: it silently truncates at 72 bytes, so long passphrases
collide — if you must use bcrypt, pre-hash with SHA-256+base64 or enforce the limit. Per NIST SP
800-63B: require length (≥8, support ≥64 / passphrases), screen against breached-password lists,
and explicitly do not impose composition rules or periodic rotation — both are now
prohibited, not merely discouraged. Generate a strong, unique app/session-signing key per
deployment, never a framework default.
5. Make injection structurally impossible
Don't sanitize — remove the class. Parameterized queries / prepared statements for all SQL
(never concatenate, including ORDER BY and identifiers — allowlist those against a fixed column
set). For OS commands pass an argv array to exec without a shell, never a built string. The
model most teams get backwards: input validation (allowlist by type/format/range — reject,
don't sanitize) defends the boundary, but the actual XSS/SQLi/command-injection fix is
context-aware output encoding at the sink (HTML body vs attribute vs JS vs URL each need
different encoding). Validation is not a substitute for encoding.
6. CSRF: an explicit token, not just SameSite
Treat SameSite cookies as defense-in-depth, not your CSRF defense — Lax still leaves
top-level GET state-changes, sibling-subdomain, and some method/redirect cases exploitable, and
a strict CORS policy is not CSRF protection either. Add an explicit token: synchronizer
token for stateful (session) apps, signed double-submit cookie for stateless/API-driven;
for pure-JSON APIs, require a custom header (e.g. X-CSRF-Token) that a simple cross-site form
can't set.
7. SSRF: an access-control problem, allowlist-only
SSRF was its own category in the 2021 list (A10:2021); recent revisions fold it into Broken
Access Control — verify the current list before citing any number. Defend it with an allowlist
of permitted hosts, never a denylist of bad IPs. The self-host bug: validate-then-fetch is
vulnerable to DNS-rebinding/TOCTOU — resolve the hostname once, check the resolved IP against
the allowlist, then connect to that exact IP, and disable HTTP redirect-following on
server-side fetches. Block loopback/private/link-local ranges (full range list →
references/hardening-reference.md). Even on one box, 169.254.169.254 (cloud metadata) and
your own localhost-bound admin/DB ports are the prize — bind internal services to 127.0.0.1
and firewall everything but 443.
8. Security misconfiguration: ship hardening as config
The highest-leverage, lowest-effort wins for one server (A05:2021). Serve only HTTPS (HSTS);
set a strict nonce-based CSP (deploy Report-Only first, then enforce) — the real second line
against XSS after output encoding — plus the standard hardening headers (full set + values →
references/hardening-reference.md). Disable stack traces / debug mode / verbose errors in prod,
remove default accounts and sample apps, keep OS/runtime/deps patched, and run as a non-root,
least-privilege service user with the DB on localhost only.
9. Secrets: out of code and source control
A committed .env, a key pasted for a "quick demo", or a world-readable config is the recurring
self-host breach — a secret in a repo is compromised the moment the repo is. Inject at
runtime (restricted-permission env file, systemd credentials, Docker/compose secrets, or a
self-hostable manager like Infisical/Vault), keep secrets out of logs and error pages, add
pre-commit secret scanning, and rotate anything that ever touched a repo or chat.
10. Threat-model at design time (the discipline QC doesn't run)
Do a 30-minute lightweight STRIDE pass before code — this is what makes this skill the design discipline, distinct from any per-change review. Draw a one-page data-flow diagram, mark trust boundaries (browser→server, server→DB, server→third-party/outbound fetch), and walk each crossing through Spoofing / Tampering / Repudiation / Information-disclosure / DoS / Elevation-of-privilege, writing the mitigating control next to each. Fixing a design flaw here is ~100× cheaper than in prod, and it catches the missing-authz and SSRF-shaped issues no linter will. Design in security logging/alerting for auth events (A09:2021) too — you can't detect credential-stuffing or IDOR-probing you never log.
Honest exit
Report against the real risk, not the effort. Claim a control only where you can point at the code that enforces it — an authz check you verified fires, a CSP you confirmed is served, a hash you read in the code. If a risk is open, a parameter is unverified, or a regulation needs a specialist, say so plainly and give a completion score (controls in place / total + what's open) rather than a false "secure" (honesty contract). When the design changes a recorded decision, update project memory in the same change; then hand off to truestack-quality-control before "done" — its one-shot safety pass enforces, per change, what you designed here.
Explain it simply
Say the threat and the fix in one plain line — "anyone could read another user's order because we trusted the id in the URL; now the query also checks it's their order." Show the auth model choice and the header/CSP set as a short list or table, not prose. After hardening anything, state in one line what an attacker can no longer do that they could before.