The instinct when several internal systems overlap is to merge them. It is usually wrong, and the reason is not sentimental.
Why merging destroys value here#
Products that serve different audiences differ in ways that look like duplication and are not.
A tool for developers and a tool for non-technical small-business owners both send WhatsApp messages. Merging them produces one product that is too complicated for the second audience and too constrained for the first. The "duplication" was the adaptation.
The general form: when two systems share a mechanism but not a user, the mechanism is the accident and the user is the essence. Consolidating on the mechanism throws away the essence.
What federation actually requires#
Four things, in this order.
1. Published contracts, not shared code. Each system exposes a documented interface — an OpenAPI description, an event schema — and consumes others' interfaces. Shared libraries create a coupling that has all the costs of a merge and none of the benefits, because now nobody can deploy independently.
2. Consistent identity. This is the hard one, and the one most federations skip. Systems calling each other need to prove who they are and on whose behalf they act, with an audit trail and a revocation path. Without it you get shared secrets in configuration files, which is a merge by other means.
3. Consistent conventions, not a shared database. Agree on how a contact is identified, how timestamps are formatted, how errors are shaped. Do not agree on one schema — that is a merge wearing a different hat.
4. One direction of authority per fact. For every piece of data, exactly one system is the source of truth, and the others hold caches that are explicitly stale. Two systems that both believe they own consent state will diverge, and the divergence will be discovered by a regulator.
What each system publishes, bottom to top
- Its own data
Never shared wholesale. Ownership stays where the system is operated and accountable.
- A stable identity
Something another system can refer to without knowing how it is stored internally.
- A published contract
The interface, versioned, with a deprecation policy. This is the only coupling that exists.
- An identity bridge
How a subject in one system corresponds to a subject in another, and who may assert it.
- Delegated authority
A scoped, revocable, time-bound grant. One system acting for another, with proof.
- Shared evidence
The audit trail spanning the boundary, so a question can be answered across it.
The delegation pattern#
The most useful shape is often for the system with the best interface to delegate rather than duplicate.
If one product has issued credentials, a published specification and a signed webhook dispatcher, while another has the strongest domain model, the answer is not to move code between them. It is for the first to keep its edge and call the second, rather than reimplementing what the second already does well.
Nothing moves. Both keep their audiences. The capability becomes available through the interface that was already designed to be called.
One system acting for another, safely
- 01Establish the identity
Each system has a verifiable identity of its own. Not a shared secret, not an API key in a config file.
- 02Request a scoped grant
Narrow: this action, this subject, this window. A grant that is broad because narrow was inconvenient is the vulnerability.
- 03Issue with an expiry
Short-lived and renewable beats long-lived and forgotten. The expiry is the safety property.
- 04Act, and carry the proof
Every action taken under delegation records which grant authorised it.
- 05Revoke independently
One system withdrawing a grant must not require the other's cooperation, or it is not revocation.
What federation costs#
It is not free, and the costs are real:
- Network calls where a function call would have done, with the latency and failure modes that implies.
- Versioning discipline. A published contract you can change unilaterally is not a contract.
- Duplicated read models. Each system holds a projection of others' data, and projections drift.
The trade is deliberate: you accept operational complexity to keep product independence. That is worth it exactly when the products serve different people, and not otherwise.
The test#
Before merging two systems, ask: do they have the same user?
Not the same buyer. Not the same organisation. The same person, doing the same job, on the same day.
If yes, merge — the separation is costing you. If no, federate, and stop measuring the duplication as though it were waste.
What to take away#
Publish contracts, bridge identity, delegate with scoped and revocable grants, and share evidence across the boundary. Keep the data where it is accountable. Accept the duplication as the price of independent failure, and check the shutdown test honestly rather than aspirationally.