diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs
index 8648c8ce9311d05430468b01510f8f88514d5e08..1452ba93a76f211cf7b7026ffe3cb138ffe7a225 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs
@@ -83,7 +83,7 @@ fn spend_roc_on_asset_hub() {
 			})),
 		});
 
-		// Dispatched from Root to `despatch_as` `Signed(treasury_account)`.
+		// Dispatched from Root to `dispatch_as` `Signed(treasury_account)`.
 		assert_ok!(teleport_call.dispatch(root));
 
 		assert_expected_events!(
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs
index 144934ecd4abd637481ed19cacc3fce07a89ea77..0057459fc93c6d4296082f1cadf57c3a143cc918 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs
@@ -21,8 +21,8 @@ use asset_hub_rococo_runtime::{
 	xcm_config,
 	xcm_config::{
 		bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount,
-		ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot,
-		TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig,
+		ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, GovernanceLocation,
+		LocationToAccountId, StakingPot, TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig,
 	},
 	AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, Block,
 	CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance,
@@ -32,13 +32,13 @@ use asset_hub_rococo_runtime::{
 };
 use asset_test_utils::{
 	test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys,
-	ExtBuilder, SlotDurations,
+	ExtBuilder, GovernanceOrigin, SlotDurations,
 };
 use codec::{Decode, Encode};
 use core::ops::Mul;
 use cumulus_primitives_utility::ChargeWeightInFungibles;
 use frame_support::{
-	assert_noop, assert_ok,
+	assert_noop, assert_ok, parameter_types,
 	traits::{
 		fungible::{Inspect, Mutate},
 		fungibles::{
@@ -61,6 +61,10 @@ use xcm_runtime_apis::conversions::LocationToAccountHelper;
 const ALICE: [u8; 32] = [1u8; 32];
 const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32];
 
+parameter_types! {
+	pub Governance: GovernanceOrigin<RuntimeOrigin> = GovernanceOrigin::Location(GovernanceLocation::get());
+}
+
 type AssetIdForTrustBackedAssetsConvert =
 	assets_common::AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>;
 
@@ -1335,7 +1339,7 @@ fn change_xcm_bridge_hub_router_byte_fee_by_governance_works() {
 	>(
 		collator_session_keys(),
 		1000,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| {
 			(
 				bridging::XcmBridgeHubRouterByteFee::key().to_vec(),
@@ -1361,7 +1365,7 @@ fn change_xcm_bridge_hub_router_base_fee_by_governance_works() {
 	>(
 		collator_session_keys(),
 		1000,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| {
 			log::error!(
 				target: "bridges::estimate",
@@ -1393,7 +1397,7 @@ fn change_xcm_bridge_hub_ethereum_base_fee_by_governance_works() {
 	>(
 		collator_session_keys(),
 		1000,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| {
 			log::error!(
 				target: "bridges::estimate",
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs
index e144f36dd6b88ae9794fc29a10db9a86bfdc2f58..46c4e4d0b28e49c6e7f11905b8fbe7894bc988f3 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs
@@ -44,6 +44,7 @@ use polkadot_parachain_primitives::primitives::Sibling;
 use polkadot_runtime_common::xcm_sender::ExponentialPrice;
 use snowbridge_router_primitives::inbound::EthereumLocationsConverterFor;
 use sp_runtime::traits::{AccountIdConversion, ConvertInto, TryConvertInto};
+use westend_runtime_constants::system_parachain::COLLECTIVES_ID;
 use xcm::latest::{prelude::*, ROCOCO_GENESIS_HASH, WESTEND_GENESIS_HASH};
 use xcm_builder::{
 	AccountId32Aliases, AliasChildLocation, AllowExplicitUnpaidExecutionFrom,
@@ -265,9 +266,9 @@ impl Contains<Location> for FellowshipEntities {
 	fn contains(location: &Location) -> bool {
 		matches!(
 			location.unpack(),
-			(1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }]) |
-				(1, [Parachain(1001), PalletInstance(64)]) |
-				(1, [Parachain(1001), PalletInstance(65)])
+			(1, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }]) |
+				(1, [Parachain(COLLECTIVES_ID), PalletInstance(64)]) |
+				(1, [Parachain(COLLECTIVES_ID), PalletInstance(65)])
 		)
 	}
 }
@@ -275,7 +276,7 @@ impl Contains<Location> for FellowshipEntities {
 pub struct AmbassadorEntities;
 impl Contains<Location> for AmbassadorEntities {
 	fn contains(location: &Location) -> bool {
-		matches!(location.unpack(), (1, [Parachain(1001), PalletInstance(74)]))
+		matches!(location.unpack(), (1, [Parachain(COLLECTIVES_ID), PalletInstance(74)]))
 	}
 }
 
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs
index 24b6d83ffae418962f026ed0c97ea8f5bf04d037..38673606541b071cff64654168acaf92b111019b 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs
@@ -21,8 +21,9 @@ use asset_hub_westend_runtime::{
 	xcm_config,
 	xcm_config::{
 		bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount,
-		ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot,
-		TrustBackedAssetsPalletLocation, WestendLocation, XcmConfig,
+		ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, GovernanceLocation,
+		LocationToAccountId, StakingPot, TrustBackedAssetsPalletLocation, WestendLocation,
+		XcmConfig,
 	},
 	AllPalletsWithoutSystem, Assets, Balances, Block, ExistentialDeposit, ForeignAssets,
 	ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem,
@@ -32,12 +33,12 @@ use asset_hub_westend_runtime::{
 pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System};
 use asset_test_utils::{
 	test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys,
-	ExtBuilder, SlotDurations,
+	ExtBuilder, GovernanceOrigin, SlotDurations,
 };
 use codec::{Decode, Encode};
 use cumulus_primitives_utility::ChargeWeightInFungibles;
 use frame_support::{
-	assert_noop, assert_ok,
+	assert_err, assert_noop, assert_ok, parameter_types,
 	traits::{
 		fungible::{Inspect, Mutate},
 		fungibles::{
@@ -49,7 +50,7 @@ use frame_support::{
 use parachains_common::{AccountId, AssetIdForTrustBackedAssets, AuraId, Balance};
 use sp_consensus_aura::SlotDuration;
 use sp_core::crypto::Ss58Codec;
-use sp_runtime::traits::MaybeEquivalence;
+use sp_runtime::{traits::MaybeEquivalence, Either};
 use std::{convert::Into, ops::Mul};
 use testnet_parachains_constants::westend::{consensus::*, currency::UNITS, fee::WeightToFee};
 use xcm::latest::{
@@ -63,6 +64,10 @@ use xcm_runtime_apis::conversions::LocationToAccountHelper;
 const ALICE: [u8; 32] = [1u8; 32];
 const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32];
 
+parameter_types! {
+	pub Governance: GovernanceOrigin<RuntimeOrigin> = GovernanceOrigin::Location(GovernanceLocation::get());
+}
+
 type AssetIdForTrustBackedAssetsConvert =
 	assets_common::AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>;
 
@@ -1309,7 +1314,7 @@ fn change_xcm_bridge_hub_router_byte_fee_by_governance_works() {
 	>(
 		collator_session_keys(),
 		1000,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| {
 			(
 				bridging::XcmBridgeHubRouterByteFee::key().to_vec(),
@@ -1335,7 +1340,7 @@ fn change_xcm_bridge_hub_router_base_fee_by_governance_works() {
 	>(
 		collator_session_keys(),
 		1000,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| {
 			log::error!(
 				target: "bridges::estimate",
@@ -1512,3 +1517,54 @@ fn xcm_payment_api_works() {
 		Block,
 	>();
 }
+
+#[test]
+fn governance_authorize_upgrade_works() {
+	use westend_runtime_constants::system_parachain::{ASSET_HUB_ID, COLLECTIVES_ID};
+
+	// no - random para
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(12334)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - AssetHub
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(ASSET_HUB_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(COLLECTIVES_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives Voice of Fellows plurality
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::LocationAndDescendOrigin(
+			Location::new(1, Parachain(COLLECTIVES_ID)),
+			Plurality { id: BodyId::Technical, part: BodyPart::Voice }.into()
+		)),
+		Either::Right(XcmError::BadOrigin)
+	);
+
+	// ok - relaychain
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(Location::parent())));
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(GovernanceLocation::get())));
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
index 23b85388b0cba82569c3e3fe09e8ce63591291a6..111da98b65c7c372699b772a1a88f1e1f948fda3 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
@@ -24,7 +24,7 @@ use bridge_hub_rococo_runtime::{
 	ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent,
 	RuntimeOrigin, SessionKeys, TransactionPayment, TxExtension, UncheckedExtrinsic,
 };
-use bridge_hub_test_utils::SlotDurations;
+use bridge_hub_test_utils::{GovernanceOrigin, SlotDurations};
 use codec::{Decode, Encode};
 use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8};
 use parachains_common::{AccountId, AuraId, Balance};
@@ -42,6 +42,7 @@ use xcm_runtime_apis::conversions::LocationToAccountHelper;
 
 parameter_types! {
 	pub CheckingAccount: AccountId = PolkadotXcm::check_account();
+	pub Governance: GovernanceOrigin<RuntimeOrigin> = GovernanceOrigin::Location(Location::parent());
 }
 
 fn construct_extrinsic(
@@ -164,7 +165,11 @@ mod bridge_hub_westend_tests {
 		bridge_hub_test_utils::test_cases::initialize_bridge_by_governance_works::<
 			Runtime,
 			BridgeGrandpaWestendInstance,
-		>(collator_session_keys(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID)
+		>(
+			collator_session_keys(),
+			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
+			Governance::get(),
+		)
 	}
 
 	#[test]
@@ -173,7 +178,11 @@ mod bridge_hub_westend_tests {
 		bridge_hub_test_utils::test_cases::change_bridge_grandpa_pallet_mode_by_governance_works::<
 			Runtime,
 			BridgeGrandpaWestendInstance,
-		>(collator_session_keys(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID)
+		>(
+			collator_session_keys(),
+			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
+			Governance::get(),
+		)
 	}
 
 	#[test]
@@ -182,7 +191,11 @@ mod bridge_hub_westend_tests {
 		bridge_hub_test_utils::test_cases::change_bridge_parachains_pallet_mode_by_governance_works::<
 			Runtime,
 			BridgeParachainWestendInstance,
-		>(collator_session_keys(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID)
+		>(
+			collator_session_keys(),
+			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
+			Governance::get(),
+		)
 	}
 
 	#[test]
@@ -191,7 +204,11 @@ mod bridge_hub_westend_tests {
 		bridge_hub_test_utils::test_cases::change_bridge_messages_pallet_mode_by_governance_works::<
 			Runtime,
 			WithBridgeHubWestendMessagesInstance,
-		>(collator_session_keys(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID)
+		>(
+			collator_session_keys(),
+			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
+			Governance::get(),
+		)
 	}
 
 	#[test]
@@ -203,7 +220,7 @@ mod bridge_hub_westend_tests {
 		>(
 			collator_session_keys(),
 			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
-			Box::new(|call| RuntimeCall::System(call).encode()),
+			Governance::get(),
 			|| (EthereumGatewayAddress::key().to_vec(), EthereumGatewayAddress::get()),
 			|_| [1; 20].into(),
 		)
@@ -219,7 +236,7 @@ mod bridge_hub_westend_tests {
 		bridge_hub_test_utils::test_cases::set_storage_keys_by_governance_works::<Runtime>(
 			collator_session_keys(),
 			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
-			Box::new(|call| RuntimeCall::System(call).encode()),
+			Governance::get(),
 			vec![
 				(snowbridge_pallet_outbound_queue::Nonce::<Runtime>::hashed_key_for::<ChannelId>(
 					channel_id_one,
@@ -284,7 +301,7 @@ mod bridge_hub_westend_tests {
 		>(
 			collator_session_keys(),
 			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
-			Box::new(|call| RuntimeCall::System(call).encode()),
+			Governance::get(),
 			|| (DeliveryRewardInBalance::key().to_vec(), DeliveryRewardInBalance::get()),
 			|old_value| old_value.checked_mul(2).unwrap(),
 		)
@@ -536,7 +553,11 @@ mod bridge_hub_bulletin_tests {
 		bridge_hub_test_utils::test_cases::initialize_bridge_by_governance_works::<
 			Runtime,
 			BridgeGrandpaRococoBulletinInstance,
-		>(collator_session_keys(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID)
+		>(
+			collator_session_keys(),
+			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
+			Governance::get(),
+		)
 	}
 
 	#[test]
@@ -545,7 +566,11 @@ mod bridge_hub_bulletin_tests {
 		bridge_hub_test_utils::test_cases::change_bridge_grandpa_pallet_mode_by_governance_works::<
 			Runtime,
 			BridgeGrandpaRococoBulletinInstance,
-		>(collator_session_keys(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID)
+		>(
+			collator_session_keys(),
+			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
+			Governance::get(),
+		)
 	}
 
 	#[test]
@@ -554,7 +579,11 @@ mod bridge_hub_bulletin_tests {
 		bridge_hub_test_utils::test_cases::change_bridge_messages_pallet_mode_by_governance_works::<
 			Runtime,
 			WithRococoBulletinMessagesInstance,
-		>(collator_session_keys(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID)
+		>(
+			collator_session_keys(),
+			bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
+			Governance::get(),
+		)
 	}
 
 	#[test]
@@ -716,7 +745,7 @@ fn change_required_stake_by_governance_works() {
 	>(
 		collator_session_keys(),
 		bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| {
 			(
 				bridge_common_config::RequiredStakeForStakeAndSlash::key().to_vec(),
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs
index f7a1859e9e842daad95df435545b5429d7f8b20f..170376318dcbdd86e7ab25032a3d673411a250be 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs
@@ -66,6 +66,7 @@ parameter_types! {
 	pub const MaxAssetsIntoHolding: u32 = 64;
 	pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating();
 	pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into();
+	pub const GovernanceLocation: Location = Location::parent();
 }
 
 /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
index b414338aab2d146a8d432130d61ef135166c9167..d9b69c54804816fd1729bb8b36577f15712c3153 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
@@ -22,12 +22,14 @@ use bp_relayers::{PayRewardFromAccount, RewardsAccountOwner, RewardsAccountParam
 use bridge_common_config::{BridgeRelayersInstance, BridgeReward, RequiredStakeForStakeAndSlash};
 use bridge_hub_test_utils::{
 	test_cases::{from_parachain, run_test},
-	SlotDurations,
+	GovernanceOrigin, SlotDurations,
 };
 use bridge_hub_westend_runtime::{
 	bridge_common_config, bridge_to_rococo_config,
 	bridge_to_rococo_config::RococoGlobalConsensusNetwork,
-	xcm_config::{LocationToAccountId, RelayNetwork, WestendLocation, XcmConfig},
+	xcm_config::{
+		GovernanceLocation, LocationToAccountId, RelayNetwork, WestendLocation, XcmConfig,
+	},
 	AllPalletsWithoutSystem, Balances, Block, BridgeRejectObsoleteHeadersAndMessages,
 	BridgeRelayers, Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime,
 	RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, TransactionPayment, TxExtension,
@@ -53,7 +55,7 @@ use sp_core::crypto::Ss58Codec;
 use sp_keyring::Sr25519Keyring::{Alice, Bob};
 use sp_runtime::{
 	generic::{Era, SignedPayload},
-	AccountId32, Perbill,
+	AccountId32, Either, Perbill,
 };
 use testnet_parachains_constants::westend::{consensus::*, fee::WeightToFee};
 use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH};
@@ -70,6 +72,8 @@ parameter_types! {
 	pub SiblingParachainLocation: Location = Location::new(1, [Parachain(SIBLING_PARACHAIN_ID)]);
 	pub SiblingSystemParachainLocation: Location = Location::new(1, [Parachain(SIBLING_SYSTEM_PARACHAIN_ID)]);
 	pub BridgedUniversalLocation: InteriorLocation = [GlobalConsensus(RococoGlobalConsensusNetwork::get()), Parachain(BRIDGED_LOCATION_PARACHAIN_ID)].into();
+	pub CheckingAccount: AccountId = PolkadotXcm::check_account();
+	pub Governance: GovernanceOrigin<RuntimeOrigin> = GovernanceOrigin::Location(GovernanceLocation::get());
 }
 
 // Runtime from tests PoV
@@ -82,10 +86,6 @@ type RuntimeTestsAdapter = from_parachain::WithRemoteParachainHelperAdapter<
 	BridgeRelayersInstance,
 >;
 
-parameter_types! {
-	pub CheckingAccount: AccountId = PolkadotXcm::check_account();
-}
-
 fn construct_extrinsic(
 	sender: sp_keyring::Sr25519Keyring,
 	call: RuntimeCall,
@@ -166,7 +166,11 @@ fn initialize_bridge_by_governance_works() {
 	bridge_hub_test_utils::test_cases::initialize_bridge_by_governance_works::<
 		Runtime,
 		BridgeGrandpaRococoInstance,
-	>(collator_session_keys(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID)
+	>(
+		collator_session_keys(),
+		bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
+		Governance::get(),
+	)
 }
 
 #[test]
@@ -174,7 +178,11 @@ fn change_bridge_grandpa_pallet_mode_by_governance_works() {
 	bridge_hub_test_utils::test_cases::change_bridge_grandpa_pallet_mode_by_governance_works::<
 		Runtime,
 		BridgeGrandpaRococoInstance,
-	>(collator_session_keys(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID)
+	>(
+		collator_session_keys(),
+		bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
+		Governance::get(),
+	)
 }
 
 #[test]
@@ -182,7 +190,11 @@ fn change_bridge_parachains_pallet_mode_by_governance_works() {
 	bridge_hub_test_utils::test_cases::change_bridge_parachains_pallet_mode_by_governance_works::<
 		Runtime,
 		BridgeParachainRococoInstance,
-	>(collator_session_keys(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID)
+	>(
+		collator_session_keys(),
+		bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
+		Governance::get(),
+	)
 }
 
 #[test]
@@ -190,7 +202,11 @@ fn change_bridge_messages_pallet_mode_by_governance_works() {
 	bridge_hub_test_utils::test_cases::change_bridge_messages_pallet_mode_by_governance_works::<
 		Runtime,
 		WithBridgeHubRococoMessagesInstance,
-	>(collator_session_keys(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID)
+	>(
+		collator_session_keys(),
+		bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
+		Governance::get(),
+	)
 }
 
 #[test]
@@ -202,7 +218,7 @@ fn change_delivery_reward_by_governance_works() {
 	>(
 		collator_session_keys(),
 		bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| (DeliveryRewardInBalance::key().to_vec(), DeliveryRewardInBalance::get()),
 		|old_value| old_value.checked_mul(2).unwrap(),
 	)
@@ -217,7 +233,7 @@ fn change_required_stake_by_governance_works() {
 	>(
 		collator_session_keys(),
 		bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
-		Box::new(|call| RuntimeCall::System(call).encode()),
+		Governance::get(),
 		|| (RequiredStakeForStakeAndSlash::key().to_vec(), RequiredStakeForStakeAndSlash::get()),
 		|old_value| old_value.checked_mul(2).unwrap(),
 	)
@@ -624,3 +640,54 @@ pub fn bridge_rewards_works() {
 		},
 	);
 }
+
+#[test]
+fn governance_authorize_upgrade_works() {
+	use westend_runtime_constants::system_parachain::{ASSET_HUB_ID, COLLECTIVES_ID};
+
+	// no - random para
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(12334)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - AssetHub
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(ASSET_HUB_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(COLLECTIVES_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives Voice of Fellows plurality
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::LocationAndDescendOrigin(
+			Location::new(1, Parachain(COLLECTIVES_ID)),
+			Plurality { id: BodyId::Technical, part: BodyPart::Voice }.into()
+		)),
+		Either::Right(XcmError::Barrier)
+	);
+
+	// ok - relaychain
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(Location::parent())));
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(Governance::get()));
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs
index a964cb26da0f2df222e037fb0d9bc3089ecce1c7..b966d445c225a030ef27370c4fc82fffba6224d7 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs
@@ -41,8 +41,8 @@ use frame_support::{
 use frame_system::pallet_prelude::BlockNumberFor;
 use parachains_common::AccountId;
 use parachains_runtimes_test_utils::{
-	mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, RuntimeCallOf,
-	SlotDurations, XcmReceivedFrom,
+	mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder,
+	GovernanceOrigin, RuntimeCallOf, RuntimeOriginOf, SlotDurations, XcmReceivedFrom,
 };
 use sp_runtime::{traits::Zero, AccountId32};
 use xcm::{latest::prelude::*, AlwaysLatest};
@@ -104,6 +104,7 @@ where
 pub fn initialize_bridge_by_governance_works<Runtime, GrandpaPalletInstance>(
 	collator_session_key: CollatorSessionKeys<Runtime>,
 	runtime_para_id: u32,
+	governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
 ) where
 	Runtime: BasicParachainRuntime + BridgeGrandpaConfig<GrandpaPalletInstance>,
 	GrandpaPalletInstance: 'static,
@@ -126,8 +127,10 @@ pub fn initialize_bridge_by_governance_works<Runtime, GrandpaPalletInstance>(
 		});
 
 		// execute XCM with Transacts to `initialize bridge` as governance does
-		assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(initialize_call.encode(),)
-			.ensure_complete());
+		assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
+			initialize_call,
+			governance_origin
+		));
 
 		// check mode after
 		assert_eq!(
@@ -142,6 +145,7 @@ pub fn initialize_bridge_by_governance_works<Runtime, GrandpaPalletInstance>(
 pub fn change_bridge_grandpa_pallet_mode_by_governance_works<Runtime, GrandpaPalletInstance>(
 	collator_session_key: CollatorSessionKeys<Runtime>,
 	runtime_para_id: u32,
+	governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
 ) where
 	Runtime: BasicParachainRuntime + BridgeGrandpaConfig<GrandpaPalletInstance>,
 	GrandpaPalletInstance: 'static,
@@ -164,10 +168,10 @@ pub fn change_bridge_grandpa_pallet_mode_by_governance_works<Runtime, GrandpaPal
 			);
 
 			// execute XCM with Transacts to `initialize bridge` as governance does
-			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(
-				set_operating_mode_call.encode(),
-			)
-			.ensure_complete());
+			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
+				set_operating_mode_call,
+				governance_origin.clone()
+			));
 
 			// check mode after
 			assert_eq!(
@@ -192,6 +196,7 @@ pub fn change_bridge_grandpa_pallet_mode_by_governance_works<Runtime, GrandpaPal
 pub fn change_bridge_parachains_pallet_mode_by_governance_works<Runtime, ParachainsPalletInstance>(
 	collator_session_key: CollatorSessionKeys<Runtime>,
 	runtime_para_id: u32,
+	governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
 ) where
 	Runtime: BasicParachainRuntime + BridgeParachainsConfig<ParachainsPalletInstance>,
 	ParachainsPalletInstance: 'static,
@@ -216,10 +221,10 @@ pub fn change_bridge_parachains_pallet_mode_by_governance_works<Runtime, Paracha
 				});
 
 			// execute XCM with Transacts to `initialize bridge` as governance does
-			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(
-				set_operating_mode_call.encode(),
-			)
-			.ensure_complete());
+			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
+				set_operating_mode_call,
+				governance_origin.clone()
+			));
 
 			// check mode after
 			assert_eq!(
@@ -244,6 +249,7 @@ pub fn change_bridge_parachains_pallet_mode_by_governance_works<Runtime, Paracha
 pub fn change_bridge_messages_pallet_mode_by_governance_works<Runtime, MessagesPalletInstance>(
 	collator_session_key: CollatorSessionKeys<Runtime>,
 	runtime_para_id: u32,
+	governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
 ) where
 	Runtime: BasicParachainRuntime + BridgeMessagesConfig<MessagesPalletInstance>,
 	MessagesPalletInstance: 'static,
@@ -268,10 +274,10 @@ pub fn change_bridge_messages_pallet_mode_by_governance_works<Runtime, MessagesP
 			});
 
 			// execute XCM with Transacts to `initialize bridge` as governance does
-			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(
-				set_operating_mode_call.encode(),
-			)
-			.ensure_complete());
+			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
+				set_operating_mode_call,
+				governance_origin.clone()
+			));
 
 			// check mode after
 			assert_eq!(
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs
index 71208b7ce875fd708ae038518c8f43800c5ae6f5..5d33d006c293cb57f1b42820a263f32a8428c4ac 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs
@@ -31,7 +31,7 @@ use parachains_common::xcm_config::{
 };
 use polkadot_parachain_primitives::primitives::Sibling;
 use polkadot_runtime_common::xcm_sender::ExponentialPrice;
-use westend_runtime_constants::xcm as xcm_constants;
+use westend_runtime_constants::{system_parachain::ASSET_HUB_ID, xcm as xcm_constants};
 use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH};
 use xcm_builder::{
 	AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter,
@@ -58,7 +58,7 @@ parameter_types! {
 	pub CheckingAccount: AccountId = PolkadotXcm::check_account();
 	pub const GovernanceLocation: Location = Location::parent();
 	pub const FellowshipAdminBodyId: BodyId = BodyId::Index(xcm_constants::body::FELLOWSHIP_ADMIN_INDEX);
-	pub AssetHub: Location = (Parent, Parachain(1000)).into();
+	pub AssetHub: Location = (Parent, Parachain(ASSET_HUB_ID)).into();
 	pub const TreasurerBodyId: BodyId = BodyId::Treasury;
 	pub AssetHubUsdtId: AssetId = (PalletInstance(50), GeneralIndex(1984)).into();
 	pub UsdtAssetHub: LocatableAssetId = LocatableAssetId {
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/tests/tests.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/tests/tests.rs
index f99bc39fc83444dcaa6a886abcf2dc83db67938b..016538c35715f4cf044127197aaf3df2af5fb316 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/tests/tests.rs
@@ -17,10 +17,14 @@
 #![cfg(test)]
 
 use collectives_westend_runtime::{
-	xcm_config::LocationToAccountId, Block, Runtime, RuntimeCall, RuntimeOrigin,
+	xcm_config::{GovernanceLocation, LocationToAccountId},
+	Block, Runtime, RuntimeCall, RuntimeOrigin,
 };
+use frame_support::{assert_err, assert_ok};
 use parachains_common::AccountId;
+use parachains_runtimes_test_utils::GovernanceOrigin;
 use sp_core::crypto::Ss58Codec;
+use sp_runtime::Either;
 use xcm::latest::prelude::*;
 use xcm_runtime_apis::conversions::LocationToAccountHelper;
 
@@ -144,3 +148,54 @@ fn xcm_payment_api_works() {
 		Block,
 	>();
 }
+
+#[test]
+fn governance_authorize_upgrade_works() {
+	use westend_runtime_constants::system_parachain::{ASSET_HUB_ID, COLLECTIVES_ID};
+
+	// no - random para
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(12334)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - AssetHub
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(ASSET_HUB_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(COLLECTIVES_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives Voice of Fellows plurality
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::LocationAndDescendOrigin(
+			Location::new(1, Parachain(COLLECTIVES_ID)),
+			Plurality { id: BodyId::Technical, part: BodyPart::Voice }.into()
+		)),
+		Either::Right(XcmError::Barrier)
+	);
+
+	// ok - relaychain
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(Location::parent())));
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(GovernanceLocation::get())));
+}
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs
index bff798259dfeb1bc623a1c9508e2d3b8fa75981d..707b9a42c855871c1e6562fa4b98bf81a72e4a3e 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs
@@ -37,6 +37,7 @@ use parachains_common::{
 use polkadot_parachain_primitives::primitives::Sibling;
 use polkadot_runtime_common::xcm_sender::ExponentialPrice;
 use sp_runtime::traits::AccountIdConversion;
+use westend_runtime_constants::system_parachain::{ASSET_HUB_ID, COLLECTIVES_ID};
 use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH};
 use xcm_builder::{
 	AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter,
@@ -55,7 +56,7 @@ use xcm_executor::XcmExecutor;
 parameter_types! {
 	pub const RootLocation: Location = Location::here();
 	pub const TokenRelayLocation: Location = Location::parent();
-	pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]);
+	pub AssetHubLocation: Location = Location::new(1, [Parachain(ASSET_HUB_ID)]);
 	pub const RelayNetwork: Option<NetworkId> = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH));
 	pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
 	pub UniversalLocation: InteriorLocation =
@@ -64,7 +65,7 @@ parameter_types! {
 		PalletInstance(<Broker as PalletInfoAccess>::index() as u8).into();
 	pub const MaxInstructions: u32 = 100;
 	pub const MaxAssetsIntoHolding: u32 = 64;
-	pub FellowshipLocation: Location = Location::new(1, Parachain(1001));
+	pub FellowshipLocation: Location = Location::new(1, Parachain(COLLECTIVES_ID));
 	pub const GovernanceLocation: Location = Location::parent();
 }
 
@@ -148,7 +149,10 @@ impl Contains<Location> for ParentOrParentsPlurality {
 pub struct FellowsPlurality;
 impl Contains<Location> for FellowsPlurality {
 	fn contains(location: &Location) -> bool {
-		matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }]))
+		matches!(
+			location.unpack(),
+			(1, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }])
+		)
 	}
 }
 
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/tests/tests.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/tests/tests.rs
index f92486f369614a8e4257e404a05c1c924698af99..b8e51f2d8e7812bb193fd419c63cb6ef9aeaa85a 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/tests/tests.rs
@@ -17,10 +17,14 @@
 #![cfg(test)]
 
 use coretime_westend_runtime::{
-	xcm_config::LocationToAccountId, Block, Runtime, RuntimeCall, RuntimeOrigin,
+	xcm_config::{GovernanceLocation, LocationToAccountId},
+	Block, Runtime, RuntimeCall, RuntimeOrigin,
 };
+use frame_support::{assert_err, assert_ok};
 use parachains_common::AccountId;
+use parachains_runtimes_test_utils::GovernanceOrigin;
 use sp_core::crypto::Ss58Codec;
+use sp_runtime::Either;
 use xcm::latest::prelude::*;
 use xcm_runtime_apis::conversions::LocationToAccountHelper;
 
@@ -144,3 +148,54 @@ fn xcm_payment_api_works() {
 		Block,
 	>();
 }
+
+#[test]
+fn governance_authorize_upgrade_works() {
+	use westend_runtime_constants::system_parachain::{ASSET_HUB_ID, COLLECTIVES_ID};
+
+	// no - random para
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(12334)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - AssetHub
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(ASSET_HUB_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(COLLECTIVES_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives Voice of Fellows plurality
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::LocationAndDescendOrigin(
+			Location::new(1, Parachain(COLLECTIVES_ID)),
+			Plurality { id: BodyId::Technical, part: BodyPart::Voice }.into()
+		)),
+		Either::Right(XcmError::BadOrigin)
+	);
+
+	// ok - relaychain
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(Location::parent())));
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(GovernanceLocation::get())));
+}
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs
index bd319e3ac3b4812a00465ec5feb6b03541afe7a9..98be08379a525a8ebadb299106b1739210f5ba84 100644
--- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs
@@ -34,6 +34,7 @@ use parachains_common::{
 };
 use polkadot_parachain_primitives::primitives::Sibling;
 use sp_runtime::traits::AccountIdConversion;
+use westend_runtime_constants::system_parachain::{ASSET_HUB_ID, COLLECTIVES_ID};
 use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH};
 use xcm_builder::{
 	AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter,
@@ -52,14 +53,14 @@ use xcm_executor::XcmExecutor;
 parameter_types! {
 	pub const RootLocation: Location = Location::here();
 	pub const RelayLocation: Location = Location::parent();
-	pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]);
+	pub AssetHubLocation: Location = Location::new(1, [Parachain(ASSET_HUB_ID)]);
 	pub const RelayNetwork: Option<NetworkId> = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH));
 	pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
 	pub UniversalLocation: InteriorLocation =
 		[GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into();
 	pub const MaxInstructions: u32 = 100;
 	pub const MaxAssetsIntoHolding: u32 = 64;
-	pub FellowshipLocation: Location = Location::new(1, Parachain(1001));
+	pub FellowshipLocation: Location = Location::new(1, Parachain(COLLECTIVES_ID));
 	pub const GovernanceLocation: Location = Location::parent();
 	/// The asset ID for the asset that we use to pay for message delivery fees. Just WND.
 	pub FeeAssetId: AssetId = AssetId(RelayLocation::get());
@@ -156,7 +157,10 @@ impl Contains<Location> for ParentOrParentsPlurality {
 pub struct FellowsPlurality;
 impl Contains<Location> for FellowsPlurality {
 	fn contains(location: &Location) -> bool {
-		matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }]))
+		matches!(
+			location.unpack(),
+			(1, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }])
+		)
 	}
 }
 
diff --git a/cumulus/parachains/runtimes/people/people-westend/tests/tests.rs b/cumulus/parachains/runtimes/people/people-westend/tests/tests.rs
index 3df1558b6f9d8f211fa0c1a7c21fa6b8e329605a..3d06ab8368a65576b0e4598c0147a439e544e8d6 100644
--- a/cumulus/parachains/runtimes/people/people-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/people/people-westend/tests/tests.rs
@@ -16,11 +16,15 @@
 
 #![cfg(test)]
 
+use frame_support::{assert_err, assert_ok};
 use parachains_common::AccountId;
+use parachains_runtimes_test_utils::GovernanceOrigin;
 use people_westend_runtime::{
-	xcm_config::LocationToAccountId, Block, Runtime, RuntimeCall, RuntimeOrigin,
+	xcm_config::{GovernanceLocation, LocationToAccountId},
+	Block, Runtime, RuntimeCall, RuntimeOrigin,
 };
 use sp_core::crypto::Ss58Codec;
+use sp_runtime::Either;
 use xcm::latest::prelude::*;
 use xcm_runtime_apis::conversions::LocationToAccountHelper;
 
@@ -144,3 +148,54 @@ fn xcm_payment_api_works() {
 		Block,
 	>();
 }
+
+#[test]
+fn governance_authorize_upgrade_works() {
+	use westend_runtime_constants::system_parachain::{ASSET_HUB_ID, COLLECTIVES_ID};
+
+	// no - random para
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(12334)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - AssetHub
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(ASSET_HUB_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::Location(Location::new(1, Parachain(COLLECTIVES_ID)))),
+		Either::Right(XcmError::Barrier)
+	);
+	// no - Collectives Voice of Fellows plurality
+	assert_err!(
+		parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+			Runtime,
+			RuntimeOrigin,
+		>(GovernanceOrigin::LocationAndDescendOrigin(
+			Location::new(1, Parachain(COLLECTIVES_ID)),
+			Plurality { id: BodyId::Technical, part: BodyPart::Voice }.into()
+		)),
+		Either::Right(XcmError::BadOrigin)
+	);
+
+	// ok - relaychain
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(Location::parent())));
+	assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
+		Runtime,
+		RuntimeOrigin,
+	>(GovernanceOrigin::Location(GovernanceLocation::get())));
+}
diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs
index b46a68312aa179775bfcfc873463ed83cb91d1a1..7bbcb7beb0e79b8c2d553623e60c63e2f50e14f5 100644
--- a/cumulus/parachains/runtimes/test-utils/src/lib.rs
+++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs
@@ -34,7 +34,10 @@ use polkadot_parachain_primitives::primitives::{
 };
 use sp_consensus_aura::{SlotDuration, AURA_ENGINE_ID};
 use sp_core::{Encode, U256};
-use sp_runtime::{traits::Header, BuildStorage, Digest, DigestItem, SaturatedConversion};
+use sp_runtime::{
+	traits::{Dispatchable, Header},
+	BuildStorage, Digest, DigestItem, DispatchError, Either, SaturatedConversion,
+};
 use xcm::{
 	latest::{Asset, Location, XcmContext, XcmHash},
 	prelude::*,
@@ -47,6 +50,7 @@ pub mod test_cases;
 pub type BalanceOf<Runtime> = <Runtime as pallet_balances::Config>::Balance;
 pub type AccountIdOf<Runtime> = <Runtime as frame_system::Config>::AccountId;
 pub type RuntimeCallOf<Runtime> = <Runtime as frame_system::Config>::RuntimeCall;
+pub type RuntimeOriginOf<Runtime> = <Runtime as frame_system::Config>::RuntimeOrigin;
 pub type ValidatorIdOf<Runtime> = <Runtime as pallet_session::Config>::ValidatorId;
 pub type SessionKeysOf<Runtime> = <Runtime as pallet_session::Config>::Keys;
 
@@ -441,6 +445,10 @@ impl<
 		AllPalletsWithoutSystem,
 	> RuntimeHelper<Runtime, AllPalletsWithoutSystem>
 {
+	#[deprecated(
+		note = "Will be removed after Aug 2025; It uses hard-coded `Location::parent()`, \
+		use `execute_as_governance_call` instead."
+	)]
 	pub fn execute_as_governance(call: Vec<u8>) -> Outcome {
 		// prepare xcm as governance will do
 		let xcm = Xcm(vec![
@@ -464,6 +472,47 @@ impl<
 		)
 	}
 
+	pub fn execute_as_governance_call<Call: Dispatchable + Encode>(
+		call: Call,
+		governance_origin: GovernanceOrigin<Call::RuntimeOrigin>,
+	) -> Result<(), Either<DispatchError, XcmError>> {
+		// execute xcm as governance would send
+		let execute_xcm = |call: Call, governance_location, descend_origin| {
+			// prepare xcm
+			let xcm = if let Some(descend_origin) = descend_origin {
+				Xcm::builder_unsafe().descend_origin(descend_origin)
+			} else {
+				Xcm::builder_unsafe()
+			}
+			.unpaid_execution(Unlimited, None)
+			.transact(OriginKind::Superuser, None, call.encode())
+			.expect_transact_status(MaybeErrorCode::Success)
+			.build();
+
+			let xcm_max_weight = Self::xcm_max_weight_for_location(&governance_location);
+			let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256);
+
+			<<Runtime as pallet_xcm::Config>::XcmExecutor>::prepare_and_execute(
+				governance_location,
+				xcm,
+				&mut hash,
+				xcm_max_weight,
+				Weight::zero(),
+			)
+		};
+
+		match governance_origin {
+			GovernanceOrigin::Location(location) =>
+				execute_xcm(call, location, None).ensure_complete().map_err(Either::Right),
+			GovernanceOrigin::LocationAndDescendOrigin(location, descend_origin) =>
+				execute_xcm(call, location, Some(descend_origin))
+					.ensure_complete()
+					.map_err(Either::Right),
+			GovernanceOrigin::Origin(origin) =>
+				call.dispatch(origin).map(|_| ()).map_err(|e| Either::Left(e.error)),
+		}
+	}
+
 	pub fn execute_as_origin<Call: GetDispatchInfo + Encode>(
 		(origin, origin_kind): (Location, OriginKind),
 		call: Call,
@@ -484,23 +533,28 @@ impl<
 			ExpectTransactStatus(MaybeErrorCode::Success),
 		]);
 		let xcm = Xcm(instructions);
+		let xcm_max_weight = Self::xcm_max_weight_for_location(&origin);
 
 		// execute xcm as parent origin
 		let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256);
 		<<Runtime as pallet_xcm::Config>::XcmExecutor>::prepare_and_execute(
-			origin.clone(),
+			origin,
 			xcm,
 			&mut hash,
-			Self::xcm_max_weight(if origin == Location::parent() {
-				XcmReceivedFrom::Parent
-			} else {
-				XcmReceivedFrom::Sibling
-			}),
+			xcm_max_weight,
 			Weight::zero(),
 		)
 	}
 }
 
+/// Enum representing governance origin/location.
+#[derive(Clone)]
+pub enum GovernanceOrigin<RuntimeOrigin> {
+	Location(Location),
+	LocationAndDescendOrigin(Location, InteriorLocation),
+	Origin(RuntimeOrigin),
+}
+
 pub enum XcmReceivedFrom {
 	Parent,
 	Sibling,
@@ -515,6 +569,14 @@ impl<ParachainSystem: cumulus_pallet_parachain_system::Config, AllPalletsWithout
 			XcmReceivedFrom::Sibling => ParachainSystem::ReservedXcmpWeight::get(),
 		}
 	}
+
+	pub fn xcm_max_weight_for_location(location: &Location) -> Weight {
+		Self::xcm_max_weight(if location == &Location::parent() {
+			XcmReceivedFrom::Parent
+		} else {
+			XcmReceivedFrom::Sibling
+		})
+	}
 }
 
 impl<Runtime: frame_system::Config + pallet_xcm::Config, AllPalletsWithoutSystem>
diff --git a/cumulus/parachains/runtimes/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
index 8a7f8d6303c86b1dfe162e54c7bc0167e8e1331d..c6b1ccdac3c12f29056484bca38548983f4da2f4 100644
--- a/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
+++ b/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
@@ -16,14 +16,21 @@
 
 //! Module contains predefined test-case scenarios for `Runtime` with common functionality.
 
-use crate::{AccountIdOf, CollatorSessionKeys, ExtBuilder, ValidatorIdOf};
+use crate::{
+	AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, ExtBuilder, GovernanceOrigin,
+	RuntimeCallOf, RuntimeOriginOf, ValidatorIdOf,
+};
 use codec::Encode;
 use frame_support::{
 	assert_ok,
 	traits::{Get, OriginTrait},
 };
 use parachains_common::AccountId;
-use sp_runtime::traits::{Block as BlockT, StaticLookup};
+use sp_runtime::{
+	traits::{Block as BlockT, StaticLookup},
+	DispatchError, Either,
+};
+use xcm::prelude::XcmError;
 use xcm_runtime_apis::fees::{
 	runtime_decl_for_xcm_payment_api::XcmPaymentApiV1, Error as XcmPaymentApiError,
 };
@@ -35,7 +42,7 @@ type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
 pub fn change_storage_constant_by_governance_works<Runtime, StorageConstant, StorageConstantType>(
 	collator_session_key: CollatorSessionKeys<Runtime>,
 	runtime_para_id: u32,
-	runtime_call_encode: Box<dyn Fn(frame_system::Call<Runtime>) -> Vec<u8>>,
+	governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
 	storage_constant_key_value: fn() -> (Vec<u8>, StorageConstantType),
 	new_storage_constant_value: fn(&StorageConstantType) -> StorageConstantType,
 ) where
@@ -73,7 +80,7 @@ pub fn change_storage_constant_by_governance_works<Runtime, StorageConstant, Sto
 
 			// encode `set_storage` call
 			let set_storage_call =
-				runtime_call_encode(frame_system::Call::<Runtime>::set_storage {
+				RuntimeCallOf::<Runtime>::from(frame_system::Call::<Runtime>::set_storage {
 					items: vec![(
 						storage_constant_key.clone(),
 						new_storage_constant_value.encode(),
@@ -81,8 +88,10 @@ pub fn change_storage_constant_by_governance_works<Runtime, StorageConstant, Sto
 				});
 
 			// execute XCM with Transact to `set_storage` as governance does
-			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(set_storage_call,)
-				.ensure_complete());
+			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
+				set_storage_call,
+				governance_origin
+			));
 
 			// check delivery reward constant after (stored)
 			assert_eq!(StorageConstant::get(), new_storage_constant_value);
@@ -97,7 +106,7 @@ pub fn change_storage_constant_by_governance_works<Runtime, StorageConstant, Sto
 pub fn set_storage_keys_by_governance_works<Runtime>(
 	collator_session_key: CollatorSessionKeys<Runtime>,
 	runtime_para_id: u32,
-	runtime_call_encode: Box<dyn Fn(frame_system::Call<Runtime>) -> Vec<u8>>,
+	governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
 	storage_items: Vec<(Vec<u8>, Vec<u8>)>,
 	initialize_storage: impl FnOnce() -> (),
 	assert_storage: impl FnOnce() -> (),
@@ -123,14 +132,16 @@ pub fn set_storage_keys_by_governance_works<Runtime>(
 	});
 	runtime.execute_with(|| {
 		// encode `kill_storage` call
-		let kill_storage_call = runtime_call_encode(frame_system::Call::<Runtime>::set_storage {
-			items: storage_items.clone(),
-		});
+		let kill_storage_call =
+			RuntimeCallOf::<Runtime>::from(frame_system::Call::<Runtime>::set_storage {
+				items: storage_items.clone(),
+			});
 
 		// execute XCM with Transact to `set_storage` as governance does
-		assert_ok!(
-			RuntimeHelper::<Runtime>::execute_as_governance(kill_storage_call,).ensure_complete()
-		);
+		assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
+			kill_storage_call,
+			governance_origin
+		));
 	});
 	runtime.execute_with(|| {
 		assert_storage();
@@ -193,3 +204,33 @@ where
 		assert_eq!(execution_fees, Err(XcmPaymentApiError::AssetNotFound));
 	});
 }
+
+/// Generic test case for Cumulus-based parachain that verifies if runtime can process
+/// `frame_system::Call::authorize_upgrade` from governance system.
+pub fn can_governance_authorize_upgrade<Runtime, RuntimeOrigin>(
+	governance_origin: GovernanceOrigin<RuntimeOrigin>,
+) -> Result<(), Either<DispatchError, XcmError>>
+where
+	Runtime: BasicParachainRuntime
+		+ frame_system::Config<RuntimeOrigin = RuntimeOrigin, AccountId = AccountId>,
+{
+	ExtBuilder::<Runtime>::default().build().execute_with(|| {
+		// check before
+		assert!(frame_system::Pallet::<Runtime>::authorized_upgrade().is_none());
+
+		// execute call as governance does
+		let code_hash = Runtime::Hash::default();
+		let authorize_upgrade_call: <Runtime as frame_system::Config>::RuntimeCall =
+			frame_system::Call::<Runtime>::authorize_upgrade { code_hash }.into();
+		RuntimeHelper::<Runtime>::execute_as_governance_call(
+			authorize_upgrade_call,
+			governance_origin,
+		)?;
+
+		// check after
+		match frame_system::Pallet::<Runtime>::authorized_upgrade() {
+			None => Err(Either::Left(frame_system::Error::<Runtime>::NothingAuthorized.into())),
+			Some(_) => Ok(()),
+		}
+	})
+}
diff --git a/prdoc/pr_7656.prdoc b/prdoc/pr_7656.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..80a62c284daa10280c26ec2aad26246980159dbe
--- /dev/null
+++ b/prdoc/pr_7656.prdoc
@@ -0,0 +1,25 @@
+title: Authorize upgrade tests for testnet runtimes + `execute_as_governance` refactor
+doc:
+- audience: Runtime Dev
+  description: |-
+    This PR contains improved test cases that rely on the governance location as preparation for AHM to capture the state as it is.
+    It introduces `execute_as_governance_call`, which can be configured with various governance location setups instead of the hard-coded `Location::parent()`.
+crates:
+- name: parachains-runtimes-test-utils
+  bump: major
+- name: asset-hub-westend-runtime
+  bump: patch
+- name: bridge-hub-westend-runtime
+  bump: minor
+- name: collectives-westend-runtime
+  bump: patch
+- name: coretime-westend-runtime
+  bump: patch
+- name: people-westend-runtime
+  bump: patch
+- name: asset-hub-rococo-runtime
+  bump: patch
+- name: bridge-hub-rococo-runtime
+  bump: patch
+- name: bridge-hub-test-utils
+  bump: major