# Kafka Data Sharing Is a Boundary Decision

Say a logistics partner asks for your `orders` stream. They want the events as they happen, and they want them without seeing the rest of your cluster.

Every way of sharing Kafka data answers two questions. The first is what the partner's software speaks: files, HTTP or the Kafka protocol. The second is where the boundary between your platform and theirs sits: at your brokers, at a second cluster, at a cloud provider's network, or at a proxy in front of your cluster. The tools follow from those two answers.

## Seven ways to share a Kafka topic, compared

The approaches, the tools that implement them, and what each one gives the partner:

| Approach | Example tools | Partner connects with | Extra copies of the data | Partner sees your topic names | Per-partner rate limits | Field masking before data leaves |
|---|---|---|---|---|---|---|
| File export | Kafka Connect sink to object storage or SFTP | Files | One per export | No | Not applicable | In the export job |
| HTTP API | [Confluent REST Proxy](https://docs.confluent.io/platform/current/kafka-rest/index.html), [Strimzi HTTP Bridge](https://strimzi.io/docs/bridge/latest/), your own service | HTTP | None | Depends on the API | In your API layer | In your service |
| Direct access | Kafka [ACLs](https://www.conduktor.io/glossary/kafka-acls-and-authorization-patterns) and [quotas](https://www.conduktor.io/glossary/quotas-and-rate-limiting-in-kafka) on your cluster | Kafka client, to your brokers | None | Yes | Kafka client quotas | No |
| Replica cluster | [MirrorMaker 2](https://www.conduktor.io/glossary/kafka-mirrormaker-2-for-cross-cluster-replication) to a dedicated sharing cluster | Kafka client, to the replica | One per replica cluster | Prefixed with the source alias by default | Quotas on the replica | In a separate processing job |
| Cross-organization replication | [Confluent Cluster Linking](https://docs.confluent.io/cloud/current/multi-cloud/cluster-linking/index.html) | Kafka client, to their own Confluent cluster | One, in the partner's cluster | Yes | On their cluster | No |
| Cross-account private network | [Amazon MSK multi-VPC private connectivity](https://docs.aws.amazon.com/msk/latest/developerguide/aws-access-mult-vpc.html) | Kafka client, from their AWS account | None | Yes | Kafka client quotas | No |
| Kafka proxy, open source | [Kroxylicious](https://kroxylicious.io/) | Kafka client, to the proxy | None | — | — | — |
| Kafka proxy, commercial | [Conduktor Gateway](https://docs.conduktor.io/guide/conduktor-concepts/partner-zones) Partner Zones | Kafka client, to the proxy | None | No, partners see aliases you choose | Produce, consume and commit rates, per Gateway node | Masking Interceptor scoped to the partner |

The three `—` cells for Kroxylicious depend on which filters you deploy and configure. Check its filter documentation for your version before relying on any of them.

The first two approaches take the partner off the Kafka protocol. The other five keep the partner on a Kafka client and differ in where the boundary sits:

Direct access puts the boundary at your brokers. A replica cluster moves it to a copy. A proxy moves it in front of the brokers, with one copy of the data.

## Files and HTTP fit partners that don't run Kafka

Many partners can't consume from Kafka at all. A finance team, a SaaS tool or a smaller company often accepts files or calls an HTTP endpoint, and nothing else. For them, a Kafka Connect sink that writes to object storage or SFTP, or an HTTP layer such as Confluent REST Proxy or the Strimzi HTTP Bridge, is the right answer.

Both approaches change the delivery model. A file export arrives in batches, so the partner works with data that's as old as the last export run. An HTTP layer can stay close to real time, but every consumer feature Kafka gives a client (ordered partitions, committed offsets, replay from a position) has to be rebuilt or approximated in the API. Data providers often run both, depending on what each customer can take:

> *"We have different ways of streaming data to a customer, whether it be Kafka topics, … files, streaming it to a big data warehouse."*
> — CEO at a data provider

## Direct access makes your cluster the partner's contract

The simplest Kafka-native option is a principal for the partner on your own cluster. Kafka's [ACLs](https://www.conduktor.io/glossary/kafka-acls-and-authorization-patterns) decide which topics and consumer groups that principal can use, and Kafka's client quotas cap how many bytes per second it can produce or fetch. Kafka filters the topic list a client receives down to what its principal is allowed to describe, so the partner doesn't see unrelated topic names.

Granting a partner read access to one topic, a prefix for its consumer groups, and a fetch quota takes three commands:

```bash
kafka-acls.sh --bootstrap-server broker:9092 --command-config admin.properties \
  --add --allow-principal User:partner-a --operation Read --topic orders

kafka-acls.sh --bootstrap-server broker:9092 --command-config admin.properties \
  --add --allow-principal User:partner-a --operation Read \
  --group partner-a- --resource-pattern-type prefixed

kafka-configs.sh --bootstrap-server broker:9092 --command-config admin.properties \
  --alter --entity-type users --entity-name partner-a \
  --add-config 'consumer_byte_rate=1048576'
```

Three properties of your cluster still reach the partner:

- **Your topic names.** The partner reads `orders` under its internal name, so renaming the topic later breaks the partner's consumer.
- **Your broker addresses.** A Kafka client connects to every broker that leads a partition it reads, using each broker's `advertised.listeners` address, so every broker must be reachable from the partner's network.
- **Every field in the record.** Kafka has no read-time field filter. If the partner may only see some fields, someone runs a stream processing job that writes a reduced topic, which is a second copy of the data.

Direct access suits a trusted partner, one or two topics, and a network path you were going to open anyway.

## A replica cluster isolates the partner and adds a copy

The traditional answer to "the partner can't touch production" is a second cluster. MirrorMaker 2 replicates the shared topics into a cluster that sits in a DMZ or a separate account, and the partner connects there. Your production brokers never see the partner's connections, and a misbehaving partner client can only overload the replica.

The costs scale with the number of boundaries you need:

- **A cluster to run per boundary.** Each replica cluster has its own brokers, monitoring, upgrades and on-call. If partners must not see each other's topics, the count grows with each partner, unless you rely on ACLs inside the shared replica, which brings back the direct-access tradeoffs.
- **Topic names change by default.** MirrorMaker 2's default replication policy prefixes each replicated topic with the source cluster alias, so `orders` becomes `source.orders` unless you configure the identity policy.
- **Offsets differ between clusters.** A partner that reads from the replica and later moves to another cluster can't reuse its committed offsets as they are. We cover offset translation in detail in [Kafka migration tools](https://www.conduktor.io/blog/kafka-migration-tools).
- **Masking still needs its own job.** The replica receives whatever the source topic holds. Removing fields before they leave means a processing step in the pipeline.

## Provider-native sharing works when both sides use the same provider

Two managed services offer their own paths, and both are strong when the partner is on the same platform.

- **Confluent Cluster Linking across organizations.** Cluster Linking creates read-only mirror topics on a destination Confluent cluster, with byte-for-byte copies and the same offsets as the source. When the partner runs its own Confluent cluster, the data lands in their environment and they operate their side. The partner needs a Confluent destination, and the copy lives in their cluster under your topic names.
- **Amazon MSK multi-VPC private connectivity.** Clients in other AWS accounts reach an MSK provisioned cluster over private connectivity, with a cluster policy granting the partner's account access. No data is copied. The partner connects to your cluster, so the direct-access properties apply: your topic names, Kafka ACLs and quotas, and no field filtering.

Neither path helps when the partner runs on another provider, on premises, or in a different cloud.

## A proxy keeps one copy and moves the boundary into the protocol

A Kafka proxy is a server that speaks the Kafka protocol on both sides: clients connect to it as if it were a cluster, and it forwards their requests to your brokers. Because it rewrites the metadata it returns, the partner's client only ever learns the proxy's addresses, so your brokers don't need to be reachable from outside. Because it reads each request, it can rename topics, restrict what a client sees, throttle it and transform records on their way out.

That gives the partner a cluster of its own without a second copy of the data. [Kroxylicious](https://kroxylicious.io/) is the open-source option: a proxy framework where behaviour comes from filters you deploy. A commercial proxy packages the partner-facing parts as a managed object.

[Conduktor Gateway](https://www.conduktor.io/gateway) does this with Partner Zones, created from Console or the Conduktor CLI. Each zone is a virtual cluster on Gateway with its own bootstrap endpoint and credentials (PLAIN, OAuth or mTLS). You pick the topics, set read or write per topic, and choose the name the partner sees, so `team-alpha.payments.raw-v3` can appear as `payments`. Traffic control policies cap the partner's produce and consume rates per Gateway node, and Console shows each zone's ingress and egress traffic. Gateway's data masking Interceptor can be scoped to the zone's virtual cluster, so masked fields never reach the partner's client.

> **Prerequisites.** Partner Zones need Console 1.37.0 or later and Gateway 3.12.0 or later, with Gateway managing authentication (`GATEWAY_SECURITY_MODE` set to `GATEWAY_MANAGED`). The full setup is in the [Partner Zones guide](https://docs.conduktor.io/guide/use-cases/third-party-data).

## What none of these approaches handle for you

Every option above moves bytes and controls access. The parts of a data-sharing agreement that sit around the bytes stay with your team:

- **The schema contract.** A partner reading Avro or Protobuf needs the schemas, and a breaking change on your side breaks their consumer. Decide whether they read from your [Schema Registry](https://www.conduktor.io/glossary/schema-registry-and-schema-management), receive a copy, or get JSON.
- **Revocation timing.** Removing an ACL or deleting a principal takes effect for new requests, but a partner keeps whatever it already consumed. With Partner Zones, local service account credentials can't be revoked before their time-to-live expires; to cut access immediately, you delete the zone and issue a new one.
- **The partner's own operations.** Consumer lag, retries and reprocessing on the partner's side are theirs to run. Agree on retention up front, because a partner that falls behind past your topic's retention loses data.
- **Network egress.** Data leaving your cloud region or account is usually billed by the provider, whichever approach carries it.
- **A proxy is a component to run.** It sits on the data path for partner traffic, so it needs the same sizing, high availability and monitoring as any other part of the platform.

## Matching the approach to the partner

Start from what the partner can run and how many partners you expect:

- **The partner doesn't run Kafka.** Export files or put an HTTP layer in front. Accept that the partner works in batches or through an API that rebuilds part of the consumer model.
- **One trusted partner, one or two topics.** Direct access with ACLs, a group prefix and a quota is the least infrastructure. Plan for your topic names becoming part of the agreement.
- **The partner runs Confluent.** Cluster Linking puts an offset-identical copy in their cluster, and they operate it.
- **Both sides are on AWS and MSK.** Multi-VPC private connectivity avoids opening the cluster to the internet and avoids a copy.
- **Strict isolation and few partners, with an existing replication team.** A MirrorMaker 2 replica cluster keeps partner traffic off production, at the cost of a cluster per boundary.
- **Several partners, internal names that must stay internal, per-partner limits and audit.** A proxy gives each partner its own endpoint over one copy of the data. Kroxylicious if you want to assemble it from filters; [Conduktor Gateway Partner Zones](https://docs.conduktor.io/guide/conduktor-concepts/partner-zones) if you want zones, aliases, rate limits and traffic views managed from Console.

## Frequently asked questions about Kafka data sharing

**Can I share a Kafka topic with an external partner without copying it?**

Yes. Direct access with ACLs, Amazon MSK multi-VPC private connectivity and a Kafka proxy all serve the partner from your existing topic. File exports, replica clusters and Cluster Linking each create a copy.

**Can a partner see other topics on my cluster?**

With Kafka ACLs, the topic list a client receives only contains topics its principal is allowed to describe. A proxy can go further and expose only the topics mapped to that partner, under names you choose.

**How do I rate-limit a partner's Kafka consumers?**

Kafka client quotas cap bytes per second per user or client ID, set with `kafka-configs.sh` and the `consumer_byte_rate` and `producer_byte_rate` settings. A proxy can apply the same kind of limit at its own endpoint.

**How do I hide sensitive fields from a partner?**

Kafka itself delivers whole records. Either run a processing job that writes a reduced topic for the partner, or apply field masking in a proxy as records are consumed.

---

Related: [The Data Sharing Maturity Ladder →](https://www.conduktor.io/blog/the-data-sharing-ladder) · [Kafka Proxy: Beyond ACLs for Governance →](https://www.conduktor.io/blog/kafka-proxy) · [Kafka Migration Tools →](https://www.conduktor.io/blog/kafka-migration-tools)
