diff --git a/private/hal_audio_default.te b/private/hal_audio_default.te
index bbbd419274b2a1489ad2a1044de54744cdd4f095..93ffd8e51ef0464f46d0d7896abf7e0a63ad26d3 100644
--- a/private/hal_audio_default.te
+++ b/private/hal_audio_default.te
@@ -1,4 +1,5 @@
-type hal_audio_default, hal_audio, domain;
-type hal_audio_default_exec, exec_type, file_type;
+type hal_audio_default, domain;
+hal_impl_domain(hal_audio_default, hal_audio)
 
+type hal_audio_default_exec, exec_type, file_type;
 init_daemon_domain(hal_audio_default)
diff --git a/private/hal_bluetooth_default.te b/private/hal_bluetooth_default.te
index f77410cf3439b0df9f2ed7d87cea3c2f4eace5ad..b8fce63e189762ded029199e1586a400103c19ab 100644
--- a/private/hal_bluetooth_default.te
+++ b/private/hal_bluetooth_default.te
@@ -1,6 +1,7 @@
-type hal_bluetooth_default, hal_bluetooth, domain;
-type hal_bluetooth_default_exec, exec_type, file_type;
+type hal_bluetooth_default, domain;
+hal_impl_domain(hal_bluetooth_default, hal_bluetooth)
 
+type hal_bluetooth_default_exec, exec_type, file_type;
 init_daemon_domain(hal_bluetooth_default)
 
 # VTS tests need to be able to toggle rfkill
diff --git a/private/hal_contexthub_default.te b/private/hal_contexthub_default.te
index 99b6b93760454ba6f6bbd68b7662c3c3617a888c..abf5b0e3be3c93b327662d6eed1a4b325f3eacfc 100644
--- a/private/hal_contexthub_default.te
+++ b/private/hal_contexthub_default.te
@@ -1,4 +1,5 @@
-type hal_contexthub_default, hal_contexthub, domain;
-type hal_contexthub_default_exec, exec_type, file_type;
+type hal_contexthub_default, domain;
+hal_impl_domain(hal_contexthub_default, hal_contexthub)
 
+type hal_contexthub_default_exec, exec_type, file_type;
 init_daemon_domain(hal_contexthub_default)
diff --git a/private/hal_dumpstate_default.te b/private/hal_dumpstate_default.te
index 46160397b604fefa4bc6587288e3b408758bb109..2b371b9a6d968b39cb4699218ac874fdc6d88186 100644
--- a/private/hal_dumpstate_default.te
+++ b/private/hal_dumpstate_default.te
@@ -1,4 +1,5 @@
-type hal_dumpstate_default, hal_dumpstate, domain;
-type hal_dumpstate_default_exec, exec_type, file_type;
+type hal_dumpstate_default, domain;
+hal_impl_domain(hal_dumpstate_default, hal_dumpstate)
 
+type hal_dumpstate_default_exec, exec_type, file_type;
 init_daemon_domain(hal_dumpstate_default)
diff --git a/private/hal_fingerprint_default.te b/private/hal_fingerprint_default.te
index 3903f85331e5195ccb9637464bd510453b35664f..c392a858319c2dfa621610642828b81d943f64e1 100644
--- a/private/hal_fingerprint_default.te
+++ b/private/hal_fingerprint_default.te
@@ -1,5 +1,5 @@
-type hal_fingerprint_default, hal_fingerprint, domain;
+type hal_fingerprint_default, domain;
+hal_impl_domain(hal_fingerprint_default, hal_fingerprint)
+
 type hal_fingerprint_default_exec, exec_type, file_type;
-# type_transition must be private policy the domain_trans rules could stay
-# public, but conceptually should go with this
 init_daemon_domain(hal_fingerprint_default)
diff --git a/private/hal_gatekeeper_default.te b/private/hal_gatekeeper_default.te
index e0c5613367c5dff117391d95e2530b9c70757337..3c84b1378c2e98773b2a888d842aaa3dae6d3431 100644
--- a/private/hal_gatekeeper_default.te
+++ b/private/hal_gatekeeper_default.te
@@ -1,4 +1,5 @@
-type hal_gatekeeper_default, hal_gatekeeper, domain;
-type hal_gatekeeper_default_exec, exec_type, file_type;
+type hal_gatekeeper_default, domain;
+hal_impl_domain(hal_gatekeeper_default, hal_gatekeeper)
 
+type hal_gatekeeper_default_exec, exec_type, file_type;
 init_daemon_domain(hal_gatekeeper_default);
diff --git a/private/hal_gnss_default.te b/private/hal_gnss_default.te
index 29ff994116bd980e828cef1e2a67b514de6230d6..78f85bcf1fce7baa74c3b72c118534f84a1c6e06 100644
--- a/private/hal_gnss_default.te
+++ b/private/hal_gnss_default.te
@@ -1,6 +1,7 @@
-type hal_gnss_default, hal_gnss, domain;
-type hal_gnss_default_exec, exec_type, file_type;
+type hal_gnss_default, domain;
+hal_impl_domain(hal_gnss_default, hal_gnss)
 
+type hal_gnss_default_exec, exec_type, file_type;
 init_daemon_domain(hal_gnss_default)
 
 # Read access to system files for HALs in
diff --git a/private/hal_graphics_allocator_default.te b/private/hal_graphics_allocator_default.te
index 36dcca30fc409221207e21083edb50a625993ae0..6b3672cf953ff8b650b62bea6e0695a563f401b1 100644
--- a/private/hal_graphics_allocator_default.te
+++ b/private/hal_graphics_allocator_default.te
@@ -1,4 +1,5 @@
-type hal_graphics_allocator_default, hal_graphics_allocator, domain;
-type hal_graphics_allocator_default_exec, exec_type, file_type;
+type hal_graphics_allocator_default, domain;
+hal_impl_domain(hal_graphics_allocator_default, hal_graphics_allocator)
 
+type hal_graphics_allocator_default_exec, exec_type, file_type;
 init_daemon_domain(hal_graphics_allocator_default)
diff --git a/private/hal_graphics_composer_default.te b/private/hal_graphics_composer_default.te
index 9ddf71f1381ab5b7dfaeae2293dd53a9e2b94eb4..99bf690fccef63167ed993c177606a292d0aa4dc 100644
--- a/private/hal_graphics_composer_default.te
+++ b/private/hal_graphics_composer_default.te
@@ -1,4 +1,5 @@
-type hal_graphics_composer_default, hal_graphics_composer, domain;
-type hal_graphics_composer_default_exec, exec_type, file_type;
+type hal_graphics_composer_default, domain;
+hal_impl_domain(hal_graphics_composer_default, hal_graphics_composer)
 
+type hal_graphics_composer_default_exec, exec_type, file_type;
 init_daemon_domain(hal_graphics_composer_default)
diff --git a/private/hal_health_default.te b/private/hal_health_default.te
index e853fb6f1175da8a5d39c6c3086d5fff08ee4369..0496cdf0157c7ef7a98b8ebd7b948c8e877b9b2e 100644
--- a/private/hal_health_default.te
+++ b/private/hal_health_default.te
@@ -1,5 +1,6 @@
 # health info abstraction
-type hal_health_default, hal_health, domain;
-type hal_health_default_exec, exec_type, file_type;
+type hal_health_default, domain;
+hal_impl_domain(hal_health_default, hal_health)
 
+type hal_health_default_exec, exec_type, file_type;
 init_daemon_domain(hal_health_default)
diff --git a/private/hal_ir_default.te b/private/hal_ir_default.te
index 1f3d694bf7db7915f69c5c2b3e8b5bf920712825..2de1b9285269fa5ed01b7fbf8ba372c23299a79d 100644
--- a/private/hal_ir_default.te
+++ b/private/hal_ir_default.te
@@ -1,4 +1,5 @@
-type hal_ir_default, hal_ir, domain;
-type hal_ir_default_exec, exec_type, file_type;
+type hal_ir_default, domain;
+hal_impl_domain(hal_ir_default, hal_ir)
 
+type hal_ir_default_exec, exec_type, file_type;
 init_daemon_domain(hal_ir_default)
diff --git a/private/hal_light_default.te b/private/hal_light_default.te
index aee44d9cf319158d771bd7e25f7bc4e8d0e9a4a1..bee7c8a533d1386097df92c2647a96d8348377b4 100644
--- a/private/hal_light_default.te
+++ b/private/hal_light_default.te
@@ -1,4 +1,5 @@
-type hal_light_default, hal_light, domain;
-type hal_light_default_exec, exec_type, file_type;
+type hal_light_default, domain;
+hal_impl_domain(hal_light_default, hal_light)
 
+type hal_light_default_exec, exec_type, file_type;
 init_daemon_domain(hal_light_default)
diff --git a/private/hal_memtrack_default.te b/private/hal_memtrack_default.te
index 113ee18711695f77b95ac635d7f93e03e81de485..1c5ca99de64fe0467f6f606d0b6f1e3c9fbcf26b 100644
--- a/private/hal_memtrack_default.te
+++ b/private/hal_memtrack_default.te
@@ -1,4 +1,5 @@
-type hal_memtrack_default, hal_memtrack, domain;
-type hal_memtrack_default_exec, exec_type, file_type;
+type hal_memtrack_default, domain;
+hal_impl_domain(hal_memtrack_default, hal_memtrack)
 
+type hal_memtrack_default_exec, exec_type, file_type;
 init_daemon_domain(hal_memtrack_default)
diff --git a/private/hal_nfc_default.te b/private/hal_nfc_default.te
index 1f7c4ed7a519a4f84b6b692f58872bdc1f849da9..b6abb1958303937d27c80e8f36952e7e1f10a481 100644
--- a/private/hal_nfc_default.te
+++ b/private/hal_nfc_default.te
@@ -1,4 +1,5 @@
-type hal_nfc_default, hal_nfc, domain;
-type hal_nfc_default_exec, exec_type, file_type;
+type hal_nfc_default, domain;
+hal_impl_domain(hal_nfc_default, hal_nfc)
 
+type hal_nfc_default_exec, exec_type, file_type;
 init_daemon_domain(hal_nfc_default)
diff --git a/private/hal_power_default.te b/private/hal_power_default.te
index e61375d4017ff480b35f12106cb70dbea3ad71e2..c8977eedb183b626c76643d54e50bf7e005f705f 100644
--- a/private/hal_power_default.te
+++ b/private/hal_power_default.te
@@ -1,4 +1,5 @@
-type hal_power_default, hal_power, domain;
-type hal_power_default_exec, exec_type, file_type;
+type hal_power_default, domain;
+hal_impl_domain(hal_power_default, hal_power)
 
+type hal_power_default_exec, exec_type, file_type;
 init_daemon_domain(hal_power_default)
diff --git a/private/hal_sensors_default.te b/private/hal_sensors_default.te
index 5f294466998ba80b3bad67423f18c5ef083f0b5a..3c3a104a6366966e3f17adad7eed331ed068691b 100644
--- a/private/hal_sensors_default.te
+++ b/private/hal_sensors_default.te
@@ -1,4 +1,5 @@
-type hal_sensors_default, hal_sensors, domain;
-type hal_sensors_default_exec, exec_type, file_type;
+type hal_sensors_default, domain;
+hal_impl_domain(hal_sensors_default, hal_sensors)
 
+type hal_sensors_default_exec, exec_type, file_type;
 init_daemon_domain(hal_sensors_default)
diff --git a/private/hal_thermal_default.te b/private/hal_thermal_default.te
index a2ff70e167f4beaae5f20938e628020cb91a40a5..baa3b97ab39ed0fabb0806f5c84ab49191361ec8 100644
--- a/private/hal_thermal_default.te
+++ b/private/hal_thermal_default.te
@@ -1,4 +1,5 @@
-type hal_thermal_default, hal_thermal, domain;
-type hal_thermal_default_exec, exec_type, file_type;
+type hal_thermal_default, domain;
+hal_impl_domain(hal_thermal_default, hal_thermal)
 
+type hal_thermal_default_exec, exec_type, file_type;
 init_daemon_domain(hal_thermal_default)
diff --git a/private/hal_vibrator_default.te b/private/hal_vibrator_default.te
index e6339537e75aa7b8e3ad791513d023e7fc898729..c185e0862e56821a104bf87b582b2e6f13bdd111 100644
--- a/private/hal_vibrator_default.te
+++ b/private/hal_vibrator_default.te
@@ -1,4 +1,5 @@
-type hal_vibrator_default, hal_vibrator, domain;
-type hal_vibrator_default_exec, exec_type, file_type;
+type hal_vibrator_default, domain;
+hal_impl_domain(hal_vibrator_default, hal_vibrator)
 
+type hal_vibrator_default_exec, exec_type, file_type;
 init_daemon_domain(hal_vibrator_default)
diff --git a/private/hal_vr_default.te b/private/hal_vr_default.te
index ba85157a589c8f597aa397be21ccbc85ba0a8c46..f32c737c18132508a1b45b48f195263094481b0c 100644
--- a/private/hal_vr_default.te
+++ b/private/hal_vr_default.te
@@ -1,4 +1,5 @@
-type hal_vr_default, hal_vr, domain;
-type hal_vr_default_exec, exec_type, file_type;
+type hal_vr_default, domain;
+hal_impl_domain(hal_vr_default, hal_vr)
 
+type hal_vr_default_exec, exec_type, file_type;
 init_daemon_domain(hal_vr_default)
diff --git a/private/hal_wifi_default.te b/private/hal_wifi_default.te
index a32a9070a19c2fae01711aec2c7f46ee16a86e20..5946ba43f05f7ae059205d111b68d759cd53a2c4 100644
--- a/private/hal_wifi_default.te
+++ b/private/hal_wifi_default.te
@@ -1,4 +1,5 @@
-type hal_wifi_default, hal_wifi, domain;
-type hal_wifi_default_exec, exec_type, file_type;
+type hal_wifi_default, domain;
+hal_impl_domain(hal_wifi_default, hal_wifi)
 
+type hal_wifi_default_exec, exec_type, file_type;
 init_daemon_domain(hal_wifi_default)
diff --git a/private/haldomain.te b/private/haldomain.te
new file mode 100644
index 0000000000000000000000000000000000000000..511f78dc9c28f3e30862abcc0cd838cb1d52b547
--- /dev/null
+++ b/private/haldomain.te
@@ -0,0 +1,3 @@
+###
+### Rules for all HAL implementations
+###
diff --git a/public/attributes b/public/attributes
index 30a6014ccf8643a7897941fc10844fd34a114469..66cc594032b593fd2bb0c58a399b830dd67449ce 100644
--- a/public/attributes
+++ b/public/attributes
@@ -114,6 +114,9 @@ attribute boot_control_hal;
 # recovery for A/B devices.
 attribute update_engine_common;
 
+# All domains used for HAL implementations
+attribute haldomain;
+
 # HALs
 attribute hal_audio;
 attribute hal_bluetooth;
diff --git a/public/hal_allocator.te b/public/hal_allocator.te
index 784bacbce58a02f40f130f4c9c8936d1c13d1a37..0f3983bdf5aaa432c063a7a7d349aa72c3ce5fa0 100644
--- a/public/hal_allocator.te
+++ b/public/hal_allocator.te
@@ -1,5 +1,5 @@
 # allocator subsystem
-type hal_allocator, domain;
+type hal_allocator, domain, haldomain;
 type hal_allocator_exec, exec_type, file_type;
 
 # hwbinder access
diff --git a/public/hal_boot.te b/public/hal_boot.te
index 3cbbb2916329f2d9cd93acca4dd0c9ce3fe0278a..d04ced28b2e388f11ab82f7672be98e46ae1560e 100644
--- a/public/hal_boot.te
+++ b/public/hal_boot.te
@@ -1,5 +1,5 @@
 # boot_control subsystem
-type hal_boot, domain, boot_control_hal;
+type hal_boot, domain, boot_control_hal, haldomain;
 type hal_boot_exec, exec_type, file_type;
 
 # hwbinder access
diff --git a/public/te_macros b/public/te_macros
index 70f0fdf2ec7ec0a2b672cbca9633a18b8f8e054a..d1267ec2d5a591a10bbee688633249e6896d04fe 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -115,6 +115,20 @@ define(`bluetooth_domain', `
 typeattribute $1 bluetoothdomain;
 ')
 
+#####################################
+# hal_impl_domain(domain, hal_type_attr)
+# Allow a base set of permissions required for a domain to host a
+# HAL implementation of the specified HAL type.
+#
+# For example, default implementation of Foo HAL:
+#   type hal_foo_default, domain;
+#   hal_impl_domain(hal_foo_default, hal_foo)
+#
+define(`hal_impl_domain', `
+typeattribute $1 haldomain;
+typeattribute $1 $2;
+')
+
 #####################################
 # unix_socket_connect(clientdomain, socket, serverdomain)
 # Allow a local socket connection from clientdomain via