Software Securityhome
Fix a findingSearch
Phase 2 · Design

Secure design patterns

A secure design pattern is a reusable, proven answer to a recurring security problem in a design, such as one deny-by-default authorization point that every request passes through. Teams reuse the pattern, ideally through a shared component that implements it, instead of designing the control again for each feature.

OWASP Top 10:2025 notes that an insecure design cannot be fixed by a perfect implementation, because the needed control was never created. If each team writes its own authorization checks, the one new endpoint that forgets its check exposes data; behind a deny-by-default choke point, the forgotten check fails closed. One shared pattern also gives reviewers one thing to verify instead of ten variants.

Who
Architects and senior developers maintain the patterns; each team applies them, and AppSec reviews departures
When
When designing a feature or service, before choosing libraries or writing code
How often
On every design; update the catalog when reviews or incidents show a recurring gap
You end up with
A short catalog of approved patterns and components, and designs that name the pattern used at each boundary

Do this

  1. Start from a short list of principles

    Give designers a checklist: least privilege, fail-safe defaults (deny unless permitted), complete mediation (check every access), economy of mechanism and separation of privilege. Saltzer and Schroeder described these in 1975, and OWASP SAMM's first Secure Architecture activity is a short checklist of principles used during design.

  2. Standardize the security components

    Pick one supported option per security function: identity provider and single sign-on, authorization policy, secret store, logging and cryptography library. NIST SSDF PW.1.3 asks software to use standardized security features and services rather than proprietary ones, and PW.4 says reuse matters most for security functions such as cryptographic modules.

  3. Write down a pattern for each boundary type

    OWASP Top 10:2025 recommends a library of secure design patterns or paved-road components. Document the pattern for each kind of boundary, with an example: one deny-by-default authorization choke point; the tenant taken from the session, with database row-level security as a backstop; untrusted input parsed into a typed value once at the boundary; idempotency keys and explicit state machines for money and workflows; an egress allowlist for outbound fetches.

  4. Make the safe path the easy path

    Ship each pattern as a library, template or framework default: parameterized query builders, auto-escaping templates, secure cookie and CSRF defaults. Give any unsafe escape hatch a loud, searchable name, such as dangerouslySetInnerHTML, unsafe_ or raw, so it stands out in code review.

  5. Name the pattern in every design

    In the design document or threat model, state the pattern each boundary uses, such as "invoice API: choke-point authorization, tenant-scoped repository". Treat each departure as a decision with a reason and an owner, and send it to the security design review (Security design review).

  6. Test that each pattern holds

    Add tests that fail if a pattern is bypassed: a new route with no explicit rule returns 403, a query without the tenant filter returns no rows under row-level security, and an error inside the permission check denies the request. Feed recurring review findings back into the catalog, as OWASP SAMM's Architecture Assessment practice describes.

Done when

The design names the pattern used at each boundary, and any departure is a recorded decision.

Mark it in the gap check

Common mistakes

  • Scattering authorization checks across handlers. The endpoint that forgets its check exposes data, and there is no single place to test.
  • Taking the tenant or the owner from the request. Each component passes its own check while the system as a whole serves another tenant's data.
  • Failing open. An exception or timeout in a permission or validation step that lets the request through turns an outage into a breach.
  • Publishing patterns without components. A pattern on a wiki page gets reimplemented differently by each team; a supported library gets reused.
  • Relying on row-level security without checking roles. In PostgreSQL, superusers and roles with BYPASSRLS always bypass it, and table owners do unless you set FORCE ROW LEVEL SECURITY.
  • Assuming layered controls are independent. Two defenses that share one assumption, such as a trusted header, fail together.

Which pattern for which problem?

A short catalog to use as a design checklist. The guide on secure design patterns has examples for each.

Which pattern for which problem?: table
PatternUse it whenPrevents
Choke-point authorization, deny by defaultAny system with sensitive actionsMissing or inconsistent access checks
Capability token: unguessable, scoped, expiringSharing access to one specific objectTampering with object IDs (IDOR)
Parse, don't validateAny untrusted inputUnchecked values reaching logic
Safe-by-default APIBuilding an API other developers callInjection and escaping mistakes at each call site
Tenant from the session, with row-level securityMulti-tenant dataCross-tenant data access
Fail closedAny authentication, authorization or validation stepErrors that grant access
Least privilege and separation of dutiesComponents, credentials and dangerous actionsWide blast radius; one actor completing a high-value action alone
Idempotency keys and explicit state machinesMoney and multi-step workflowsDouble spending and skipped steps

Tools and guides

Standards

NIST SSDF 1.1
PW.1 Design Software to Meet Security Requirements and Mitigate Security RisksPW.4 Reuse Existing, Well-Secured Software When Feasible Instead of Duplicating Functionality

Sources

  1. Saltzer and Schroeder: The Protection of Information in Computer Systems, basic principles. 1975.
  2. OWASP Secure Product Design Cheat Sheet
  3. OWASP SAMM: Secure Architecture, stream A (Architecture Design)
  4. OWASP SAMM: Architecture Assessment
  5. NIST SP 800-218: Secure Software Development Framework (SSDF) Version 1.1. February 2022.
  6. OWASP Top 10:2025 A06 Insecure Design
  7. PostgreSQL: row security policies. PostgreSQL 18.

Find your next answer

Type to search. Search runs in your browser.

Searches run in your browser, but the host can infer them from the index files they load. The address shows your search so you can bookmark or share it.