<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by SarahElDah on Medium]]></title>
        <description><![CDATA[Stories by SarahElDah on Medium]]></description>
        <link>https://medium.com/@saraheldahh?source=rss-5ff741804d5b------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*22kplUrHm6qW04sVnt5Rig.png</url>
            <title>Stories by SarahElDah on Medium</title>
            <link>https://medium.com/@saraheldahh?source=rss-5ff741804d5b------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 24 May 2026 12:51:16 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@saraheldahh/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Achieving Reliable Communication in Microservices with Outbox and Inbox Patterns]]></title>
            <link>https://medium.com/@saraheldahh/achieving-reliable-communication-in-microservices-with-outbox-and-inbox-patterns-38a9cb89bf97?source=rss-5ff741804d5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/38a9cb89bf97</guid>
            <category><![CDATA[outbox-pattern]]></category>
            <category><![CDATA[microservice-architecture]]></category>
            <category><![CDATA[inbox-pattern]]></category>
            <category><![CDATA[messaging-broker]]></category>
            <dc:creator><![CDATA[SarahElDah]]></dc:creator>
            <pubDate>Mon, 23 Jun 2025 12:47:13 GMT</pubDate>
            <atom:updated>2025-06-26T08:40:45.558Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_ysIt8puQUW1H4iP_gXFdQ.png" /></figure><p>In the world of microservices, ensuring reliable communication between services can often be more challenging than writing the services themselves. While REST and synchronous APIs might work in simpler systems, they break down as systems scale and failures become inevitable.</p><p>This is where <strong>messaging patterns,</strong> such as the <strong>Outbox and Inbox,</strong> come into play. These two patterns provide a robust foundation for <strong>reliable, asynchronous, and decoupled communication</strong> between microservices.</p><h3>What’s the Problem we are trying to resolve?</h3><p>Before diving into the Inbox and Outbox patterns, it’s important to understand the two key problems they are designed to solve:</p><h4><strong>1. </strong>The Dual-Write Problem &amp; Transactional Inconsistency:</h4><p>Microservices often rely on <strong>event-driven communication</strong> through a message broker (e.g., Kafka, RabbitMQ, etc.). However, coordinating database operations and message publishing within a single atomic transaction is not straightforward. This challenge is commonly known as the <strong>dual-write problem</strong>.</p><p>This leads to scenarios such as:</p><ul><li>A service <strong>commits</strong> changes to its database but <strong>fails to send the message</strong>, leading to data inconsistency.</li><li>A service <strong>successfully sends a message</strong>, but then <strong>crashes before committing its transaction</strong>, causing consumers to act on a message that doesn’t reflect the actual system state.</li></ul><p>This inability to guarantee atomicity also leads to <strong>temporal coupling</strong> between the service and the broker. Let’s consider Service A sending a message to a broker for Service B. If Service B is down, the broker holds the message and delivers it when B becomes available.</p><p>However, if we look closer, temporal coupling exists between Service A and the message broker itself. Here’s why: Service A assumes its message was safely handed off only after it receives an ACK (acknowledgment) from the broker. But if the broker is unavailable, no ACK is sent, and Service A may retry or, worse, fail. Even worse, consider this subtle failure mode:</p><ul><li>The broker receives the message and sends back an ACK.</li><li>Before the ACK reaches Service A, Service A crashes.</li></ul><p>The message ends up sitting in the broker’s queue, ready to be consumed by Service B. But since Service A’s transaction may not have been committed (e.g., updating the database), this leads to <strong>data inconsistency</strong>; <strong>Service B acts on a message that no longer reflects the system’s true state</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/983/1*D86lNEcl5WANoRgj0fYsyA.png" /><figcaption><strong>Failure Scenario: Message Loss Due to Crash Before Broker ACK</strong></figcaption></figure><p>Let’s make this concrete with a <strong>real-world example</strong>:</p><p><em>Imagine an </em><strong><em>e-commerce system</em></strong><em>.</em></p><ul><li>Service A handles order placement, saving customer orders to the database.</li><li>Service B is responsible for inventory management and deducts items from stock when an order is placed.</li></ul><p>Now, suppose a customer places an order. Service A saves the order and sends a message to Service B to update the inventory. However, after the message is sent to the broker (but before the ACK is received), Service A crashes. The order is never committed, but Service B receives the message and deducts stock anyway.</p><p>The result? The product stock is reduced, but there’s no record of the order. This inconsistency is precisely what the <strong>Outbox Pattern</strong> is designed to prevent.</p><h4><strong>2. </strong>Ensuring Exactly-Once Processing and Handling Duplicates:</h4><p>Even when messages are reliably sent, ensuring that consumers process each message <strong>once and only once</strong> is another challenge.</p><p>Without proper safeguards, this can lead to:</p><ul><li><strong>Duplicate messages</strong> if retries are made without idempotency.</li><li><strong>Race conditions</strong>, when multiple workers try to process or send the same message simultaneously.</li></ul><p>These issues are common in distributed systems where <strong>failures, retries, and eventual consistency</strong> are expected. To maintain data integrity, especially on the <strong>consumer side</strong>, we must ensure:</p><ul><li><strong>Idempotent message handling</strong>, so processing the same message twice doesn’t cause unintended side effects.</li><li><strong>Concurrency control</strong>, to avoid multiple workers acting on the same unprocessed message.</li></ul><p>This is the problem the <strong>Inbox Pattern</strong> addresses: by reliably storing and tracking received messages and ensuring they are processed exactly once.</p><h3><strong>Outbox Pattern: Reliable Message Sending</strong></h3><p>The <strong>Outbox Pattern</strong> ensures that both <strong>business data updates</strong> and <strong>outgoing messages</strong> are committed in the <strong>same local transaction</strong>.</p><h4>How It Works:</h4><ol><li>Instead of sending the message directly, the service writes it to an <strong>Outbox table</strong> in its database.</li><li>The business logic and the outbox write happen in <strong>one atomic transaction</strong>.</li><li>A <strong>background process</strong> (or message relay worker) scans the outbox table, <strong>sends the message</strong> to the broker, and marks it as <strong>sent</strong>.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eBggnRTvwjvbrLEPw4alwg.png" /><figcaption>Outbox Pattern Workflow</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KykDzEB6dtwOl5OCTkNv1w.png" /><figcaption>Outbox Pattern Sequence Diagram</figcaption></figure><h4>Why use the Outbox Pattern?</h4><ul><li><strong>Atomicity Guarantee:</strong> Ensures data changes and the outgoing message are stored in the <strong>same transaction</strong>, preventing inconsistencies.</li><li><strong>Reliable Message Delivery: </strong>It makes sure that the message is delivered<strong> at least once</strong>, even in the case of service or broker crashes.</li><li><strong>Resilience:</strong> If the message broker is temporarily down, no data is lost.</li><li><strong>Decoupling:</strong> Services don’t block waiting for acknowledgment from the broker.</li></ul><h3>Inbox Pattern: Reliable Message Processing</h3><p>If Outbox ensures reliable <strong>sending</strong>, the <strong>Inbox Pattern</strong> ensures reliable <strong>receiving and processing</strong> of messages.</p><h4>How It Works:</h4><ol><li>When a service receives a message, it stores it in an <strong>Inbox table</strong>.</li><li>The message is processed in the background, and the result is applied to the business database.</li><li>Once successfully processed, the message is marked as <strong>processed</strong>.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xGdmdylHpGPbkDMbUvM67A.png" /><figcaption>Inbox Pattern Workflow</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VXt0f2VUhlQxs2IfGKLJ5Q.png" /><figcaption>Inbox Pattern Sequence Diagram</figcaption></figure><h4>Why Use the Inbox Pattern?</h4><ul><li>Guarantees <strong>exactly-once processing</strong>, even if the same message is delivered multiple times.</li><li>Handles <strong>crashes and retries</strong> gracefully.</li><li>Ensures <strong>idempotency</strong> by checking for message duplicates using MessageId.</li></ul><h4>Challenges and Key Considerations:</h4><h4>1. Inbox and Outbox Table Cleanup:</h4><p>Periodic cleanup is essential to prevent performance degradation. Messages accumulate in the Inbox and Outbox tables over time. Without regular cleanup, these tables grow large, leading to slower read and write performance, increased storage costs, and potential degradation of the overall system’s responsiveness.</p><p><strong>How to handle it:</strong><br> Implement a background job or scheduled process that:</p><ul><li>Use a scheduled background job to delete or archive successfully sent messages from the Outbox table and successfully processed messages from the Inbox table.</li><li>Consider moving old messages to a log or audit table for traceability.</li></ul><h4>2. Concurrency Control:</h4><p>Use row-level locks to prevent multiple workers from processing the same message from the Outbox table. In distributed systems, various instances of the background worker might try to process the same message simultaneously, leading to race conditions or duplicate events.</p><p><strong>How to handle it:</strong><br> Use row-level locking mechanisms like:<br> SELECT * FROM Outbox WHERE Processed = false FOR UPDATE SKIP LOCKED<br> This ensures:</p><ul><li>Each worker safely picks a unique message.</li><li>No message is processed twice.</li><li>Parallelism is preserved without causing conflicts.</li></ul><h4>3. Atomicity Requirement:</h4><p>The Outbox pattern relies on atomic database transactions to ensure both the state change and the message record are saved together.</p><p><strong>So:</strong></p><ul><li>Use a relational database that supports ACID guarantees.</li></ul><h3>Conclusion</h3><p><strong>Inbox + Outbox = Safe and Reliable Messaging</strong></p><p>In the world of microservices, reliable and decoupled communication is critical. By applying the <strong>Outbox</strong> and <strong>Inbox</strong> patterns:</p><ul><li>You protect your system from <strong>data-message inconsistencies</strong>.</li><li>You handle <strong>failures gracefully</strong> and ensure <strong>exactly-once processing</strong>.</li><li>You enable <strong>event-driven architectures</strong> that are easier to scale and maintain.</li></ul><p>These patterns are <strong>indispensable tools</strong> for solving the <strong>dual-write problem</strong> and building resilient microservices. They ensure that business state and messaging remain <strong>in sync</strong>, even in the face of crashes or retries.</p><p>For more complex workflows that span <strong>multiple services</strong>, you can extend these patterns by combining them with the <strong>Saga pattern</strong>. Sagas provide a mechanism for coordinating distributed transactions using a series of local transactions and <strong>compensating actions</strong> in case of failure, all while relying on the reliable messaging infrastructure established by the Outbox and Inbox patterns.</p><p><strong>References</strong></p><ol><li><a href="https://newsletter.systemdesignclassroom.com/p/every-outbox-needs-an-inbox">Every Outbox Needs an Inbox</a></li><li><a href="https://www.youtube.com/watch?v=5YLpjPmsPCA&amp;t=5s&amp;ab_channel=Confluent">What is the Transactional Outbox Pattern? | Designing Event-Driven Microservices</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=38a9cb89bf97" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Enhancing Web Application Security with HTTP Security Headers]]></title>
            <link>https://medium.com/@saraheldahh/enhancing-web-application-security-with-http-security-headers-d7d35aecbef8?source=rss-5ff741804d5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/d7d35aecbef8</guid>
            <category><![CDATA[website-security]]></category>
            <category><![CDATA[website-security-audit]]></category>
            <category><![CDATA[http-security-headers]]></category>
            <dc:creator><![CDATA[SarahElDah]]></dc:creator>
            <pubDate>Wed, 28 Dec 2022 14:02:42 GMT</pubDate>
            <atom:updated>2023-01-01T18:51:27.459Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mguxkf9IMaMoXeNJ894Jow.jpeg" /></figure><h3><strong>What are HTTP Security Headers?</strong></h3><p>When we visit any website in the browser, the browser sends some request headers to the server and the server responds with HTTP response headers. These headers are used by the client and server to share information as a part of the HTTP protocol.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/742/1*a0AiGIim4Bd0oPDgV6w1Kw.png" /><figcaption>HTTP Security Headers</figcaption></figure><h3><strong>Why are HTTP Security Headers necessary?</strong></h3><p>HTTP security headers are an important aspect of web application security. They allow web developers to specify security policies that their applications should follow when interacting with browsers. By implementing these headers, developers can protect their applications from various security threats such as cross-site scripting (XSS), cross-site request forgery (CSRF), and other types of attacks.</p><h4><strong>Here are the top five HTTP security headers that you should consider implementing in your application:</strong></h4><h4><strong>1. Content-Security-Policy</strong></h4><p>This header allows developers to specify a list of trusted sources for resources such as JavaScript, CSS, and images. By specifying a list of allowed sources, developers can prevent attackers from injecting malicious content into their applications like XSS attacks. The <strong>Content-Security-Policy</strong> header can also be used to specify the number of other security policies, such as preventing the execution of inline JavaScript or disabling the use of eval().</p><p>A basic CSP header to allow only assets from the local origin is :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wxuCoc9usNMkZsu-CQtYug.png" /><figcaption>Basic CPS Header</figcaption></figure><p>Other directives include script-src, style-src, and img-src to specify permitted sources for scripts, CSS stylesheets, and images.</p><h4>2. <strong>Strict-Transport-Security</strong></h4><p>This header tells the browser to only access the site using a secure connection (HTTPS). By setting this header, developers can ensure that their users’ communication with the site is encrypted, protecting it from eavesdropping and man-in-the-middle attacks. This is especially important for sites that handle sensitive information, such as financial or personal data. A typical HSTS header might look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1HWzwgGevFNp4EhNSlr18g.png" /><figcaption>Basic HTSTS Header</figcaption></figure><p>This informs any visiting web browser that the site and all its subdomains use only SSL/TLS communication and that the browser should default to accessing it over HTTPS for the next two years(the max-age value in seconds). The purpose of preloading is to speed up page loads and eliminate the risk of man_in_the_middle(MITM) attacks.</p><h4>3. <strong>X-Frame-Options</strong></h4><p>This header is used to prevent clickjacking attacks by specifying whether the page can be rendered in a frame or iframe. By setting this header to ‘Deny’, developers can prevent their pages from being rendered in a frame on another site.</p><p>A Basic X-Frame-Options header looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/606/1*0lGTOLTZwPb1Hq0q_hPOjQ.png" /><figcaption>Basic X-Frame-Options header</figcaption></figure><p>Other Supported values are sameorigin to only allow loading into iframes with the same origin and allow-from to indicate specific permitted URLs.</p><h4>4. X-Content-Type-Options</h4><p>The <strong>X-Content-Type-Options</strong> HTTP header is used to prevent content type sniffing, a technique that some older browsers use to determine the content type of a file when it is not explicitly specified. By setting this header to <strong>‘nosniff’</strong>, developers can tell the browser to use the specified content type and not try to determine it based on the content of the file.</p><p>This is important because content-type sniffing can allow attackers to bypass security controls and execute malicious content. For example, an attacker might try to upload a file with a content type of <strong>text/plain</strong>, but with malicious JavaScript code in the file. Without the <strong>X-Content-Type-Options</strong> header, the browser might execute the JavaScript code as if it were a legitimate script. By setting the <strong>X-Content-Type-Options </strong>header to <strong>‘nosniff’</strong>, the browser will treat the file as plain text and not execute any malicious code.</p><p>This header has just one directive:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/843/1*Pngf3rw6xcI97Qpf2jRhNg.png" /><figcaption>Basic X-Content-Type-Options Header</figcaption></figure><h4>5. Referrer-Policy</h4><p>This header controls the information that is sent in the <strong>‘Referer’ </strong>header when a user clicks on a link. The <strong>‘Referer’ </strong>header is used to indicate the URL of the page that the user was on before clicking the link. By setting this header, developers can protect the privacy of their users and prevent the leakage of sensitive information.</p><p>Typical usage would be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/639/1*HMPCgJXBCc3N0l7ulvWxZQ.png" /><figcaption>Basic Referrer-Policy Header</figcaption></figure><h4>Configuring HTTP security headers in C#:</h4><p>In this section, we will look at common approaches for configuring HTTP security headers in C#, specifically in ASP.NET and ASP.NET Core applications. We will cover how to set these headers using the Web.config file and middleware, and provide examples of each approach. By the end of this section, you should have a good understanding of how to configure HTTP security headers in C# and how to choose the right approach for your application.</p><ol><li><strong>Using the Web.config file:</strong></li></ol><p>HTTP security headers can be configured in the <strong>Web.config</strong> file of an ASP.NET application. For example, to set the <strong>Content-Security-Policy</strong> header, you can add the following entry to the <strong>&lt;system.webServer&gt;</strong> section:</p><pre>&lt;httpProtocol&gt;<br>  &lt;customHeaders&gt;<br>    &lt;add name=&quot;Header-Name&quot; value=&quot;Header-Value&quot;/&gt;<br>  &lt;/customHeaders&gt;<br>&lt;/httpProtocol&gt;</pre><p>Example:</p><pre>&lt;httpProtocol&gt;<br>  &lt;customHeaders&gt;<br>    &lt;add name=&quot;Content-Security-Policy&quot; value=&quot;default-src &#39;self&#39;; img-src &#39;self&#39; https://example.com;&quot; /&gt;<br>  &lt;/customHeaders&gt;<br>&lt;/httpProtocol&gt;</pre><p>2. <strong>Using middleware:</strong></p><p>HTTP security headers can also be configured using middleware in ASP.NET Core applications.</p><pre>app.Use(async (context, next) =&gt;<br>{<br>    context.Response.Headers.Add(&quot;Header-Name&quot;, &quot;Header-Value&quot;);<br>    await next();<br>});</pre><p><strong>For example</strong>, you can use <strong>Microsoft.AspNetCore.HttpOverrides</strong> package to set the X-Frame-Options header:</p><pre>app.Use(async (context, next) =&gt;<br>{<br>    context.Response.Headers.Add(&quot;X-Frame-Options&quot;, &quot;DENY&quot;);<br>    await next();<br>});</pre><h4>Configuring HTTP security headers at the server level:</h4><p>In this section, we will look at how to configure HTTP security headers at the server level on different platforms, including Apache and Nginx. We will provide examples of how to set these headers in the server configuration files or using the server management tools. By the end of this section, you should have a good understanding of how to configure HTTP security headers at the server level and how to choose the right approach for your server platform.</p><ol><li><strong>Apache:</strong></li></ol><p>In Apache, HTTP security headers can be configured in the ‘<strong>.htaccess’</strong> file or in the server configuration file (e.g. ‘<strong>httpd.conf’</strong>). For example, to set the <strong>Content-Security-Policy</strong> header, you can add the following line to the ‘<strong>.htaccess’</strong> file:</p><pre>Header set Content-Security-Policy &quot;default-src &#39;self&#39;; img-src &#39;self&#39; https://example.com;&quot;</pre><p>2. <strong>Nginx:</strong></p><p>In Nginx, HTTP security headers can be configured in the server configuration file (e.g. ‘<strong>nginx.conf’</strong>). For example, to set the X-Frame-Options header, you can add the following block to the server configuration:</p><pre>server {<br>    ...<br>    add_header X-Frame-Options &quot;DENY&quot;;<br>    ...<br>}</pre><p>These are just a few examples of how HTTP security headers can be configured at the server level. Depending on the specific server and configuration you are using, there may be other approaches available for setting these headers.</p><h3>Recommended Approach</h3><p>In my opinion, it is advisable to use the server configuration approach for setting HTTP security headers. This is because server configurations have the ability to overwrite any other configurations that may be present, providing a stronger and more consistent level of security for the application. Additionally, server configurations are often easier to maintain and can be managed centrally, making it easier to ensure that all necessary security measures are in place.</p><p>In summary, Implementing these HTTP security headers can greatly improve the security of your web application. It is important to regularly review and update your security headers to ensure that your application is properly protected against the latest security threats.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d7d35aecbef8" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>