A file manager for your Cloudflare R2 bucket.

ByteFlow connects straight from your phone to your own storage. There is no account to create and no server in the middle, and your keys stay locked on the device.

What ByteFlow does

Cloudflare R2 is cheap, durable file storage, but it comes with no phone app. ByteFlow is that app: it makes your bucket look and work like folders of files.

It is built for one person using their own storage. You bring a Cloudflare account and a bucket, and ByteFlow talks to it directly from your phone, on Android or iOS. The only server it ever contacts is your R2 endpoint.

Browse
Move through folders in a list or grid, then sort and search. Your bucket's listing is kept on the phone, so browsing is instant.
Upload and download
Transfers run in a queue with live progress. You can pause them, large files go up in parts, and interrupted transfers carry on where they stopped.
Preview
Open photos, video, audio and text files inside the app without downloading them first.
Organise
Rename, move, copy and delete files or whole folders. Long-press to select several at once.
Sync a folder
Pick a folder on your phone and upload what's new or changed. You review the list first, and nothing in the bucket is ever deleted.
Share
Create a link that expires, from 15 minutes up to 7 days, and send it to anyone.
Encrypt
Optionally encrypt files on your phone before they upload, so that even Cloudflare only ever holds scrambled data.

Setting it up

Setup takes about ten minutes. Most of that is creating a bucket and an access key in Cloudflare, so have your Cloudflare login ready.

  1. Create a bucket and an API token

    In the Cloudflare dashboard, open R2 and create a bucket if you don't have one. Then open Manage API tokens and create a token with Object Read & Write permission. Limit it to this one bucket, so the key on your phone can't reach anything else.

    Cloudflare shows the Secret Access Key only once, so keep that page open until step 3. You'll also need your Account ID, which is shown on the R2 overview page.

  2. Choose two passwords

    Install ByteFlow and open it. It asks for two different passwords of at least 10 characters. A meter shows how strong each one is.

    • The login password unlocks the app. It's also your way back in if your fingerprint or face stops working.
    • The destruction password erases ByteFlow from the phone the moment it's entered at the unlock screen, with no confirmation.

    Make them hard to confuse, and read how the passwords work before you choose. Neither password can be reset or changed, so choose ones you'll remember.

  3. Connect your bucket

    Fill in the details from step 1:

    FieldWhere it comes from
    Account IDR2 overview page
    Access Key IDShown when you create the token
    Secret Access KeyShown once when you create the token
    Bucket nameThe name you gave the bucket
    Public URLOptional. Your custom domain or r2.dev address, if you've turned one on and want permanent public links.
    Custom endpointOptional. Leave it empty unless you know you need it; ByteFlow works it out from your Account ID.

    Tap Test connection. If it can't connect, it tells you why. A signature error almost always means a mistyped secret key or a wrong clock on the phone.

  4. Save and unlock

    Tap Save & unlock. ByteFlow encrypts your Cloudflare details and locks them behind your fingerprint or face.

  5. Pull down to load your files

    A new install shows an empty list until you pull down to refresh. That first pull reads your whole bucket, which can take a while if it holds a lot of files. After that, your listing is stored on the phone.

Everyday use

Unlocking. Type your password, or tap the shield above the field to use your fingerprint or face. ByteFlow never starts the fingerprint prompt by itself.

Adding files. Use the add button to upload files, create a folder, or sync a folder. If a file with the same name already exists, ByteFlow asks whether to replace it or upload it as a new file.

Seeing changes made elsewhere. Browsing reads the listing stored on your phone, so it doesn't use the network. Changes you make in ByteFlow appear straight away. If you add files another way, such as through the Cloudflare dashboard, pull down to refresh.

Syncing a folder. Syncing only ever goes from your phone to the bucket. ByteFlow scans the folder, shows what's new or changed, and uploads only what you tick. Files that exist only in the bucket are listed for information and left alone.

Sharing a file. Choose Share link on any unencrypted file. Anyone with the link can download the file until it expires, without a Cloudflare account. Set the default lifetime in Settings. Active links are listed under Shared links with a countdown.

Links can't be cancelled. That's how R2 links work: once sent, a link works until it expires. The only way to stop one early is to delete the API token in Cloudflare, which stops every link made with it, and then enter a new key in ByteFlow.

Choosing where downloads go. By default, downloads stay in app-private storage, hidden from other apps. In Settings you can choose your shared Downloads folder or another folder instead. Files saved there are ordinary files on your phone, outside ByteFlow's protection.

Passwords and unlocking

Your Cloudflare keys are the most sensitive thing in the app. Anyone holding them can read and delete everything in your bucket, so ByteFlow is designed to keep them unreadable on a lost, stolen or seized phone.

One field, three outcomes

The unlock screen has a single password field. It looks and behaves the same whichever password you type, until the moment something happens.

What was typed?

The app erases itself

There's no warning and no message. The keys are destroyed, local data is deleted, and ByteFlow opens on its first setup screen, as if it had just been installed.

Nothing happens

The login fails and you can try again.

How your fingerprint fits in

A fingerprint can't be turned into a password: your phone's secure hardware only answers yes or no. So ByteFlow generates a random key inside that hardware and asks the phone to use it only after your fingerprint or face is accepted. The key can't be copied out, and patching the app wouldn't reveal it.

Your login password is a second, independent way to reach the same data:

Each way in opens its own locked copy of the same data key, and that key decrypts your Cloudflare details.

Phones cancel fingerprint keys when fingerprints change, which is deliberate: someone who adds their own finger shouldn't gain access. Without the password route, you would lose access at that moment. If it happens, your login password still works, and from then on it's how you unlock.

What the destruction password erases

It's meant for a moment when someone forces you to open the app. The same wipe runs from Settings, Wipe everything, after you type WIPE to confirm. It only affects your phone.

Erased from the phone

  • The hardware key and every stored key
  • Your Cloudflare details and passwords
  • Your file-encryption key
  • The transfer queue, sync settings and link history
  • Thumbnails, temporary files and private downloads
  • The stored listing of your bucket, in its default location

Not erased

  • Everything in your R2 bucket
  • Your API token, which stays valid at Cloudflare
  • Share links already sent
  • Downloads saved to a shared folder
  • A bucket listing you moved to shared storage

The last item needs explaining. In Settings, Local cache you can move the stored listing of your bucket to a folder in shared storage, so it survives uninstalling the app and doesn't have to be rebuilt. A file there also survives a wipe, and other apps may be able to read it. It holds file names, sizes, dates and which files are encrypted, but no keys and no file contents. Leave it in the default location if those names are sensitive.

A wipe can't be undone. If you type the destruction password by accident, you'll have to set ByteFlow up again from scratch. Your bucket will still be there, so keep your Cloudflare access and encryption passphrase somewhere safe. Encrypted files can't be opened without that passphrase.

If your phone was taken, delete the API token in the Cloudflare dashboard as soon as you can. That cuts off the key itself, wherever it might be.

Other protections

  • Auto-lock. ByteFlow locks after it has been in the background for a set time, from 30 seconds to 10 minutes. The default is 2 minutes.
  • Hidden in the app switcher. The screen blurs as soon as you leave the app. On Android, screenshots are blocked too.
  • Protected fields. Secret fields can't be copied to the clipboard. Your saved secret key is never shown again, and saving changes to your Cloudflare details asks for your fingerprint or face.
  • Left out of backups. ByteFlow's app data is excluded from Google and iCloud device backups and from phone-to-phone transfers.
  • Wipe if biometrics change. This optional setting runs the full wipe when ByteFlow detects that your fingerprints or face have changed. It's off by default because the phone can't tell a thief's new fingerprint from your own, so turning it on means your own change would erase the app too. ByteFlow only notices when someone taps the shield.

File encryption

Everything above protects your keys. This optional layer protects what's inside your files, by scrambling them on your phone before they upload.

Cloudflare already encrypts stored data on its side, but it holds the means to read it. With ByteFlow's encryption on, your bucket holds only data that needs your passphrase to read. Cloudflare can't read it, and neither can anyone who gets hold of your API token.

Encryption off
FF D8 FF E0 00 10 4A 46
49 46 00 01 01 00 00 01
00 01 00 00 FF E1 2A 16
45 78 69 66 00 00 4D 4D
JFIF ... Exif
Encryption on
42 46 45 4E 43 32 7C E1
09 B3 5A D4 8F 21 C6 6E
3B F0 92 1D A7 58 EE 04
6A CD 31 B9 72 0F 8B D3
BFENC2 ... noise

The first bytes of the same photo as stored in your bucket (example values). Without encryption, anyone with access can tell what it is and open it.

Turning it on

  1. Open Settings, File encryption.
  2. Choose a private key. This is a passphrase of at least 10 characters, separate from your login password.
  3. Turn on Encrypt new uploads so that new files are encrypted from now on.
  4. To cover what's already there, choose Encrypt all existing files. Each file is downloaded, encrypted and uploaded again in a background queue. You can also encrypt individual files from their action sheet.

Write your passphrase down somewhere safe. Nobody can reset it. If a wipe or a new phone removes the stored key and you've lost the passphrase, your encrypted files are gone for good.

What changes once a file is encrypted

  • It shows an encrypted badge in the browser.
  • Previews still work. ByteFlow decrypts to a temporary file and deletes it when you close the viewer.
  • Downloads give you a normal, decrypted copy.
  • Share link isn't offered, because the link would deliver scrambled data. Download and send a copy, or decrypt the file first.
  • It has no thumbnail. Keeping one would leave a picture of the file in readable form.

What encryption doesn't hide

Only the contents of a file are encrypted. File names, folder names, sizes and dates stay readable to anyone who can list the bucket, including Cloudflare. Avoid putting secrets in file names.

Getting your files back on a new phone

Each encrypted file carries the settings needed to rebuild its key from your passphrase. So your files need only their own bytes and your passphrase, not the phone that encrypted them. After reinstalling, pull down to refresh and ByteFlow detects which files are encrypted. Open one, enter the passphrase, and it opens.

The same prompt appears for files encrypted outside the app with a passphrase of their own. ByteFlow remembers the resulting key for that file, so it only asks once.

Changing or removing the key

Change key re-encrypts every file under a new passphrase in the background. Files stay encrypted throughout. Remove encryption decrypts every file back to its original form in your bucket and deletes the key, after you type DECRYPT to confirm. Both have to download and re-upload each file, so they can take a while on a large bucket.

When things go wrong

What happenedWhat to do
My fingerprint stopped workingUnlock with your login password.
I changed my fingerprintsFingerprint unlock stops working for good, so keep using your login password. If you turned on Wipe if biometrics change, tapping the shield erases the app instead, and you set it up again.
I forgot my login passwordYou can still unlock with your fingerprint or face if that works. If you can't get in at all, reinstall and enter your Cloudflare details again. Your bucket isn't affected, and encrypted files will need your passphrase.
I entered the destruction passwordThe app has erased itself. Set it up again with a new or existing API token and pull down to refresh.
I forgot my encryption passphraseWhile ByteFlow is still set up on your phone, it can keep opening your files. Use Remove encryption or download copies right away. Once the stored key is gone, the files can't be recovered.
I got a new phoneInstall ByteFlow, set new passwords, and enter your Cloudflare details. Pull down to refresh, and use your passphrase for encrypted files.
My phone was lost or stolenDelete the API token in Cloudflare. Your details stay encrypted on the phone, but deleting the token removes any risk from them.
The connection test failsCheck the Account ID, keys and bucket name for typos. For a signature error, check the secret key and that your phone's clock is set automatically.
A file isn't showing upIf it was added outside ByteFlow, pull down to refresh.

What it doesn't do

  • It isn't a backup service. Deleting a file in ByteFlow deletes it from your bucket, and sync only uploads. Your files are stored once, in your own Cloudflare account.
  • It has no accounts or multi-user features. There's no sign-in, no sync between devices and no way to manage bucket permissions. Each phone is set up by itself.
  • Transfers need the app running. If the app is closed, transfers pause and resume the next time you open it.
  • It can't protect an unlocked phone. If someone has your unlocked app, or malware controls your phone while you use it, the protections here don't apply.
  • It doesn't replace Cloudflare. You pay Cloudflare directly for storage and operations, and your account's security is your own.

Technical details

For readers who want the specifics:

Credential encryptionAES-256-GCM with a random 256-bit data key, generated once at setup
Biometric key, AndroidAES-256 key in Android Keystore, StrongBox when available, requires strong biometric authentication per use, invalidated on enrolment change
Biometric key, iOSSecure Enclave P-256 key bound to the current biometric set, device-only
Password hashingArgon2id, 64 MiB, 3 iterations, parallelism 4, separate salts for each password
File encryptionStreaming AES-256-GCM over 64 KiB chunks, with a per-file key. Truncated or reordered data fails to decrypt.
NetworkDirect HTTPS to your R2 endpoint, with requests signed on the device using AWS Signature Version 4
TelemetryNone: no analytics, no crash reporting

Download ByteFlow

ByteFlow is coming to Google Play and the App Store. You'll need a Cloudflare account to use it, as the setup guide explains.

  • Google Play

    For Android. Installs and updates through the Play Store.

    Coming soon
  • App Store

    For iPhone. Installs and updates through the App Store.

    Coming soon