Project

Secure Design Patterns

February 2023

Personal View on GitHub

Building Security Into Software Design: A Practical Guide to Secure Design Patterns

A comprehensive exploration of six fundamental security patterns with working implementations


Introduction: The Security-by-Design Imperative

In today’s threat landscape, security cannot be an afterthought. According to research from Carnegie Mellon’s Software Engineering Institute, fixing security vulnerabilities after deployment costs exponentially more than addressing them during the design phase (Dougherty et al., 2009). Yet, traditional software development often treats security as something to “bolt on” after the core architecture is complete—a reactive approach that leads to scattered security controls, inconsistent enforcement, and persistent vulnerabilities.

What if we could weave security directly into the architectural patterns that form the foundation of our applications? This is the promise of secure design patterns: reusable solutions that integrate security controls at the design level rather than as aftermarket patches.

My repository, secure-design-patterns, provides practical, runnable Java implementations of six fundamental secure design patterns. Each pattern demonstrates how to embed authentication, authorization, and least privilege principles directly into object-oriented designs, creating systems that are secure by construction rather than by accident.

The Problem with Bolt-On Security

Traditional approaches to software security typically follow this pattern:

  1. Design the application architecture
  2. Implement core business logic
  3. Add authentication checks where needed
  4. Sprinkle authorization logic throughout
  5. Hope nothing was missed

This reactive methodology creates several critical problems:

  • Scattered Security Controls: Authentication and authorization logic becomes distributed across the codebase, making it difficult to audit and maintain
  • Inconsistent Enforcement: Without a unified approach, security policies are applied inconsistently, creating potential bypass opportunities
  • High Maintenance Burden: Security logic entangled with business logic makes both harder to modify and test
  • Increased Attack Surface: Each ad-hoc security check represents a potential point of failure

Research from academic institutions like Michigan State University has shown that using UML diagrams and patterns to model security requirements early in the software development lifecycle significantly reduces security vulnerabilities (Wassermann & Cheng, 2007).

Understanding Design Patterns in Security Context

Design patterns, as introduced by the Gang of Four (Gamma et al., 1994), provide reusable solutions to common software design problems. When extended with security considerations, these patterns become powerful tools for building secure-by-design systems. As noted in the Software Engineering Institute’s research on secure design patterns, “the creation of secure design patterns by generalizing and cataloging existing best practices benefits the developers of secure software products” (Dougherty et al., 2009).

The six patterns in my repository demonstrate how classic Gang of Four patterns can be enhanced with security-specific functionality:

1. Secure Factory Pattern

Security Principle: Centralized credential validation before object instantiation

The Factory Method pattern is one of the fundamental creational patterns that “defines an interface for creating an object, but lets subclasses decide which class to instantiate” (Gamma et al., 1994). In its secure variant, the factory validates credentials before creating sensitive objects like database connections or privileged resources.

UML Structure: The pattern follows the classic factory structure with an additional layer of credential checking:

                    ┌─────────────────┐
                    │   <<interface>> │
                    │     Factory     │
                    └─────────────────┘
                            △
                            │
                    ┌───────┴────────┐
                    │SecureFactory   │
                    │+ authenticate()│
                    │+ createObject()│
                    └────────────────┘

Key Security Benefits:

  • Single point of control for object creation
  • Credential validation happens before instantiation
  • Failed authentication prevents resource allocation
  • Consistent security policy enforcement across all object creation

Real-World Applications:

  • Database connection pooling with role-based access
  • API client factory with OAuth token validation
  • File system access with permission checking

For detailed UML diagrams of the Factory Method pattern, see the comprehensive examples at Wikipedia and UML-Diagrams.org.

2. Secure Builder Factory Pattern

Security Principle: Restricting complex object construction to trusted builders

The Builder pattern, traditionally used to construct complex objects step-by-step, can be secured by ensuring only authorized builders can assemble sensitive objects. This pattern combines the factory’s centralized control with the builder’s flexibility.

UML Structure: This pattern combines Factory and Builder patterns:

    ┌──────────────┐         ┌──────────────┐
    │ SecureFactory│────────>│ Builder      │
    │+ createBuild │         │+ buildPart() │
    └──────────────┘         └──────────────┘
           │                        △
           │                        │
           │                ┌───────┴────────┐
           │                │ TrustedBuilder │
           └───validates───>│+ authenticate()│
                            └────────────────┘

Key Security Benefits:

  • Multi-step validation during object construction
  • Prevention of partially-constructed objects in invalid states
  • Builder authorization separate from user authorization
  • Immutable objects with verified configurations

Real-World Applications:

  • Configuration objects with validated parameters
  • Encrypted message builders with key management
  • Secure session objects with verified attributes

3. Secure Strategy Factory Pattern

Security Principle: Runtime algorithm selection based on caller privileges

The Strategy pattern encapsulates algorithms behind a common interface, allowing them to be selected and swapped at runtime. In its secure form, the pattern ensures only authorized users can invoke certain strategies (e.g., biometric authentication vs. password-based authentication).

UML Structure:

    ┌─────────────────┐      ┌──────────────┐
    │StrategyFactory  │─────>│<<interface>> │
    │+ getStrategy()  │      │  Strategy    │
    │+ checkPrivilege │      └──────────────┘
    └─────────────────┘             △
                                    │
                    ┌───────────────┴────────────────┐
                    │                                │
            ┌───────┴────────┐            ┌─────────┴────────┐
            │PasswordStrategy│            │BiometricStrategy │
            │+ authenticate()│            │+ authenticate()  │
            └────────────────┘            └──────────────────┘

Key Security Benefits:

  • Different authentication mechanisms based on security context
  • Privilege escalation prevention through factory control
  • Centralized algorithm selection logic
  • Easy addition of new authentication methods

Real-World Applications:

  • Multi-factor authentication systems
  • Payment processing with different security levels
  • Data encryption with algorithm selection based on classification

4. Secure Chain of Responsibility Pattern

Security Principle: Multi-layered validation through handler pipeline

The Chain of Responsibility pattern allows multiple objects to handle a request by passing it along a chain until one object handles it (or all objects process it). For security, this creates a validation pipeline where each handler can approve, reject, or pass the request forward.

UML Structure: The pattern creates a linked chain of validators:

    ┌─────────────────────┐
    │  <<interface>>      │
    │    Handler          │
    │+ setNext(Handler)   │
    │+ handle(Request)    │
    └─────────────────────┘
            △
            │
    ┌───────┴──────────────────────────────────────┐
    │                                               │
┌───┴────────────┐  ┌─────────────────┐  ┌────────┴──────────┐
│ LoggingHandler │  │  AuthHandler    │  │AuthorizationHandler│
│+ handle()      │  │+ authenticate() │  │+ authorize()      │
└────────────────┘  └─────────────────┘  └───────────────────┘

The Chain of Responsibility pattern is extensively documented with UML examples at Wikipedia and in academic research by Wassermann & Cheng (2007).

Key Security Benefits:

  • Defense in depth through multiple validation layers
  • Request logging at entry point
  • Sequential authentication and authorization checks
  • Easy addition or removal of security checks

Real-World Applications:

  • HTTP request filtering (CORS, authentication, rate limiting)
  • Email spam filtering with multiple heuristics
  • Network packet inspection and firewall rules

Implementation Example:

// From the repository
public abstract class Handler {
    protected Handler next;
    
    public void setNext(Handler next) {
        this.next = next;
    }
    
    public abstract boolean handle(Request request);
}

5. Secure State Machine Pattern

Security Principle: Explicit state modeling with guarded transitions

State machines model an object’s lifecycle through discrete states and transitions. A secure state machine explicitly models authentication and authorization states, ensuring that state transitions only occur when security conditions are met.

UML State Diagram: Security states with guarded transitions:

    ┌─────────────┐ credentials ┌──────────────┐
    │Unauthenticat├────────────>│ Authenticated│
    │    -ed      │             │              │
    └─────────────┘             └───────┬──────┘
                                        │ [hasRole(admin)]
                                        │
                                 ┌──────┴─────────┐
                                 │  Authorized    │
                                 │   (Admin)      │
                                 └────────────────┘

UML State Machine diagrams for security are extensively covered in research literature. Sparx Systems provides excellent tutorials on State Machine Diagrams, while academic research by Bajaj & Ramachandran (2015) demonstrates how to represent security specifications in UML State Machine diagrams.

Key Security Benefits:

  • Explicit modeling of security states
  • Impossible to reach privileged states without proper transitions
  • Clear audit trail of state changes
  • Prevention of privilege escalation through invalid transitions

Real-World Applications:

  • User session management (anonymous → authenticated → authorized)
  • Document workflow with approval states
  • Payment processing state machines

Carnegie Mellon’s research on secure state machines shows this pattern effectively prevents unauthorized state transitions, a common source of security vulnerabilities (Dougherty et al., 2009).

6. Secure Visitor Pattern

Security Principle: Adding access control operations without modifying protected classes

The Visitor pattern allows adding new operations to objects without modifying their classes. In its secure form, visitors implement different access control operations (guest access, user access, admin access) that can be applied to protected content.

UML Structure: The visitor with role-based access:

    ┌──────────────────┐        ┌─────────────────┐
    │ <<interface>>    │        │ <<interface>>   │
    │   Element        │        │   Visitor       │
    │+ accept(Visitor) │        │+ visit(Element) │
    └──────────────────┘        └─────────────────┘
            △                           △
            │                           │
    ┌───────┴─────────┐        ┌───────┴──────────┐
    │ ProtectedContent│        │ AccessCheckVisitor│
    │+ accept()       │<───────│+ visit()         │
    │+ getContent()   │        │+ checkPermission()│
    └─────────────────┘        └──────────────────┘

The Visitor pattern’s UML structure and security implications are well-documented at Wikipedia and in educational resources from Baeldung.

Key Security Benefits:

  • New security operations without modifying protected classes
  • Separation of access control logic from business logic
  • Role-based access control through different visitor implementations
  • Open/Closed Principle for security features

Real-World Applications:

  • Content management systems with role-based viewing
  • Document redaction based on clearance level
  • API response filtering by user permissions

Practical Implementation: Getting Started

All six patterns in the repository are implemented in plain Java with no framework dependencies. This makes them ideal for:

  • Educational purposes: Understanding secure design principles
  • Reference implementations: Adapting patterns to your language and framework
  • Prototyping: Quickly testing security architectures
  • Code reviews: Having examples of secure patterns for comparison

Repository Structure

secure-design-patterns/
├── SecureFactory/
│   └── src/
│       └── org/secureFactoryExample/
├── SecureBuilderFactory/
│   └── src/
├── SecureStrategyFactory/
│   └── src/
├── SecureChainOfResponsibility/
│   └── src/
├── SecureStateMachine/
│   └── src/
└── SecureVisitor/
    └── src/

Running the Examples

Each pattern can be compiled and run independently:

# Navigate to a pattern directory
cd SecureChainOfResponsibility

# Compile the source files
javac -d out $(find src -name "*.java")

# Run the main class
java -cp out Main

Example Output: Chain of Responsibility

[LOG] Request received from user: alice
[AUTH] Authenticating user: alice
[AUTH] User authenticated successfully
[AUTHZ] Checking authorization for operation: readData
[AUTHZ] User authorized for operation
[HANDLER] Processing request for authorized user

Academic and Industry Foundation

The patterns implemented in this repository are grounded in both academic research and industry best practices:

Academic Research

  1. Software Engineering Institute (CMU) - Dougherty, Sayre, and Seacord’s comprehensive report on “Secure Design Patterns” (2009) catalogs patterns at architecture, design, and implementation levels. Their research demonstrates that using patterns reduces both development costs and post-deployment security risks.

  2. Michigan State University - Wassermann and Cheng’s work on “Security Patterns” shows how UML-based security patterns can be formally verified and integrated into existing software development processes.

  3. Pattern-Based Security Methodology - Research published in IARIA conferences demonstrates how UML diagrams combined with security patterns provide a semi-formal approach to secure system design that is both practical and verifiable.

Industry Standards

The patterns align with established security principles:

  • OWASP Secure Coding Practices: Particularly principle of “Defense in Depth” (Chain of Responsibility) and “Fail Securely” (State Machine)
  • NIST Cybersecurity Framework: Supporting the “Protect” function through secure-by-design architectures
  • ISO/IEC 27034: Application Security standard emphasizing security controls integrated into design

Why These Patterns Matter

1. Prevention Over Detection

By designing security into your architecture, you prevent entire classes of vulnerabilities rather than trying to catch them through testing or monitoring. As the Software Engineering Institute notes, secure design patterns “eliminate the accidental insertion of vulnerabilities into code” (Dougherty et al., 2009).

2. Clarity and Maintainability

When security is part of the design pattern, it’s immediately clear to all developers:

  • Where security controls are enforced
  • What the security requirements are
  • How to extend the system securely

3. Scalability

These patterns scale naturally as applications grow. Unlike ad-hoc security measures that become unwieldy in large codebases, pattern-based security maintains its structure and effectiveness.

4. Communication and Documentation

Patterns provide a common vocabulary for discussing security architecture. Rather than lengthy prose descriptions, teams can reference well-known patterns with understood security properties.

5. Testability

Security logic encapsulated in patterns can be unit tested independently from business logic. The Chain of Responsibility, for example, allows each handler to be tested in isolation.

Educational Value

This repository serves multiple educational purposes:

For Students

  • Concrete examples of secure coding principles
  • Runnable code that can be experimented with
  • Progressive complexity from simple (Secure Factory) to complex (Secure Visitor)

For Professional Developers

  • Reference implementations for code reviews
  • Starting points for secure refactoring
  • Patterns to discuss in architecture review sessions

For Security Professionals

  • Examples of security-by-design thinking
  • Patterns that align with security frameworks
  • Teaching tools for security training programs

Extending the Patterns

Each pattern in the repository includes extension suggestions. For example:

Secure Factory: Add credential caching, implement password policies, integrate with identity providers

Chain of Responsibility: Add rate limiting handlers, implement circuit breakers, create audit logging

State Machine: Model complex approval workflows, implement timeout transitions, add compensation states

Visitor: Implement content redaction, create permission inheritance, add temporal access control

Real-World Applications

These patterns aren’t just academic exercises—they appear throughout production systems:

Enterprise Applications

  • Spring Security uses Chain of Responsibility for filter chains
  • Hibernate uses Visitor for query parsing and optimization
  • Apache Shiro uses Factory patterns for security managers

Cloud Platforms

  • AWS IAM uses State Machines for permission evaluation
  • Azure’s resource providers use Factory patterns with authentication
  • Google Cloud’s IAM uses Visitor-like patterns for policy evaluation

Financial Systems

  • Payment processors use State Machines for transaction lifecycles
  • Banking systems use Chain of Responsibility for fraud detection
  • Trading platforms use Strategy patterns for authentication methods

Performance Considerations

Secure design patterns do introduce some overhead, but this is typically negligible compared to their security benefits:

  • Factory patterns: Single additional credential check per object creation
  • Chain of Responsibility: Linear overhead proportional to chain length
  • State Machines: Constant-time state transition validation
  • Visitor patterns: Additional indirection through double-dispatch

In performance-critical paths, consider:

  • Caching authentication results
  • Optimizing chain handler order (fail-fast)
  • Pre-compiling state transition tables

Common Pitfalls and How to Avoid Them

1. Over-Engineering

Problem: Applying patterns where simple solutions suffice Solution: Use patterns when you have multiple security operations or complex state management needs

2. Incomplete Implementation

Problem: Implementing the pattern structure but skipping security checks Solution: Include security checks in code reviews and security testing

3. Tight Coupling

Problem: Concrete implementations depend on specific credential types Solution: Use interfaces for credentials and security contexts

4. State Explosion

Problem: State machines with too many states become unmanageable Solution: Use hierarchical state machines or composite patterns

Future Directions

This repository continues to evolve. Planned additions include:

Additional Patterns

  • Secure Proxy: Access control and monitoring for remote objects
  • Secure Decorator: Adding security features to existing objects
  • Secure Template Method: Security-aware algorithm skeletons

Expanded Languages

  • Python implementations for data science applications
  • Go implementations for microservices
  • Rust implementations emphasizing compile-time security

Integration Examples

  • Spring Framework integration
  • Jakarta EE security integration
  • Microservices patterns with OAuth2

Formal Verification

  • Model checking for state machines
  • Property-based testing examples
  • Security protocol verification

Conclusion: Security as a First-Class Concern

The fundamental lesson of secure design patterns is that security cannot be an afterthought. By treating security as a first-class design concern—on par with performance, maintainability, and scalability—we can build systems that are secure by construction.

The patterns in this repository demonstrate that secure design doesn’t require sacrificing code quality or developer productivity. Instead, it provides structure, clarity, and confidence that security requirements are consistently enforced.

Whether you’re designing a new system or refactoring an existing one, these patterns offer proven approaches to common security challenges. They embody decades of collective wisdom from both academic research and industry practice, condensed into runnable examples that you can experiment with, learn from, and adapt to your needs.

Getting Involved

The repository is open source and welcomes contributions:

  • Try the examples: Clone the repository and run the patterns
  • Provide feedback: Open issues for bugs or suggestions
  • Contribute patterns: Add new secure patterns or language implementations
  • Share experiences: Discuss real-world applications of these patterns

Visit the repository at github.com/dschulmeist/secure-design-patterns


References and Further Reading

Primary Sources

Dougherty, C., Sayre, K., Seacord, R. C., Svoboda, D., & Togashi, K. (2009). Secure Design Patterns. Software Engineering Institute, Carnegie Mellon University. Technical Report CMU/SEI-2009-TR-010. Available at: https://resources.sei.cmu.edu/library/asset-view.cfm?assetid=9115

Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.

Wassermann, R., & Cheng, B. H. C. (2007). Security Patterns. Michigan State University Technical Report MSU-CSE-03-23.

UML and Design Pattern Resources

UML State Machines: https://www.uml-diagrams.org/state-machine-diagrams.html

Factory Method Pattern: https://en.wikipedia.org/wiki/Factory_method_pattern

Chain of Responsibility Pattern: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

Visitor Pattern: https://en.wikipedia.org/wiki/Visitor_pattern

Refactoring Guru - Design Patterns: https://refactoring.guru/design-patterns

Security Standards and Frameworks

OWASP Secure Coding Practices: https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/

NIST Cybersecurity Framework: https://www.nist.gov/cyberframework

Software Engineering Institute - Secure Design: https://www.sei.cmu.edu/our-work/secure-design/

Academic Papers

Bajaj, M., & Ramachandran, S. (2015). “Representing Security Specifications in UML State Machine Diagrams.” Procedia Computer Science, 57, 1150-1158.

Fernandez, E. B., & Pan, R. (2001). “A Pattern Language for Security Models.” PLoP Conference Proceedings.

Schumacher, M., Fernandez-Buglioni, E., Hybertson, D., Buschmann, F., & Sommerlad, P. (2006). Security Patterns: Integrating Security and Systems Engineering. Wiley.

Educational Resources

Sparx Systems UML Tutorials: https://sparxsystems.com/resources/tutorials/uml2/

Visual Paradigm Design Pattern Tutorials: https://www.visual-paradigm.com/tutorials/

GeeksforGeeks System Design: https://www.geeksforgeeks.org/system-design/


Last updated: January 2024

Questions or suggestions? Open an issue on GitHub or reach out to discuss how you’re applying these patterns in your projects!