diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js
--- a/lib/actions/upload-actions.js
+++ b/lib/actions/upload-actions.js
@@ -22,6 +22,7 @@
 import {
   makeBlobServiceEndpointURL,
   makeBlobServiceURI,
+  generateBlobHolder,
 } from '../utils/blob-service.js';
 import { getMessageForException } from '../utils/errors.js';
 import {
@@ -169,7 +170,7 @@
     const { uploadInput, callbacks, keyserverOrThreadID } = input;
     const { encryptionKey, loop, dimensions, thumbHash, blobInput } =
       uploadInput;
-    const blobHolder = uuid.v4();
+    const blobHolder = await generateBlobHolder();
     const blobHash = toBase64URL(uploadInput.blobHash);
     const defaultHeaders = createDefaultHTTPRequestHeaders(authMetadata);
 
diff --git a/lib/utils/blob-service.js b/lib/utils/blob-service.js
--- a/lib/utils/blob-service.js
+++ b/lib/utils/blob-service.js
@@ -1,7 +1,10 @@
 // @flow
 
 import invariant from 'invariant';
+import uuid from 'uuid';
 
+import { toBase64URL } from './base64.js';
+import { getContentSigningKey } from './crypto-utils.js';
 import { replacePathParams, type URLPathParams } from './url-utils.js';
 import type { BlobServiceHTTPEndpoint } from '../facts/blob-service.js';
 import blobServiceConfig from '../facts/blob-service.js';
@@ -50,11 +53,26 @@
   });
 }
 
+/**
+ * Generates random blob holder prefixed by current device ID
+ */
+async function generateBlobHolder(): Promise<string> {
+  const randomID = uuid.v4();
+  try {
+    const deviceID = await getContentSigningKey();
+    const urlSafeDeviceID = toBase64URL(deviceID);
+    return `${urlSafeDeviceID}:${randomID}`;
+  } catch {
+    return randomID;
+  }
+}
+
 export {
   makeBlobServiceURI,
   isBlobServiceURI,
   blobHashFromURI,
   blobHashFromBlobServiceURI,
+  generateBlobHolder,
   getBlobFetchableURL,
   makeBlobServiceEndpointURL,
 };