4+1 Architecture Views For Security Reviews
A refund times out and two workers may retry it. Follow the same operation through the logical, code, runtime, and deployment views.
By Kevin O'Connor
Last reviewed
A refund request times out. The worker retries it. Somewhere in the system, a payment may already have completed.
The business rule says the customer should receive one refund. A shared library checks an operation ID. Two workers can process the same message. The payment credential is available in more than one deployment. All of those descriptions matter, but putting them on a single diagram makes it difficult to see which assumption is doing the work.
Philippe Kruchten's 4+1 model, published in 1995, separates logical, development, process, and physical views. Scenarios connect those views. I find that separation useful for security reviews because a rule that looks clear in one view can become ambiguous in another.
The logical view: what a refund means
Start with the business objects and permitted state changes. A refund belongs to a transaction and a customer. It has an amount, currency, and approval. A request may be pending, accepted, completed, rejected, or awaiting reconciliation.
For this example, I'd define two rules before discussing implementation. The amount sent for payment must match the approved amount, and retrying an accepted operation must not create another payment. “Refund completed” also needs a precise meaning: the application should have a downstream result that supports that state.
These rules raise a question about an unknown result. If the request times out, the system cannot safely treat it as either completed or never received. It needs a state that preserves the uncertainty while the result is reconciled.
The development view: which code owns the rule
Now find the modules that implement those decisions:
[Refund API] ------> [Refund Policy]
| |
v v
[Refund Repository] <--- [Approval Check]
|
v
[Payment Client]
The drawing is only helpful if these names lead to code. Identify the module that binds approval to the refund arguments, the repository operation that records the request, and the client that calls the payment service.
Then find every caller of the payment client. If a support script or scheduled job can bypass the refund policy module, the business rule has another implementation to review. Sharing a library reduces duplication, but a caller still has to use it correctly.
This is also where dependency ownership becomes practical. A change to the payment client's retry behavior can affect the refund rule even if the refund module itself stays untouched. The team reviewing that dependency needs the scenario in front of it.
The process view: two workers and one request
At runtime, a simple sequence becomes concurrent work:
[Refund Request] --> [Queue] --> [Worker A] --> [Payment Service]
|
+------> [Worker B] --> [Payment Service]
Suppose worker A sends the payment, loses the response, and doesn't acknowledge the queue message. Worker B receives the redelivery. A check that only looks for a local “completed” row may find nothing and send another payment.
The operation identifier has to survive the queue and retry path. The application also needs a way to ask the downstream service about an unknown result, using the semantics that service actually supports. Marking a message processed too early can lose work; marking it too late can permit duplication. The persistence and acknowledgement order deserves an explicit review.
Approval has a lifetime too. If the job waits in the queue, does execution use the approval as it existed at submission, or must it still be valid when the worker runs? Either design needs a deliberate rule. Otherwise the API and worker can make different assumptions about the same request.
This view is where I would put timeouts, concurrent deliveries, worker crashes, and replay. A static module diagram cannot show their ordering by itself.
The physical view: where the authority lives
Map the workers, database, queue, and payment connection onto their deployed locations. Show where the payment credential is available and who can change it. Include maintenance jobs and administrative access.
[Application Account]
Refund API --> Queue --> Workers --> Payment endpoint
| |
+----------+--> Refund database
[Logging Account]
Receives application and worker records
If another workload can read the payment credential, that workload may be able to act outside the refund application's checks. Network access and secret distribution should match the software paths described in the development view.
The separate logging account in this sketch also creates an operational dependency. Decide how workers behave when they cannot deliver logs, and where pending records survive a restart. A line pointing to a logging service says little about whether a particular refund can be reconstructed later.
Use the retry to check the views together
Run the same refund through each description. The logical view requires one payment for one approved operation. The development view identifies the code that enforces that relationship. The process view explains duplicate delivery and unknown results. The physical view shows which workloads can actually reach the payment service with usable credentials.
A useful test set would include an ordinary approved refund, a changed amount, an expired approval, duplicate queue delivery, and a lost payment response. For each one, inspect the final payment state as well as the application record. Two “success” messages from workers don't establish whether the customer was paid once or twice.
Keep those cases with the diagrams and the relevant release. When a retry policy or worker changes, the team can revisit a concrete operation instead of asking whether the architecture still “looks right.” That's the value of the extra views: they make disagreements about the same operation easier to find.
Keep reading
Architecture · 4 min read
Using C4 Diagrams In Security Work
Follow a customer attachment from the browser to storage, using C4 to locate the ownership check and the paths that might bypass it.
Enterprise Architecture · 4 min read
TOGAF And Zachman For Security Architecture
Use contractor access expiry to work through the difference between planning an architecture change and finding gaps in its description.
Email updates
Get new research by email
In-depth notes on AI security, threat research, and practical defensive work.