Skip to content
Open Data Sync ↗

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 planeNot stored in the control plane
Sync definitions — connections referenced, tables selected, mappings, replication modeRow values, in any form
Checkpoints — the last durably written source log position per syncColumn contents, samples, or previews
Run history — run number, type, start and end, duration, event and byte counts, statusCredential values, for any provider
Schema names — table and column names and their typesAnything read during a dry run
Operational metrics — lag, throughput, partition progressRow 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.

ModelWho runs the runnersWhere credentials liveWhere the control plane runs
ManagedBlunoxBlunox credential store, or your ownBlunox
BYOCYou, in your cloud accountYour own secret storeBlunox
Air-gappedYouYoursYours

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.

The deciding question: can checkpoints and schema names live in Blunox's control plane? If yes, choose between managed and BYOC on the basis of where you want row traffic and credential custody. If no, you want the air-gapped installation — BYOC does not solve it, because BYOC keeps rows in your network but still reports metadata upward.

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.

The strongest option is not storing it with us at all. Bring-your-own credentials — HashiCorp Vault, AWS Secrets Manager or GCP Secret Manager — mean Blunox holds a typed reference and nothing else; the runner resolves it at run time and never persists the value. See Connections → Credentials.

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.

MechanismWhat it is for
Static egress IPsEach 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 ConnectFor 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 allowlistingOptional, for console access — restrict which source addresses can reach the Blunox console for your organisation. Available on Enterprise.
There are no bastion hosts and no SSH tunnels. Data Sync does not support them and will not add them on request. This is a design decision, not a missing feature: a bastion is a long-lived credentialed foothold inside your network with a shell attached, and it is a strictly worse answer than either an egress-only runner sitting next to your data or a private endpoint. If your current pattern is "vendor connects through a jump box", the equivalent here is BYOC — and it gives you a smaller attack surface, not a larger one.

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.

RoleScopeWhat it can do
adminOrg-wideAll verbs, everywhere in the organisation.
editorAny tierRead and write — create and modify connections, syncs and mappings within the granted scope.
operatorAny tierRead everywhere, plus run. Can start, stop and restart syncs; cannot change their definitions.
viewerAny tierRead 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.

EventRecorded
Credential accessWhich credential was resolved, by which principal, for which run.
Sync mutationCreating, editing, starting, stopping or restarting a sync, and who did it.
ApprovalResolving a pending_schema_approval gate — what the change was and who approved it. See Schema changes.
Dry runAudited 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.