Chapter 3
Secure Architecture and Engineering Principles
Bachelors Program in Full Stack Development
Web Security & Performance Optimization
•
Bachelor
Secure Architecture and Engineering Principles
Introduction and Context
Secure software is not produced by adding authentication, encryption, or a firewall at the end of development. It is engineered through architectural decisions that reduce attack opportunities, constrain the effects of compromise, preserve service under stress, and make unsafe actions difficult or impossible. For full-stack developers, this means treating security as a property of the whole system: browser, mobile client, APIs, application services, databases, infrastructure, deployment pipeline, identities, and third-party dependencies.
A secure architecture answers five questions:
Who or what is requesting access?
What is the requester allowed to do under the current context?
Which components and data are separated from one another?
What happens when a component fails or is attacked?
How can security decisions be verified throughout the software life cycle?
This chapter develops these answers using Zero Trust, separation of duties, secure design patterns, layered controls, resilience, fail-safe behavior, and security requirements engineering.
Learning Objectives
By the end of this chapter, you should be able to:
explain the principles of secure-by-default architecture;
apply Zero Trust and least privilege to full-stack systems;
identify trust boundaries and use separation of duties;
select suitable secure design patterns and layered controls;
analyse retry amplification, failure modes, and resilience trade-offs;
express security requirements as testable acceptance criteria;
integrate threat modelling and security verification into the SDLC; and
evaluate a secure architecture in a realistic application scenario.
1. Secure-by-Default Thinking
A system is secure by default when its initial configuration provides the safest reasonable behavior without requiring every user or operator to make a correct security decision. Examples include private cloud storage by default, deny-by-default authorization, disabled debug endpoints in production, secure cookie attributes, and encrypted transport as the normal mode.
Security architecture differs from security functionality. A password-reset feature is functionality; isolating the reset process, limiting its privileges, rate-limiting requests, logging decisions, and preventing account enumeration are architectural concerns.
Three complementary properties are useful:
Confidentiality: information is disclosed only to authorized subjects.
Integrity: information and system behavior are protected from unauthorized alteration.
Availability: authorized users can obtain legitimate service when needed.
Security controls can also be classified as preventive, detective, corrective, or compensating. A policy engine is mainly preventive; an audit trail is detective; credential rotation is corrective; manual review may compensate for an incomplete automated control.
Fundamental design principles
Principle
Meaning
Example in a web system
Least privilege
Grant only the permissions needed for a task
A reporting service can read aggregated data but cannot update orders
Fail-safe defaults
Failure should produce the safer state
A failed authorization check denies access
Complete mediation
Check every relevant access, not merely the first one
The API verifies object ownership on every request
Economy of mechanism
Keep security mechanisms small and understandable
A central policy component with documented rules
Least common mechanism
Minimize shared mechanisms and shared state
Separate tenant encryption keys and service accounts
Defense in depth
Use independent layers of protection
WAF, API validation, authorization, database constraints, monitoring
Open design
Do not depend on secrecy of the design
Use standard cryptographic protocols rather than secret algorithms
Secure failure and recovery
Recovery must not bypass controls
A break-glass account is time-limited, approved, and audited
These principles can conflict. For example, extensive logging improves detection but may threaten confidentiality if logs contain tokens or personal data. Engineering requires explicit trade-offs, data minimization, and review.
2. Trust Boundaries and Zero Trust
A trust boundary is a transition across which assumptions about identity, integrity, confidentiality, or administrative control change. Common boundaries occur between a browser and an API, a public network and a private subnet, application services and a database, or a company and a software supplier. A boundary is not necessarily a physical network boundary: a service-to-service call inside one cluster can still cross an identity and privilege boundary.
The Zero Trust model rejects implicit trust based on network location. Its central principle is: verify explicitly, use least privilege, and assume breach. A request should be evaluated using identity, device or workload state, resource, action, context, and policy—not simply the requester’s IP address.
A practical request decision can be represented conceptually as:
This is a logical model rather than a complete implementation. Authentication proves or estimates identity; authorization determines permission; policy conditions may include device posture, time, risk, tenant, network, or transaction value. A false or unavailable decision should normally result in denial for sensitive operations.
Layered web architecture with explicitly drawn trust boundaries and controls spanning every layer
Figure: Layered web architecture with explicitly drawn trust boundaries and controls spanning every layer
Figure: Explicit trust boundaries between architectural layers and controls that span the complete system, rather than only the application layer.
Zero Trust does not mean that every request must be challenged with an interactive login. It means that authorization decisions are continuously and appropriately evaluated. Short-lived tokens, mutual TLS for workloads, audience restrictions, risk-based step-up authentication, and resource-level authorization are common implementations.
3. Separation of Duties and Privilege Boundaries
Separation of duties (SoD) prevents one actor from controlling an entire sensitive process. A developer may create a deployment but not approve it; an operations engineer may execute an approved deployment but not alter the source; a finance employee may prepare a refund but another authorized employee approves it.
SoD reduces fraud, insider abuse, and the impact of compromised credentials. It should be applied to both human and machine identities. Important mechanisms include:
separate production and development accounts;
independent approval for high-risk changes;
protected branches and required peer review;
distinct service identities for distinct services;
database roles separated into read, write, migration, and administration; and
immutable audit records reviewed by an independent role.
SoD can create operational friction. Excessively broad approval requirements encourage workarounds, while excessively narrow separation can make emergency response impossible. A balanced design uses risk-based thresholds, time-limited emergency access, dual control for critical actions, and post-event review.
4. Secure Design Patterns and Layered Controls
A security pattern is a reusable design solution to a recurring security problem. Important patterns for full-stack systems include:
Policy enforcement point: intercepts requests and enforces decisions.
Policy decision point: evaluates identity, resource, action, and context.
Reference monitor: mediates access, is tamper-resistant, and is complete for the protected resource.
Capability-based access: a holder of a narrowly scoped, unforgeable capability receives limited authority.
Input validation and canonicalization: validates structured input after resolving ambiguous representations.
Parameterized queries: separates SQL code from data and reduces injection risk.
Envelope encryption: encrypts data with a data-encryption key, while a key-encryption key protects that key.
Bulkhead isolation: limits failure or resource exhaustion in one component so it does not sink the whole system.
Circuit breaker: temporarily stops calls to an failing dependency after a defined failure threshold, allowing recovery.
Patterns are not magic. A gateway cannot correct an authorization flaw inside an application if the gateway does not understand object ownership. A circuit breaker improves availability but does not make unsafe data acceptable. Every pattern must have an explicit threat model and verification strategy.
Layered controls
A layered architecture may include browser protections, identity controls, network segmentation, API validation, application authorization, database constraints, secrets management, monitoring, and recovery. Layers should be as independent as practical. Repeating the same weak check in three places is less valuable than combining different controls that fail differently.
For example, a transaction may be protected by TLS in transit, schema validation at the API, authorization in the service, a database constraint preventing invalid state, an audit event, and a recovery mechanism. The database constraint is particularly important because it protects against clients or services that bypass the normal user interface.
5. Resilience, Failure Modes, and Retry Amplification
Security and availability are related. A denial-of-service attack exploits resource consumption; a dependency outage can cause unsafe fallback behavior; an overloaded system may skip logging or authorization unless those functions are designed carefully.
Retry mathematics
Suppose a request passes through n sequential layers. At each layer, the initial attempt may be followed by r retries, so the maximum number of attempts made by that layer is:
A = r + 1
where r is the number of retries, excluding the initial attempt. If every layer independently performs this many attempts and every attempt reaches the next layer, the worst-case number of downstream attempts is:
D = (r + 1)n
This is a worst-case upper bound under strong assumptions: all attempts fail, retry schedules overlap sufficiently, no circuit breaker intervenes, and each layer retries the operation independently. It is not a prediction of normal traffic.
Worked example. Four layers each permit two retries. Each layer therefore makes three total attempts. The maximum downstream attempts are:
D = (2 + 1)4 = 34 = 81
Thus one incoming operation can induce up to 81 attempts at the deepest dependency. If the architecture instead has a single retrying layer with two retries, the downstream attempts are only 3, not 81. This distinction is why retry ownership should be explicit.
If layer i has a different retry count rᵢ, the corresponding bound is:
D = ∏(rᵢ + 1), i = 1 to n
The formula assumes every layer’s attempts propagate fully downstream. Timeouts, caching, hedging, partial failures, queueing, and asynchronous work can change actual behavior. Safe practice includes bounded retries, exponential backoff with jitter, idempotency keys, retry budgets, deadlines propagated across calls, and circuit breakers.
Fail-safe behavior
Fail-safe behavior means that an error produces the safer outcome for the protected asset. An authorization service outage should deny a transfer, not silently permit it. However, fail-safe does not mean “always shut down.” For a public catalogue, serving a cached read-only copy may be safer than making the whole site unavailable. The correct fallback depends on asset sensitivity and threat consequences.
A useful decision process is:
identify the protected asset;
list failure states and attacker opportunities;
compare deny, degrade, queue, and recover options;
preserve auditability and user transparency; and
test the selected behavior under fault injection.
6. Security Requirements Across the SDLC
Security requirements should be specific, testable, and traceable. “The system shall be secure” is not testable. A stronger requirement is: “For every order-read request, the service shall verify that the authenticated principal is an authorized member of the order’s tenant before returning order fields.”
Security requirements can be elicited from:
business assets and harm analysis;
legal and regulatory obligations;
abuse cases and threat models;
architectural constraints;
operational experience and incidents; and
privacy and accessibility expectations.
A useful requirement template is:
When [condition], the system shall [security behavior], so that [protected property], verified by [test or evidence].
Examples:
When a user changes a payment instrument, the system shall require reauthentication and record an immutable audit event, verified by integration testing and log review.
The API shall reject requests containing an invalid tenant identifier rather than interpreting it as a default tenant, verified by negative tests.
Production secrets shall be retrieved at runtime from an approved secret store and shall not occur in source control, container images, or build logs, verified by automated scanning.
Security activities by life-cycle stage
Stage
Security activity
Typical evidence
Requirements
Assets, abuse cases, privacy and compliance analysis
Data retention, key destruction, account and endpoint removal
Disposal evidence and closure checklist
Threat modelling methods such as STRIDE help identify spoofing, tampering, repudiation, information disclosure, denial of service, and elevation of privilege. The method is a prompt, not a substitute for domain expertise. Threats should be prioritized using likelihood, impact, exploitability, and affected assets; a numerical score is useful only when its assumptions are documented.
7. Verification and Observability
A secure design must be observable. Logs should record security-relevant events such as authentication failures, privilege changes, policy decisions, administrative actions, and key security configuration changes. Logs should be time-synchronized, protected against unauthorized modification, access-controlled, and minimized to avoid leaking credentials or unnecessary personal data.
Useful engineering measures include:
percentage of critical assets with an owner and threat model;
time to remediate vulnerabilities by severity;
percentage of privileged accounts using phishing-resistant MFA;
rate of failed authorization tests in continuous integration;
recovery time and recovery-point performance; and
frequency of unreviewed emergency access.
Metrics can be gamed. A low vulnerability count may indicate poor scanning rather than good security. Therefore metrics should be combined with independent testing, qualitative review, and incident evidence.
A university learning platform provides course content, assessments, messaging, and payment for professional certificates. It serves many institutions in a shared cloud environment.
Problem
An initial design used one API service account with broad database privileges. Authorization was performed mainly in the web interface, retries were configured independently in the browser, gateway, and service, and a failed policy-service call caused the application to use a permissive cached decision.
Analysis
The design had four major weaknesses:
A malicious client could call APIs directly and attempt cross-tenant object access.
The shared account violated least privilege and weakened accountability.
Independent retries could amplify load during a dependency outage.
Permissive fallback converted an availability problem into a confidentiality and integrity risk.
The data-flow review identified boundaries at the client/API, gateway/service, service/database, and platform/tenant transitions.
Approach and solution
The engineering team introduced:
tenant-aware authorization at the service for every object request;
separate service identities and database roles;
deny-by-default policy evaluation for grading and payment operations;
read-only cached fallback only for low-risk course catalogue data;
a single bounded retry policy with deadlines and idempotency keys;
circuit breaking and queueing for non-interactive notifications;
protected audit logs for administrative and grading events;
mandatory peer approval for production policy changes; and
threat-model and negative-authorization tests in the delivery pipeline.
Outcome
The revised architecture reduced the blast radius of a compromised service, prevented reliance on client-side authorization, and avoided unrestricted retry storms. It also made security decisions explainable through policy records and audit events. Availability for catalogue browsing was preserved during a policy-service outage, while high-risk operations failed closed.
Learning points
Security is not achieved by one product. It emerged from explicit boundaries, narrowly scoped identities, multiple controls, safe failure choices, and continuous evidence. The case also demonstrates that availability decisions must be asset-sensitive: a cached public page and a payment authorization should not have the same fallback policy.
9. Challenges, Ethics, and Contemporary Practice
Challenges and limitations
Zero Trust can increase latency, operational complexity, and dependence on identity infrastructure. Excessive micro-segmentation may become impossible to administer. Strong SoD can delay incident response. Central policy services can become high-value targets and availability dependencies. Encryption protects content but does not eliminate metadata exposure, compromised endpoints, or misuse by authorized identities.
Architects should therefore document assumptions, recovery paths, ownership, and residual risk. Security controls must be usable; otherwise staff may bypass them. Accessibility is also a security concern: inaccessible authentication can force users toward unsafe workarounds.
Governance and ethics
Security monitoring should be proportionate, transparent, and limited to legitimate purposes. Organizations should define retention periods, access to logs, employee monitoring boundaries, breach notification processes, and procedures for correcting inaccurate risk decisions. Automated or AI-assisted risk scoring must be tested for bias, explainability, data minimization, and human appeal. AI coding tools should not receive secrets or sensitive production data, and generated code requires review, testing, and license analysis.
Contemporary practice increasingly uses software supply-chain attestations, signed artifacts, workload identity, phishing-resistant authentication, memory-safe components where suitable, policy-as-code, confidential computing for selected threat models, and continuous authorization. These technologies are valuable only when integrated into governance and verified against actual threats.
Best-Practice Checklist
Define assets, trust boundaries, identities, and security assumptions.
Deny by default and authorize at the resource, action, and tenant level.
Use separate human and machine privileges with auditable ownership.
Apply independent, layered controls rather than repeated weak checks.
Make retries bounded, idempotent, deadline-aware, and centrally owned.
Select fail-open or fail-closed behavior according to asset risk, not convenience.
Keep secrets out of code, logs, images, and client-side bundles.
Test negative paths, dependency failure, privilege escalation, and recovery.
Maintain traceability from requirements to design, code, tests, and operations.
Review residual risk and update the threat model as the system changes.
Chapter Summary
Secure architecture is a system-wide discipline grounded in least privilege, complete mediation, defense in depth, separation of duties, and fail-safe defaults. Zero Trust replaces implicit network trust with explicit, contextual decisions for each resource and action. Trust boundaries must be identified and protected even when components share a physical network. Secure patterns such as policy enforcement points, reference monitors, parameterized queries, bulkheads, circuit breakers, and envelope encryption address recurring risks but require suitable threat models and testing.
Resilience must not undermine security. If each of n layers performs r retries in addition to its initial attempt, the worst-case downstream attempt count is (r + 1)n, subject to stated assumptions—not rn. Requirements engineering, threat modelling, secure implementation, verification, release controls, monitoring, and retirement form a continuous security life cycle. The illustrative learning platform showed how tenant authorization, privilege separation, bounded retries, and asset-sensitive fallback can jointly reduce risk while preserving useful availability.
Key Terms
Zero Trust: A security model that requires explicit, contextual verification rather than implicit trust based on network location.
Trust boundary: A transition where assumptions about identity, control, integrity, or confidentiality change.
Least privilege: Granting only the permissions necessary for a task.
Fail-safe default: A default behavior that protects the asset when a control or component fails.
Complete mediation: Checking access on every relevant operation.
Defense in depth: Using multiple, preferably independent, protective layers.
Separation of duties: Dividing sensitive responsibilities among distinct people or identities.
Reference monitor: A complete, tamper-resistant mechanism that mediates access to a resource.
Policy decision point: A component that evaluates a request against policy.
Policy enforcement point: A component that intercepts and enforces the decision.
Bulkhead: Isolation that limits failure or resource exhaustion to one component.
Circuit breaker: A control that temporarily stops calls to an failing dependency.
Idempotency: The property that repeating an operation has the same intended effect as performing it once.
Retry amplification: Growth in downstream attempts caused by independent retries across layers.
Threat modelling: Structured identification and analysis of threats, assets, and mitigations.
Abuse case: A description of how a system may be intentionally misused.
Security requirement: A testable statement specifying a protection or security behavior.
Blast radius: The extent of harm resulting from a compromise or failure.
Policy as code: Machine-readable policy maintained, reviewed, and tested like software.
Review Questions
Short Answer Questions
What is the difference between authentication and authorization?
Define a trust boundary and give two examples in a web application.
Why is separation of duties useful for production deployment?
What does fail-safe default mean?
Why should authorization be enforced at the service rather than only in the user interface?
Long Answer Questions
Explain Zero Trust and analyse how it changes the design of a service-to-service architecture.
Compare preventive, detective, corrective, and compensating controls with suitable examples.
Explain how security requirements should be developed and verified across the SDLC.
Discuss the benefits and limitations of defense in depth.
Describe how a secure architecture should handle a dependency outage affecting authorization.
Analytical / Application Questions
A system has five sequential layers, each allowing three retries after the initial attempt. Calculate the worst-case downstream attempts under the independent-retry assumptions, and recommend two mitigations.
Design an authorization and separation-of-duties model for a multi-tenant assessment platform. Identify its trust boundaries and failure-safe choices.
A public catalogue and a payment service share an unavailable policy engine. Propose different fallback behaviors and justify them using confidentiality, integrity, and availability considerations.
Multiple Choice Questions with Answers
Question 1
A layer allows two retries after its initial attempt. How many total attempts can that layer make?
A. 1
B. 2
C. 3
D. 4
Correct Answer: C. 3
Question 2
Four sequential layers each allow two retries after the initial attempt. Under the stated worst-case independent-retry assumptions, what is the maximum number of deepest downstream attempts?
A. 16
B. 24
C. 64
D. 81
Correct Answer: D. 81
Question 3
Which statement best expresses Zero Trust?
A. Internal network traffic is trusted automatically
B. Every request is evaluated using explicit identity, authorization, and context
C. Only external users require authentication
D. A firewall removes the need for application authorization
Correct Answer: B. Every request is evaluated using explicit identity, authorization, and context
Question 4
Which control is an example of separation of duties?
A. One administrator writes and approves every production change
B. A developer approves their own deployment without review
C. One employee prepares a refund and another approves it
D. All services use one shared administrative account
Correct Answer: C. One employee prepares a refund and another approves it
Question 5
What is the safest default for a failed authorization decision on a payment transfer?
A. Permit the transfer
B. Retry indefinitely
C. Deny the transfer and record the event
D. Use an anonymous account
Correct Answer: C. Deny the transfer and record the event
Question 6
Which pattern separates SQL instructions from user-supplied values?
A. Parameterized queries
B. Shared administrative credentials
C. Client-side hiding of fields
D. Unbounded retries
Correct Answer: A. Parameterized queries
Question 7
Which condition is required for the retry-amplification bound ∏(rᵢ + 1) to apply?
A. Only the first layer retries
B. Every layer's attempts propagate fully to the downstream dependency
C. All requests are successful
D. No layer performs an initial attempt
Correct Answer: B. Every layer's attempts propagate fully to the downstream dependency
Question 8
Which security activity is most appropriate during architectural design?
A. Threat modelling and trust-boundary analysis
B. Deleting audit logs
C. Disabling code review
D. Publishing production secrets
Correct Answer: A. Threat modelling and trust-boundary analysis
Question 9
What is the primary purpose of a circuit breaker?
A. To increase unlimited request repetition
B. To encrypt database records
C. To temporarily stop calls to a failing dependency
D. To replace authorization checks
Correct Answer: C. To temporarily stop calls to a failing dependency
Question 10
Which is the strongest security requirement?
A. The system should be secure
B. Users should be protected somehow
C. The API shall verify tenant ownership before returning an order, verified by negative integration tests
D. Developers should use best practices
Correct Answer: C. The API shall verify tenant ownership before returning an order, verified by negative integration tests
Web Security & Performance Optimization
Chapter 3
of 15