diff --git a/domain.te b/domain.te
index 86c683f23e1bb57ebb2441070afbe61e7e8fe305..466e48a470c5a8a2cf6bb0cde6345544ea83b70e 100644
--- a/domain.te
+++ b/domain.te
@@ -11,7 +11,23 @@ allow domain tmpfs:file { read getattr };
 allow domain tmpfs:dir r_dir_perms;
 
 # Intra-domain accesses.
-allow domain self:process ~{ execmem execstack execheap ptrace setexec setfscreate setcurrent setkeycreate setsockcreate };
+allow domain self:process {
+    fork
+    sigchld
+    sigkill
+    sigstop
+    signull
+    signal
+    getsched
+    setsched
+    getsession
+    getpgid
+    setpgid
+    getcap
+    setcap
+    getattr
+    setrlimit
+};
 allow domain self:fd use;
 allow domain self:dir r_dir_perms;
 allow domain self:lnk_file r_file_perms;
diff --git a/init.te b/init.te
index e4d1f88aa3c242105c961ad77e7e35f223d2fde1..3f4d706c87ad1392b20af06497373ff83eaff356 100644
--- a/init.te
+++ b/init.te
@@ -76,3 +76,13 @@ allow init self:process { setexec setfscreate setsockcreate };
 # Create /data/property and files within it.
 allow init property_data_file:dir create_dir_perms;
 allow init property_data_file:file create_file_perms;
+
+###
+### neverallow rules
+###
+
+# The init domain is only entered via setcon from the kernel domain,
+# never via an exec-based transition.
+neverallow { domain -kernel} init:process dyntransition;
+neverallow domain init:process transition;
+neverallow init { file_type fs_type }:file entrypoint;
diff --git a/kernel.te b/kernel.te
index 0de0ab894424c7d71b1b75953b103ab7593b28cb..08ccbf59c74f8d317c887f9c0ec909097050b896 100644
--- a/kernel.te
+++ b/kernel.te
@@ -30,3 +30,11 @@ dontaudit kernel self:security setenforce;
 
 # Set checkreqprot by init.rc prior to switching to init domain.
 allow kernel self:security setcheckreqprot;
+
+###
+### neverallow rules
+###
+
+# The initial task starts in the kernel domain (assigned via
+# initial_sid_contexts), but nothing ever transitions to it.
+neverallow domain kernel:process { transition dyntransition };