The End of Gateways?
It usually starts quietly: a new partner needs access, a shop should send orders directly, a mobile app wants real-time inventory visibility. So one more technical control point appears between source and target system.
Then another one. And another one.
With each integration, the same management question gets more urgent: who is now allowed to access what, and how do we make sure this access cannot be abused?
Many teams first answer this with infrastructure: API gateway, ESB, reverse proxy, security appliance, service mesh. Or with the next step: one cluster for production, a second one for preparation, physically separated.
That sounds plausible at first glance. In reality, it is a dangerous misconception.
Who actually decides which domain-level commands a system is allowed to produce — and which ones it is not?
This is exactly where the risk sits: systems can be technically authenticated, located in the right network, and still send commands they should never be allowed to send from a business-process perspective.
For an ERP, this is the key point. Not whether a system is connected, but whether it is allowed to trigger exactly this domain action.
And this is where the real story of this article begins: why physical separation does not solve the concrete problem, why it still exists across two or more chained clusters, and why Apache Pulsar as a gatekeeper for domain integrity makes the decisive difference.
The next security boundary in modern integration architectures is not in front of the message bus.
It is inside the message bus.
Why Legacy Systems Are Not Zero-Trust Systems
Many ERP systems come from a time when integrations were manageable.
There were:
- few producers
- clearly defined interfaces
- controlled batch processes
- internal networks
- implicit trust
As digitalization advances, this changes fundamentally.
Suddenly, integrations emerge with:
- web shops
- mobile apps
- IoT platforms
- partner ecosystems
- third-party systems
- automation platforms
The result is often the same:
More and more systems can speak directly or indirectly with the ERP.
This is where the real security problem begins.
What is often missing is not encryption or authentication.
What is missing is the ability to enforce domain boundaries between producers and core systems.
Message-Level Zero Trust
Zero Trust is often discussed at network or API level. In practice, that usually means: verify identity, assign permissions, secure connections, segment access.
For classic request/response systems this is useful, but in modern integration landscapes it is no longer sufficient. Critical business processes now run through events, commands, streams, queues, and topics.
If business-critical decisions are transported as messages, the trust boundary cannot stop at the HTTP endpoint. Every message must pass the same bar as an API request: who produced it, from which topic it came, which command it contains, whether it matches a domain policy, and whether it is even allowed to reach the target system.
The trust decision therefore shifts from the network to the data stream.
Zero Trust becomes:
Trust nothing. Validate every message.
This approach becomes truly strong only as a combination:
- clear client authentication at the broker
- domain policy enforcement on message content
Neither identity alone nor content alone is enough. It is both together.
A Simple Command Format
Assume a compact, legacy ERP format:
ORD+4711+ACME+1234.56
The first field describes the command.
ORD create order
CUS update customer
STK update stock
CAN cancel order
The format is intentionally simple.
It is representative of many proprietary text formats that are still common in industrial legacy environments.
The key point is:
The command sits at a defined position.
That means it can be extracted and validated against policy.
Topic Structure as a Security Model
Instead of giving all producers access to one shared ERP topic, ingress channels are separated by domain.
persistent://public/raw/shop
persistent://public/raw/crm
persistent://public/raw/warehouse
Each producer gets write rights only for its own ingress channel.
| System | Topic | Allowed Commands |
|---|---|---|
| Shop | raw/shop | ORD |
| CRM | raw/crm | CUS |
| Warehouse | raw/warehouse | STK |
This yields a simple but strong policy:
(raw/shop, ORD) -> PASS
(raw/shop, STK) -> FAIL
(raw/crm, CUS) -> PASS
(raw/crm, CAN) -> FAIL
Topics are not just technical channels.
They are explicit contracts between producers, policies, and target systems.
Apache Pulsar as Gatekeeper
The architecture then looks like this:
Shop
|
v
raw/shop
|
v
Command Filter (Policy Enforcement Point)
|
+--> erp/ingress
|
+--> erp/quarantine
The ERP no longer consumes from raw/shop.
It consumes exclusively from:
persistent://public/erp/ingress
Only one controlled component is allowed to write there.
Producer -> produce to raw/*
Function -> consume raw/*, produce erp/*
ERP -> consume erp/ingress
Pulsar becomes the security boundary — not as a downstream proxy or an additional gateway, but as a broker-controlled integration layer.
The command filter shown here is exactly the policy enforcement point: every message is checked against domain policy before it is forwarded or moved to quarantine.
Pulsar Functions as Policy Enforcement Point
The command filter from the previous section is exactly this Pulsar Function in implementation terms.
A Pulsar Function is a small program executed directly in the data stream: it reads a message from a topic, checks or transforms it according to clear rules, then forwards it deliberately — or blocks it.
In this article, that is exactly what the command filter is: the operational point where policy gets enforced.
If you want a deeper dive: Data hub instead of a hatch: Pulsar Functions in the data stream and Controlling load instead of bending systems: Rate limiting with Apache Pulsar.
A Pulsar Function consumes incoming messages.
It extracts the command:
String command = payload.substring(0, 3);
Then it checks topic and command against policy.
if (allowed(topic, command)) {
forward();
} else {
quarantine();
}
Only approved messages reach the ERP.
raw/*
|
v
Policy Function
|
+--> erp/ingress
|
+--> erp/quarantine
Why We Suddenly No Longer Need a Gateway
The classic setup looks familiar:
[Classic]
Partner systems --> Gateway --> Pulsar --> ERP
The new setup has clearer responsibility:
[New]
Partner systems --> Pulsar --> ERP
|
`--> Policy Enforcement (Pulsar Functions)
The difference is crucial: the classic model mainly controls system access. The Pulsar model additionally controls which domain command is allowed to continue.
| Comparison point | Classic with gateway | Pulsar with policy functions |
|---|---|---|
| Verify technical identity | ✅ | ✅ |
| Enforce domain command rules in-stream | ⚠️ often needs extra custom logic | ✅ directly at the enforcement point |
| Isolate unauthorized messages deliberately | ⚠️ project-specific | ✅ quarantine topic as standard pattern |
| Visibility per source system/command | ⚠️ often post-factum | ✅ via topic structure and metrics |
| Operability with growing integration count | ⚠️ increasing project overhead | ✅ lightweight via standardized functions |
And this is exactly why physical cluster separation is not enough. You could only prevent this by disallowing communication altogether — or by placing a classic gateway in between again. As long as systems communicate, an unauthorized command will still flow cleanly to the target without domain policy checks.
Practical operational advantage: authentication, authorization, encryption, limits, observability, and scalable topic separation remain part of one platform and reinforce each other directly in the data stream, instead of being coordinated across multiple disconnected solutions.
For a long time, the gateway was the place where trust was evaluated.
In event-driven systems, the broker with policy functions is often the more effective place.
As a side note: this principle resembles the NetBSD idea behind kauth/secmodel: policy belongs where decisions can be enforced centrally and consistently.
What This Approach Does Not Solve
Pulsar does not replace every security architecture.
What it does not solve automatically:
- fine-grained user permissions inside ERP
- multi-step business approval flows
- deep master-data and fraud checks
Physical separation of clusters remains useful for operations and isolation, but does not solve the core problem: as long as communication is allowed, every message needs domain policy validation.
For simple rules, a slim function is often enough. For complex decisions, it can delegate in a controlled way to a policy service or rules engine.
In-stream policy enforcement is strong for transport, structure, and clearly defined domain rules.
Complex business decisions remain in versioned domain components.
Conclusion
For many legacy environments, this is the pragmatic way to retrofit Zero Trust: do not rebuild the core system — stop unchecked messages before they get there.
The key lever is Pulsar Functions as policy enforcement points. They are lightweight, standardized, often just a few lines of clear logic, and much easier to operate than classic gateway projects with high yearly maintenance overhead.
This creates a security boundary directly in the data stream: identity, authorization, domain command checks, quarantine, and observability converge in one place.
The outcome is both management-relevant and technically robust: less architectural ballast, clearer responsibility, and a controlled message flow into ERP.
Maybe this really is the end of many classic gateways.
Not because gateways were wrong.
But because policy enforcement in the message bus is the more effective and economical approach for this problem.
Zero Trust does not end at the network.
In modern integration architectures, it starts with every single message.