Claim Check Pattern
The basics
When we’re working in event-driven architecture we have to take care to maintain size-efficient payloads as they move between our micro-services. This is doubly important when we’re working with sensitive data (like PII) and we need to keep that data ring-fenced.
This is where Claim Check saves us. What we’re essentially doing is taking any large or sensitive data and ri~~~~ng-fencing it behind security and authentication. The data will have an identifier and whenever a service requests data for that specific identifier, the Claim Check service can supply that data, thus hydrating models and recording access requests (should the requirement exist).
Example
A user submits their data on an online form. This event can propagate to many downstream subscribers. As the event originator doesn’t know what the downstream subscribers need it sends everything:
From the above, it’s quite clear that a lot of data is being sent to the Event Bus. If we have thousands of users registering we’re putting a lot of load on the event bus, not to mention there’s a lot of protected information that isn’t even required by most of the components.
Before we look at how we’d implement the Claim Check pattern in here, let’s see what the component itself would look like:
Note: This is not a generic implementation of the Claim Check pattern but rather a design suited to the needs of the example.
In this example, we see a service requesting information from the Claim Check service. I’ve added an ambassador to take care of a few things:
Authentication: Each call contains an AuthToken
(consider an API key if you will) which the API can authenticate against. This way we’re doing our diligence in insuring data isn’t share frivolously.
Audit: Each request, whether it succeeds authentication or not, is logged to an audit database, thus giving us a register of processing. Certain regulations might require exactly this when you’re dealing with PII.
Proxy: Finally, the request is forwarded to the ClaimCheckStorage
interface and the response is returned to the requesting service.
Now, to put it all together, things look a bit more like this:
No things are looking a bit busier but in a good way. I’ve thrown in a Command Gateway for good measure, this can be a simple sidecar that speaks to Claim Check for us.
Let’s go through what each Backend component is doing:
Registration Page: Captures the user input and stores it in Claim Check via the Command Gateway**.** It then emits the RegistrationClaim event via our Event Bus**.**
User Verification: Consumes a RegistrationClaim event and requests information via the Command Gateway by passing the ObjectId
and a list that would likely look like ['FirstName', 'LastName', 'DateOfBirth']
. For all intents and purposes, this is all the information required.
Email Verification: Similarly, consumes a RegistrationClaim event and requests ['Email']
from Claim Check and ultimately uses that email to send out a “Please Verify this is your email address” mailer.
Promotions: Same as above but instead of a verification mailer, it could be sending out our newsletter.
Metrics: An interesting one, metrics is simply here to log how many registration events we see. It doesn’t care about the information that is stored in the claim check and thanks to implementing the pattern we reduced our requests for information.
Benefits and trade-offs
The benefits of using this pattern are simple:
Reduced Payload Size: By offloading the large data payload, the amount of data transferred over the network is significantly reduced, leading to improved performance and reduced latency.
Scalability: The storage system can be optimized for handling large data, making it easier to scale and manage the system.
Loose Coupling: The Claim Check pattern promotes loose coupling between services since they only need to agree on the format and handling of the claim check.
Data Integrity: The external storage system can provide data integrity and persistence, reducing the chances of data loss.
It should however be noted that it’s not always necessary or desirable to implement the Claim Check Pattern as it does add a layer of complexity, additional round-trip time to hydrate your required data, and additional maintenance for another storage system.
Overall, the Claim Check pattern is a useful approach for handling large-, or sensitive-, data payloads in distributed systems and can help improve performance and maintainability.