diff --git a/native/native_rust_library/Cargo.lock b/native/native_rust_library/Cargo.lock
--- a/native/native_rust_library/Cargo.lock
+++ b/native/native_rust_library/Cargo.lock
@@ -786,6 +786,7 @@
  "tokio",
  "tonic",
  "tracing",
+ "tracing-subscriber",
 ]
 
 [[package]]
diff --git a/native/native_rust_library/Cargo.toml b/native/native_rust_library/Cargo.toml
--- a/native/native_rust_library/Cargo.toml
+++ b/native/native_rust_library/Cargo.toml
@@ -12,6 +12,7 @@
 tonic = "0.9.1"
 lazy_static = "1.4"
 tracing = "0.1"
+tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
 comm-opaque2 = { path = "../../shared/comm-opaque2" }
 derive_more = "0.99"
 serde = { version = "1.0", features = ["derive"] }
diff --git a/native/native_rust_library/src/config.rs b/native/native_rust_library/src/config.rs
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/src/config.rs
@@ -0,0 +1,41 @@
+use std::{env, fs, path::Path};
+
+use serde::{Deserialize, Serialize};
+use tracing::{info, warn};
+
+use crate::constants::DEFAULT_SOCKET_ADDR;
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub(super) struct IdentityServiceConfig {
+  pub(super) identity_socket_addr: String,
+}
+
+impl Default for IdentityServiceConfig {
+  fn default() -> Self {
+    Self {
+      identity_socket_addr: DEFAULT_SOCKET_ADDR.to_string(),
+    }
+  }
+}
+
+pub(super) fn get_identity_service_config(
+) -> Result<IdentityServiceConfig, Box<dyn std::error::Error>> {
+  info!(
+    "Current working directory is: {}",
+    env::current_dir().unwrap().display()
+  );
+  const IDENTITY_SERVICE_CONFIG_PATH: &str =
+    "../facts/identity_service_config.json";
+
+  let path = Path::new(IDENTITY_SERVICE_CONFIG_PATH);
+  let file_content = fs::read_to_string(path).map_err(|e| {
+    warn!("Failed to read config file '{}': {}", path.display(), e);
+    e
+  })?;
+
+  serde_json::from_str(&file_content).map_err(|e| {
+    warn!("Failed to deserialize file content: {}", e);
+    e.into()
+  })
+}
diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs
--- a/native/native_rust_library/src/lib.rs
+++ b/native/native_rust_library/src/lib.rs
@@ -1,7 +1,8 @@
-use crate::ffi::{bool_callback, string_callback, void_callback};
+use backup::ffi::*;
 use comm_opaque2::client::{Login, Registration};
 use comm_opaque2::grpc::opaque_error_to_grpc_status as handle_error;
-use constants::DEFAULT_SOCKET_ADDR;
+use config::{get_identity_service_config, IdentityServiceConfig};
+use ffi::{bool_callback, string_callback, void_callback};
 use grpc_clients::identity::protos::authenticated::{
   UpdateUserPasswordFinishRequest, UpdateUserPasswordStartRequest,
 };
@@ -20,10 +21,12 @@
 use std::sync::Arc;
 use tokio::runtime::{Builder, Runtime};
 use tonic::{Request, Status};
-use tracing::instrument;
+use tracing::{instrument, Level};
+use tracing_subscriber::EnvFilter;
 
 mod argon2_tools;
 mod backup;
+mod config;
 mod constants;
 
 use argon2_tools::compute_backup_key_str;
@@ -41,11 +44,23 @@
 pub const DEVICE_TYPE: DeviceType = DeviceType::Android;
 
 lazy_static! {
-  pub static ref RUNTIME: Arc<Runtime> =
+  static ref RUNTIME: Arc<Runtime> =
     Arc::new(Builder::new_multi_thread().enable_all().build().unwrap());
+  static ref IDENTITY_SERVICE_CONFIG: IdentityServiceConfig = {
+    let filter = EnvFilter::builder()
+      .with_default_directive(Level::INFO.into())
+      .with_env_var(EnvFilter::DEFAULT_ENV)
+      .from_env_lossy();
+
+    let subscriber = tracing_subscriber::fmt().with_env_filter(filter).finish();
+    tracing::subscriber::set_global_default(subscriber)
+      .expect("Unable to configure tracing");
+
+    get_identity_service_config()
+      .unwrap_or_else(|_| IdentityServiceConfig::default())
+  };
 }
 
-use backup::ffi::*;
 #[cxx::bridge]
 mod ffi {
 
@@ -244,7 +259,7 @@
 
 async fn fetch_nonce() -> Result<String, Error> {
   let mut identity_client = get_unauthenticated_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     CODE_VERSION,
     DEVICE_TYPE.as_str_name().to_lowercase(),
   )
@@ -266,7 +281,7 @@
 
 async fn version_supported_helper() -> Result<bool, Error> {
   let mut identity_client = get_unauthenticated_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     CODE_VERSION,
     DEVICE_TYPE.as_str_name().to_lowercase(),
   )
@@ -374,7 +389,7 @@
   };
 
   let mut identity_client = get_unauthenticated_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     CODE_VERSION,
     DEVICE_TYPE.as_str_name().to_lowercase(),
   )
@@ -488,7 +503,7 @@
   };
 
   let mut identity_client = get_unauthenticated_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     CODE_VERSION,
     DEVICE_TYPE.as_str_name().to_lowercase(),
   )
@@ -612,7 +627,7 @@
   };
 
   let mut identity_client = get_unauthenticated_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     CODE_VERSION,
     DEVICE_TYPE.as_str_name().to_lowercase(),
   )
@@ -667,7 +682,7 @@
     opaque_registration_request,
   };
   let mut identity_client = get_auth_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     update_password_info.user_id,
     update_password_info.device_id,
     update_password_info.access_token,
@@ -737,7 +752,7 @@
 
 async fn delete_user_helper(auth_info: AuthInfo) -> Result<(), Error> {
   let mut identity_client = get_auth_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     auth_info.user_id,
     auth_info.device_id,
     auth_info.access_token,
@@ -856,7 +871,7 @@
   };
 
   let mut identity_client = get_unauthenticated_client(
-    DEFAULT_SOCKET_ADDR,
+    &IDENTITY_SERVICE_CONFIG.identity_socket_addr,
     CODE_VERSION,
     DEVICE_TYPE.as_str_name().to_lowercase(),
   )