diff --git a/crates/configuration/Cargo.toml b/crates/configuration/Cargo.toml
index 56d70d80a8accfc46fcefa9dce1a12b267c7bd55..b7525f21af7bcc8021744bc472d3b804ad3ca5d3 100644
--- a/crates/configuration/Cargo.toml
+++ b/crates/configuration/Cargo.toml
@@ -12,3 +12,4 @@ thiserror = { workspace = true }
 anyhow = { workspace = true }
 serde = { workspace = true, features = ["derive"] }
 toml = { workspace = true }
+serde_json = { workspace = true }
diff --git a/crates/configuration/src/parachain.rs b/crates/configuration/src/parachain.rs
index 543b778a13576e07b7b36000012e627f73761187..8dd9c9bcd9a8c3f01041ce59794ff395c4ed690e 100644
--- a/crates/configuration/src/parachain.rs
+++ b/crates/configuration/src/parachain.rs
@@ -122,6 +122,7 @@ pub struct ParachainConfig {
     is_cumulus_based: bool,
     #[serde(skip_serializing_if = "std::vec::Vec::is_empty", default)]
     bootnodes_addresses: Vec<Multiaddr>,
+    genesis_overrides: Option<serde_json::Value>,
     #[serde(skip_serializing_if = "std::vec::Vec::is_empty", default)]
     collators: Vec<NodeConfig>,
 }
@@ -197,6 +198,11 @@ impl ParachainConfig {
         self.genesis_state_generator.as_ref()
     }
 
+    /// The genesis overrides as a JSON value.
+    pub fn genesis_overrides(&self) -> Option<&serde_json::Value> {
+        self.genesis_overrides.as_ref()
+    }
+
     /// The location of a pre-existing chain specification for the parachain.
     pub fn chain_spec_path(&self) -> Option<&AssetLocation> {
         self.chain_spec_path.as_ref()
@@ -250,6 +256,7 @@ impl Default for ParachainConfigBuilder<Initial> {
                 genesis_wasm_generator: None,
                 genesis_state_path: None,
                 genesis_state_generator: None,
+                genesis_overrides: None,
                 chain_spec_path: None,
                 is_cumulus_based: true,
                 bootnodes_addresses: vec![],
@@ -540,6 +547,18 @@ impl ParachainConfigBuilder<WithId> {
         }
     }
 
+    /// Set the genesis overrides as a JSON object.
+    pub fn with_genesis_overrides(self, genesis_overrides: impl Into<serde_json::Value>) -> Self {
+        Self::transition(
+            ParachainConfig {
+                genesis_overrides: Some(genesis_overrides.into()),
+                ..self.config
+            },
+            self.validation_context,
+            self.errors,
+        )
+    }
+
     /// Set the location of a pre-existing chain specification for the parachain.
     pub fn with_chain_spec_path(self, location: impl Into<AssetLocation>) -> Self {
         Self::transition(
diff --git a/crates/configuration/src/relaychain.rs b/crates/configuration/src/relaychain.rs
index b087ddcf7efd1ac2d892ee3bd4c04f06092f75f5..f226b79d7ba985e3042989ce3bbf746f37bee898 100644
--- a/crates/configuration/src/relaychain.rs
+++ b/crates/configuration/src/relaychain.rs
@@ -27,6 +27,7 @@ pub struct RelaychainConfig {
     max_nominations: Option<u8>,
     #[serde(skip_serializing_if = "std::vec::Vec::is_empty", default)]
     nodes: Vec<NodeConfig>,
+    genesis_overrides: Option<serde_json::Value>,
 }
 
 impl RelaychainConfig {
@@ -75,6 +76,11 @@ impl RelaychainConfig {
         self.max_nominations
     }
 
+    /// The genesis overrides as a JSON value.
+    pub fn genesis_overrides(&self) -> Option<&serde_json::Value> {
+        self.genesis_overrides.as_ref()
+    }
+
     /// The nodes of the relay chain.
     pub fn nodes(&self) -> Vec<&NodeConfig> {
         self.nodes.iter().collect::<Vec<&NodeConfig>>()
@@ -114,6 +120,7 @@ impl Default for RelaychainConfigBuilder<Initial> {
                 chain_spec_path: None,
                 random_nominators_count: None,
                 max_nominations: None,
+                genesis_overrides: None,
                 nodes: vec![],
             },
             validation_context: Default::default(),
@@ -314,6 +321,18 @@ impl RelaychainConfigBuilder<WithChain> {
         )
     }
 
+    /// Set the genesis overrides as a JSON object.
+    pub fn with_genesis_overrides(self, genesis_overrides: impl Into<serde_json::Value>) -> Self {
+        Self::transition(
+            RelaychainConfig {
+                genesis_overrides: Some(genesis_overrides.into()),
+                ..self.config
+            },
+            self.validation_context,
+            self.errors,
+        )
+    }
+
     /// Add a new node using a nested [`NodeConfigBuilder`].
     pub fn with_node(
         self,
diff --git a/crates/orchestrator/src/generators/chain_spec.rs b/crates/orchestrator/src/generators/chain_spec.rs
index f302d65909d9b70fff3445f08cef675c5b58f99d..9497ebf74b7c5af9294b1783081e4b67dd7514d9 100644
--- a/crates/orchestrator/src/generators/chain_spec.rs
+++ b/crates/orchestrator/src/generators/chain_spec.rs
@@ -311,7 +311,13 @@ impl ChainSpec {
                 .map_err(GeneratorError::ChainSpecGeneration)?;
 
             // make genesis overrides first.
-            // override_genesis()
+            if let Some(overrides) = &para.genesis_overrides {
+                if let Some(genesis) = chain_spec_json.pointer_mut(&format!("{}/genesis", pointer))
+                {
+                    override_genesis(genesis, overrides);
+                }
+            }
+
             clear_authorities(&pointer, &mut chain_spec_json);
 
             // Get validators to add as authorities
@@ -381,7 +387,12 @@ impl ChainSpec {
                 .map_err(GeneratorError::ChainSpecGeneration)?;
 
             // make genesis overrides first.
-            // override_genesis()
+            if let Some(overrides) = &relaychain.genesis_overrides {
+                if let Some(genesis) = chain_spec_json.pointer_mut(&format!("{}/genesis", pointer))
+                {
+                    override_genesis(genesis, overrides);
+                }
+            }
 
             println!(
                 "{:#?}",
@@ -596,8 +607,29 @@ fn get_runtime_config_pointer(chain_spec_json: &serde_json::Value) -> Result<Str
 }
 
 // Override `genesis` key if present
-fn override_genesis() {
-    todo!()
+fn override_genesis(genesis: &mut serde_json::Value, overrides: &serde_json::Value) {
+    if let (Some(genesis_obj), Some(overrides_obj)) =
+        (genesis.as_object_mut(), overrides.as_object())
+    {
+        for overrides_key in overrides_obj.keys() {
+            // we only want to override keys present in the genesis object
+            if let Some(genesis_value) = genesis_obj.get_mut(overrides_key) {
+                match (&genesis_value, overrides_obj.get(overrides_key)) {
+                    // recurse if genesis value is an object
+                    (serde_json::Value::Object(_), Some(overrides_value))
+                        if overrides_value.is_object() =>
+                    {
+                        override_genesis(genesis_value, overrides_value);
+                    },
+                    // override if genesis value not an object
+                    (_, Some(overrides_value)) => {
+                        *genesis_value = overrides_value.clone();
+                    },
+                    _ => {},
+                }
+            }
+        }
+    }
 }
 
 fn clear_authorities(runtime_config_ptr: &str, chain_spec_json: &mut serde_json::Value) {
diff --git a/crates/orchestrator/src/network_spec/parachain.rs b/crates/orchestrator/src/network_spec/parachain.rs
index d5334df5c9b280f209e8754738f0fe1e4c8da251..33e1217f0690f178b5a754d91f24f34768d39705 100644
--- a/crates/orchestrator/src/network_spec/parachain.rs
+++ b/crates/orchestrator/src/network_spec/parachain.rs
@@ -57,6 +57,9 @@ pub struct ParachainSpec {
     /// Genesis wasm to register the parachain
     pub(crate) genesis_wasm: ParaArtifact,
 
+    /// Genesis overrides as JSON value.
+    pub(crate) genesis_overrides: Option<serde_json::Value>,
+
     /// Collators to spawn
     pub(crate) collators: Vec<NodeSpec>,
 }
@@ -174,6 +177,7 @@ impl ParachainSpec {
             initial_balance: config.initial_balance(),
             genesis_state,
             genesis_wasm,
+            genesis_overrides: config.genesis_overrides().cloned(),
             collators,
         };
 
diff --git a/crates/orchestrator/src/network_spec/relaychain.rs b/crates/orchestrator/src/network_spec/relaychain.rs
index 1f1fd608001b9d017b4cdd87e2aa5bc9ecebfc1d..a7adee2ab4badb87b6e71f7d75478801f9c50295 100644
--- a/crates/orchestrator/src/network_spec/relaychain.rs
+++ b/crates/orchestrator/src/network_spec/relaychain.rs
@@ -43,6 +43,9 @@ pub struct RelaychainSpec {
     /// Set the max nominators value (used with PoS networks).
     pub(crate) max_nominations: u8,
 
+    /// Genesis overrides as JSON value.
+    pub(crate) genesis_overrides: Option<serde_json::Value>,
+
     /// Nodes to run.
     pub(crate) nodes: Vec<NodeSpec>,
 }
@@ -107,6 +110,7 @@ impl RelaychainSpec {
             chain_spec,
             random_nominators_count: config.random_nominators_count().unwrap_or(0),
             max_nominations: config.max_nominations().unwrap_or(24),
+            genesis_overrides: config.genesis_overrides().cloned(),
             nodes,
         })
     }