Product Updates Intermediate By Samson Tanimawo, PhD Published Aug 12, 2026 8 min read

Nova Transfer: Encrypted, Audited Cross-Cloud File Transfer

Move files between AWS, Azure, and GCP with end-to-end encryption, RBAC on both ends, and a full audit trail. The piece your compliance team will actually let you ship to production.

Why we built it

Cross-cloud file transfer sounds boring. It mostly is. The interesting part is that every team that needs to do it ends up writing custom scripts, running them on a bastion host, hoping nobody loses the credentials, and prayer-driven-developing the audit story for their compliance team. The boring problem is solved badly almost everywhere we've looked.

Nova Transfer was built because we kept watching our customers reinvent it during onboarding, they had a 50GB analytics dump in one cloud and needed it in another for a Nova-based pipeline, and the homegrown S3-to-GCS copier was the friction point. We shipped Transfer in v2.5 to move that friction out of the way.

What it does in one sentence: encrypted, RBAC-enforced, fully audited file transfer between any two of AWS S3, Azure Blob, and Google Cloud Storage, with sane defaults and decent throughput.

End-to-end encryption

The crypto model is the thing we got most carefully right. Bytes are encrypted before they leave the source's egress and decrypted only at the destination. Nova orchestrates the transfer; Nova never has the unencrypted bytes in memory or on disk. This isn't marketing language, the encryption happens in customer-side workers running in the customer's cloud account; Nova's control plane only sees the ciphertext.

The encryption key is derived from a per-transfer ephemeral key plus the customer's KMS root key. The ephemeral key is generated at transfer-start time and discarded at transfer-end; the root key never leaves the customer's KMS. Even if Nova's control plane were compromised at transfer time, the attacker would have ciphertext without the key.

The cipher is AES-256-GCM with a fresh nonce per chunk. Chunks are independently decryptable, which is what makes the transfer resumable, if a transfer dies at the 70% mark, restart picks up from chunk 70% with the same key, and the already-transferred chunks don't need to be redone.

RBAC on both ends

Every transfer requires authorisation against both the source and the destination. The user (or the agent) initiating the transfer must have read access to the source object and write access to the destination location. Nova enforces this by checking the IAM policies of both ends before starting the transfer.

The check is against the underlying cloud's IAM (AWS IAM, Azure RBAC, GCP IAM), not against a Nova-internal permission system. This matters because it means a user who's been off-boarded from the source bucket loses transfer permission within seconds of the IAM update, there's no Nova-side cache to stale.

For agent-initiated transfers (a runbook executing as part of an automated remediation, for example), the agent runs as a service-principal with explicit IAM grants. The audit ledger records both the agent identity and the human who authorised the runbook to act on their behalf.

The audit trail

Every transfer produces a ledger entry with the source object, destination object, byte count, hash of the encrypted payload, who initiated it, what RBAC decision was made on each end, the start and end timestamps, and the result. The hash lets compliance verify post-hoc that the bytes that arrived at the destination are the bytes that left the source, no silent corruption, no man-in-the-middle.

The ledger is queryable by source, destination, user, time range, and result. The common compliance ask, "show me every transfer of customer data out of the EU region this quarter", is a single query against a small number of well-indexed columns.

For deeper forensics, we keep the per-chunk ledger entries (start time, end time, hash, retry count) for 30 days. This is the source of truth when something goes wrong, was the transfer slow because of a network blip, or because of throttling, or because someone's IAM policy changed mid-transfer? The chunk-level data answers all three.

Throughput

The naive S3-to-GCS copy through a customer's VPC tops out at about 100 MB/s, limited by the single TCP connection and the round-trip time. Nova Transfer pipelines parallel chunks across both source and destination, hitting 1.2 GB/s on standard cloud egress connections. A 50GB transfer drops from 8 minutes to 40 seconds.

The implementation is unglamorous. The transfer planner splits the source object into chunks (default 8MB; configurable), schedules N concurrent chunk fetches against the source, encrypts each chunk in a worker, and dispatches N concurrent uploads to the destination. The throughput sweet spot for most cloud-to-cloud paths is 32-48 concurrent chunks; we autotune within that range based on observed throughput.

For very large transfers (TB-scale), we recommend splitting the work across multiple transfer jobs with non-overlapping object lists. The planner can do this automatically, give it a 5TB prefix and it shards into 50 jobs of 100GB each, runs them in parallel, and gives you back a single transfer ID that aggregates the results.

How to use it

The UI is at Operations → Transfers → New Transfer. Pick source bucket, pick destination, pick prefix or specific objects, configure throttling if needed, click Start. The transfer progress streams live in the UI; you can leave the page and come back, the state is server-side.

The API is `POST /v1/transfers` with the source spec, destination spec, and optional throttle. The response is a transfer ID; subsequent `GET /v1/transfers/{id}` returns the live state.

The Nova Shell command is "transfer the 2026-04 dataset from s3 prod-data to gcs analytics-staging", the shell parses, generates the structured transfer spec, shows the diff, waits for confirmation, then kicks off the API call. This is the path most operators end up using once they're comfortable with the shell.

Nova Transfer is live for all tenants. AWS S3, Azure Blob, and Google Cloud Storage are supported today; on-prem object stores (MinIO, Ceph) ship in v2.9.