diff --git a/services/blob/Cargo.lock b/services/blob/Cargo.lock
--- a/services/blob/Cargo.lock
+++ b/services/blob/Cargo.lock
@@ -19,6 +19,21 @@
  "tokio-util",
 ]
 
+[[package]]
+name = "actix-cors"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b340e9cfa5b08690aae90fb61beb44e9b06f44fe3d0f93781aaa58cfba86245e"
+dependencies = [
+ "actix-utils",
+ "actix-web",
+ "derive_more",
+ "futures-util",
+ "log",
+ "once_cell",
+ "smallvec",
+]
+
 [[package]]
 name = "actix-http"
 version = "3.3.1"
@@ -817,6 +832,7 @@
 name = "blob"
 version = "0.1.0"
 dependencies = [
+ "actix-cors",
  "actix-multipart",
  "actix-web",
  "anyhow",
diff --git a/services/blob/Cargo.toml b/services/blob/Cargo.toml
--- a/services/blob/Cargo.toml
+++ b/services/blob/Cargo.toml
@@ -7,7 +7,8 @@
 edition = "2021"
 
 [dependencies]
-actix-multipart = "0.6.0"
+actix-cors = "0.6"
+actix-multipart = "0.6"
 actix-web = "4.3"
 anyhow = "1.0"
 async-stream = "0.3"
diff --git a/services/blob/src/http/handlers/blob.rs b/services/blob/src/http/handlers/blob.rs
--- a/services/blob/src/http/handlers/blob.rs
+++ b/services/blob/src/http/handlers/blob.rs
@@ -66,6 +66,7 @@
   Ok(
     HttpResponse::Ok()
       .content_type("application/octet-stream")
+      .append_header(("Content-Length", file_size.to_string()))
       .streaming(Box::pin(stream.in_current_span())),
   )
 }
diff --git a/services/blob/src/http/mod.rs b/services/blob/src/http/mod.rs
--- a/services/blob/src/http/mod.rs
+++ b/services/blob/src/http/mod.rs
@@ -2,6 +2,7 @@
 use crate::database::DatabaseClient;
 use crate::s3::S3Client;
 
+use actix_cors::Cors;
 use actix_web::{web, App, HttpServer};
 use anyhow::Result;
 use tracing::info;
@@ -16,6 +17,22 @@
   use super::context::{handle_db_error, AppContext};
 }
 
+fn cors_config() -> Cors {
+  if CONFIG.is_sandbox {
+    // All origins, methods, request headers and exposed headers allowed.
+    // Credentials supported. Max age 1 hour. Does not send wildcard.
+    return Cors::permissive();
+  }
+
+  Cors::default()
+    .allowed_origin("https://web.comm.app")
+    // for local development using prod service
+    .allowed_origin("http://localhost:3000")
+    .allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"])
+    .allow_any_header()
+    .expose_any_header()
+}
+
 pub async fn run_http_server(
   db_client: DatabaseClient,
   s3_client: S3Client,
@@ -32,6 +49,7 @@
     };
     App::new()
       .wrap(tracing_actix_web::TracingLogger::default())
+      .wrap(cors_config())
       .app_data(web::Data::new(ctx))
       .service(
         web::resource("/blob/{holder}")