Security & deployment
Most questions about Data Sync security reduce to one question: what leaves your network, and where does it go? This page answers that precisely, then works outwards to deployment models, runners, credentials, network access and access control.
Where your data goes
Rows travel source → runner → sink. They do not pass through Blunox's control plane, and there is no path by which they could — the control plane never receives a row payload.
What the control plane does hold is the metadata needed to schedule work and recover from failure:
| Stored in the control plane | Not stored in the control plane |
|---|---|
| Sync definitions — connections referenced, tables selected, mappings, replication mode | Row values, in any form |
| Checkpoints — the last durably written source log position per sync | Column contents, samples, or previews |
| Run history — run number, type, start and end, duration, event and byte counts, status | Credential values, for any provider |
| Schema names — table and column names and their types | Anything read during a dry run |
| Operational metrics — lag, throughput, partition progress | Row data in log lines; log attributes carry metadata only |
Two consequences are worth stating plainly. A table called customers with a column called ssn means the strings customers and ssn are stored by Blunox — the names are metadata and metadata is stored. And a dry run, which samples real rows and shows you the transformed output, streams those rows and discards them; nothing sampled is written to the sink or persisted anywhere.
Deployment models
The split between row data and metadata is what gives you three deployment options rather than one.
| Model | Who runs the runners | Where credentials live | Where the control plane runs |
|---|---|---|---|
| Managed | Blunox | Blunox credential store, or your own | Blunox |
| BYOC | You, in your cloud account | Your own secret store | Blunox |
| Air-gapped | You | Yours | Yours |
Managed. Blunox operates the runner fleet. You create connections in the console, credentials are held encrypted in the Blunox credential store and unwrapped per use, and there is nothing to install. Your source and sink must be reachable from Blunox's network, which is what the static egress IPs and Private Service Connect described below are for.
BYOC. The same runner binary runs inside your own cloud account, next to your data. It reads credentials from your secret store and opens a single outbound WSS connection on TCP 443 to the Blunox control plane. Rows never leave your network — they go from your source, through your runner, into your sink, all inside your perimeter. The control plane still holds sync definitions, checkpoints and schema names. Terraform modules exist for deploying the BYOC runner.
Air-gapped. You operate the entire installation, control plane included. Nothing crosses your perimeter, including metadata. This is the option when checkpoints and schema names are themselves in scope for your data-residency or classification rules.
Runners
A runner is the execution host: the process that reads your source, applies mappings and writes your sink. It is the only component that ever touches a row.
A BYOC runner is egress-only. It holds one long-lived outbound connection on TCP 443, secured with TLS, with a 15-second heartbeat. There is no inbound path, no public IP, and no listening port for anything to reach. It has no database of its own — all durable state lives in the control plane, which is why a dead runner's work can be re-dispatched to a different one without loss.
You do not open a firewall hole to install a runner. If your egress policy already permits outbound 443, there is nothing further to configure on the network side.
The Runners page lists each runner’s mode (byoc or managed), declared capabilities, health, version and status, and is where you rotate a runner’s secret or revoke it.
Capabilities and environment binding. When you create a runner you give it a name, an environment to bind to, a mode, and the set of capabilities it may serve — values like pulse.cdc.postgres, pulse.cdc.mysql, pulse.cdc.sqlserver, pulse.cdc.mongodb or mira.pushdown. Work is only dispatched to a runner that declares the capability the sync needs.
The environment binding is a permission boundary, not a label. A runner's permissions are checked against the scope it is bound to, so a runner bound to staging cannot be handed a prod connection to resolve. If you want production traffic isolated to particular hosts, bind those hosts to prod and bind nothing else to it.
Rotate and revoke. Every runner has a secret it authenticates with. Rotating issues a new one; revoking invalidates the runner immediately and it can no longer connect or receive work. Revoke is the correct response to a suspected compromise of the host — it does not depend on being able to reach the machine.
Credential storage
A connection stores a reference to a credential, never the value. When the credential provider is Blunox-managed, that value is protected with envelope encryption.
Each stored credential gets its own AES-256-GCM data key. That data key is wrapped by a per-workspace key held in KMS — so the ciphertext on disk is useless without a KMS operation, and a compromise of the storage layer alone yields nothing.
The wrapping binds the ciphertext to its workspace and to the specific resource it belongs to. A ciphertext copied out of one workspace and inserted into another will not decrypt, because the binding no longer matches. This closes the replay path that a naive per-tenant key would leave open.
Cryptoshredding. Deleting a workspace revokes its key. Every ciphertext under that workspace becomes permanently unreadable at that moment, regardless of what copies exist in backups or replicas. Deletion is a key operation, not a sweep of rows.
Customer-held KMS. Enterprise installations can double-wrap with a customer-held KMS key, so both key managers must agree before a credential can be decrypted. Withdrawing your key stops decryption without any action on the Blunox side.
Audit. Every credential access is recorded — which credential, by which principal, for which run.
Network access
How Blunox reaches your systems depends on the deployment model. Under BYOC and air-gapped the question mostly disappears, because the runner is already inside your network. Under managed, three mechanisms cover it.
| Mechanism | What it is for |
|---|---|
| Static egress IPs | Each workspace region has a fixed set of egress addresses. Allowlist them on your database firewall or security group and traffic from Blunox arrives from a known, stable range. |
| Private Service Connect | For warehouses that live in a private VPC with no public endpoint. Traffic stays on the provider's private network rather than traversing the public internet. |
| Inbound IP allowlisting | Optional, for console access — restrict which source addresses can reach the Blunox console for your organisation. Available on Enterprise. |
Transport
Replication channels require TLS in both directions with certificate validation — runner to control plane, and runner to your source and sink.
Misconfiguration fails closed. If a certificate does not validate, or TLS cannot be negotiated where it is required, the sync does not start. There is no silent downgrade to plaintext and no "continue anyway" path in the runtime, because a transport that quietly degrades is worse than one that stops.
TLS behaviour on the source and sink side is configured per connector — for example PostgreSQL's sslmode, which defaults to require and can be tightened to verify-ca or verify-full. The connector pages document the relevant field in each case.
Access control
Scopes nest, and containment is total: org → workspace → project → environment. A grant at a higher tier applies to every descendant beneath it. Granting editor at the org level grants it in every workspace, project and environment; granting it on a single environment confines it there.
This is what makes environment binding useful. Rather than maintaining a parallel workspace for production, you grant broadly on dev and staging and narrowly on prod, and the same connections, syncs and runners obey the boundary.
| Role | Scope | What it can do |
|---|---|---|
admin | Org-wide | All verbs, everywhere in the organisation. |
editor | Any tier | Read and write — create and modify connections, syncs and mappings within the granted scope. |
operator | Any tier | Read everywhere, plus run. Can start, stop and restart syncs; cannot change their definitions. |
viewer | Any tier | Read only, and no access to secrets. |
operator is the role most on-call rotations want: it can act on a lagging or failed sync at 3am without also being able to redefine what that sync replicates.
Tenant isolation
Isolation between tenants is enforced with row-level security on every Data Sync table, in the database itself.
The distinction matters. Application-layer filtering — a WHERE tenant_id = ? that every query is supposed to include — fails open: one query written without the predicate, one code path that forgets, and rows cross the boundary. Row-level security fails closed, because the policy is attached to the table and the database applies it whether or not the query asked. A missing predicate returns nothing rather than everything.
Audit
Data Sync records an audit entry for every credential access, every sync mutation and every approval.
| Event | Recorded |
|---|---|
| Credential access | Which credential was resolved, by which principal, for which run. |
| Sync mutation | Creating, editing, starting, stopping or restarting a sync, and who did it. |
| Approval | Resolving a pending_schema_approval gate — what the change was and who approved it. See Schema changes. |
| Dry run | Audited distinctly from a real run, so "someone sampled production rows into a preview" and "someone replicated production rows to a sink" are never confused with each other in the record. |
Run logs are a separate stream from the audit trail, retained for 30 days by default and configurable per workspace. Their attributes carry metadata only — never row data.