diff --git a/services/identity/src/config.rs b/services/identity/src/config.rs
--- a/services/identity/src/config.rs
+++ b/services/identity/src/config.rs
@@ -1,9 +1,11 @@
+use base64::{engine::general_purpose, DecodeError, Engine as _};
 use once_cell::sync::Lazy;
 use std::{collections::HashSet, env, fmt, fs, io, path};
+use tracing::{error, info};
 
 use crate::constants::{
-  KEYSERVER_PUBLIC_KEY, LOCALSTACK_ENDPOINT, SECRETS_DIRECTORY,
-  SECRETS_SETUP_FILE,
+  KEYSERVER_PUBLIC_KEY, LOCALSTACK_ENDPOINT, OPAQUE_SERVER_SETUP,
+  SECRETS_DIRECTORY, SECRETS_SETUP_FILE,
 };
 
 pub static CONFIG: Lazy<Config> =
@@ -27,10 +29,11 @@
   fn load() -> Result<Self, Error> {
     let localstack_endpoint = env::var(LOCALSTACK_ENDPOINT).ok();
 
-    let mut path = path::PathBuf::new();
-    path.push(SECRETS_DIRECTORY);
-    path.push(SECRETS_SETUP_FILE);
-    let server_setup = get_server_setup_from_file(&path)?;
+    let mut path_buf = path::PathBuf::new();
+    path_buf.push(SECRETS_DIRECTORY);
+    path_buf.push(SECRETS_SETUP_FILE);
+
+    let server_setup = get_server_setup(path_buf.as_path())?;
 
     let reserved_usernames = get_reserved_usernames_set()?;
 
@@ -65,13 +68,36 @@
   Env(env::VarError),
   #[display(...)]
   Json(serde_json::Error),
+  #[display(...)]
+  Decode(DecodeError),
 }
 
-fn get_server_setup_from_file<P: AsRef<path::Path>>(
-  path: &P,
+fn get_server_setup(
+  path: &path::Path,
 ) -> Result<comm_opaque2::ServerSetup<comm_opaque2::Cipher>, Error> {
-  let bytes = fs::read(path)?;
-  comm_opaque2::ServerSetup::deserialize(&bytes).map_err(Error::Opaque)
+  let encoded_server_setup = if let Ok(env_setup) =
+    env::var(OPAQUE_SERVER_SETUP)
+  {
+    info!(
+      "Using OPAQUE server setup from env var: {}",
+      OPAQUE_SERVER_SETUP
+    );
+    env_setup
+  } else if let Ok(file_setup) = fs::read_to_string(path) {
+    info!("Using OPAQUE server setup from file: {}", path.display());
+    file_setup
+  } else {
+    error!("Unable to locate OPAQUE server setup. Please run `keygen` command and run Identity service again.");
+    return Err(Error::Io(io::Error::new(
+      io::ErrorKind::NotFound,
+      "Missing server credentials",
+    )));
+  };
+
+  let decoded_server_setup =
+    general_purpose::STANDARD_NO_PAD.decode(encoded_server_setup)?;
+  comm_opaque2::ServerSetup::deserialize(&decoded_server_setup)
+    .map_err(Error::Opaque)
 }
 
 fn get_reserved_usernames_set() -> Result<HashSet<String>, Error> {
diff --git a/services/identity/src/constants.rs b/services/identity/src/constants.rs
--- a/services/identity/src/constants.rs
+++ b/services/identity/src/constants.rs
@@ -106,3 +106,7 @@
 // LocalStack
 
 pub const LOCALSTACK_ENDPOINT: &str = "LOCALSTACK_ENDPOINT";
+
+// OPAQUE Server Setup
+
+pub const OPAQUE_SERVER_SETUP: &str = "OPAQUE_SERVER_SETUP";
diff --git a/services/identity/src/keygen.rs b/services/identity/src/keygen.rs
--- a/services/identity/src/keygen.rs
+++ b/services/identity/src/keygen.rs
@@ -1,4 +1,5 @@
 use crate::constants::SECRETS_SETUP_FILE;
+use base64::{engine::general_purpose, Engine as _};
 use std::{fs, io, path};
 
 pub fn generate_and_persist_keypair(dir: &str) -> Result<(), io::Error> {
@@ -17,7 +18,9 @@
     eprintln!("{:?} already exists, skipping", path);
   } else {
     println!("Writing setup file to {:?}", path);
-    fs::write(&path, server_setup.serialize())?;
+    let encoded_server_setup =
+      general_purpose::STANDARD_NO_PAD.encode(server_setup.serialize());
+    fs::write(&path, encoded_server_setup)?;
   }
 
   Ok(())
diff --git a/services/identity/src/main.rs b/services/identity/src/main.rs
--- a/services/identity/src/main.rs
+++ b/services/identity/src/main.rs
@@ -4,7 +4,6 @@
 use database::DatabaseClient;
 use moka::future::Cache;
 use tonic::transport::Server;
-use tracing_subscriber::FmtSubscriber;
 
 mod client_service;
 mod config;