diff --git a/private/compat/26.0/26.0.ignore.cil b/private/compat/26.0/26.0.ignore.cil
index de0cc7987b49b2358cf9fedee0c1544cca778b12..91724c07949c465f14839afd37660cc304640719 100644
--- a/private/compat/26.0/26.0.ignore.cil
+++ b/private/compat/26.0/26.0.ignore.cil
@@ -135,6 +135,7 @@
     property_info
     recovery_socket
     role_service
+    runas_app
     runtime_service
     secure_element
     secure_element_device
diff --git a/private/compat/27.0/27.0.ignore.cil b/private/compat/27.0/27.0.ignore.cil
index 429725c70e0bc95f24184161c252b6cb259d69cc..ff1c8578189c254b8d37252f07f0e31f70110943 100644
--- a/private/compat/27.0/27.0.ignore.cil
+++ b/private/compat/27.0/27.0.ignore.cil
@@ -122,6 +122,7 @@
     property_info
     recovery_socket
     role_service
+    runas_app
     runtime_service
     secure_element
     secure_element_device
diff --git a/private/compat/28.0/28.0.ignore.cil b/private/compat/28.0/28.0.ignore.cil
index 9133c44916709be32713f77d0c4eb5422f6911df..58e936c311bc41c4acf2c33341b65101c063cc75 100644
--- a/private/compat/28.0/28.0.ignore.cil
+++ b/private/compat/28.0/28.0.ignore.cil
@@ -73,6 +73,7 @@
     rs_exec
     rss_hwm_reset
     rss_hwm_reset_exec
+    runas_app
     runtime_service
     sensor_privacy_service
     server_configurable_flags_data_file
diff --git a/private/runas_app.te b/private/runas_app.te
index b976b91879ed85a34e98e032c07ce622e1f76537..638702c7e136330825d2cb8b1e6c4d071ed0571f 100644
--- a/private/runas_app.te
+++ b/private/runas_app.te
@@ -1,4 +1,3 @@
-type runas_app, domain;
 typeattribute runas_app coredomain;
 
 app_domain(runas_app)
@@ -7,5 +6,12 @@ net_domain(runas_app)
 bluetooth_domain(runas_app)
 
 # The ability to call exec() on files in the apps home directories
-# when using run-as on a debuggable app. Needed by simpleperf.
+# when using run-as on a debuggable app. Used to run lldb/ndk-gdb/simpleperf,
+# which are copied to the apps home directories.
 allow runas_app app_data_file:file execute_no_trans;
+
+# Allow lldb/ndk-gdb/simpleperf to read maps of debuggable app processes.
+r_dir_file(runas_app, untrusted_app_all)
+
+# Allow lldb/ndk-gdb/simpleperf to ptrace attach to debuggable app processes.
+allow runas_app untrusted_app_all:process ptrace;
diff --git a/private/seapp_contexts b/private/seapp_contexts
index 14a8bff53b15016718ae9ee26a22f45bbaa887f3..9fc6816e8da09783ff71dc6eb0f66762b8b475b9 100644
--- a/private/seapp_contexts
+++ b/private/seapp_contexts
@@ -122,4 +122,5 @@ user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFr
 user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all
 user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file levelFrom=user
 user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user
-user=_app fromRunAs=true domain=runas_app levelFrom=all
+user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all
+user=_app fromRunAs=true domain=runas_app levelFrom=user
diff --git a/public/runas_app.te b/public/runas_app.te
new file mode 100644
index 0000000000000000000000000000000000000000..cdaa799c9dca37761bd00d5617467bea399adcb6
--- /dev/null
+++ b/public/runas_app.te
@@ -0,0 +1 @@
+type runas_app, domain;
diff --git a/public/te_macros b/public/te_macros
index c70e7db38d1a3a27bcbc0776557fba935fce97b8..149d5ac22d8b6ffbdb50f1eb93512986ceb9d499 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -176,15 +176,16 @@ typeattribute $1 appdomain;
 tmpfs_domain($1)
 # Map with PROT_EXEC.
 allow $1 $1_tmpfs:file execute;
-neverallow { $1 -shell } { domain -$1 }:file no_rw_file_perms;
-neverallow { appdomain -shell -$1 } $1:file no_rw_file_perms;
+neverallow { $1 -runas_app -shell } { domain -$1 }:file no_rw_file_perms;
+neverallow { appdomain -runas_app -shell -$1 } $1:file no_rw_file_perms;
 # The Android security model guarantees the confidentiality and integrity
 # of application data and execution state. Ptrace bypasses those
 # confidentiality guarantees. Disallow ptrace access from system components
 # to apps. Crash_dump is excluded, as it needs ptrace access to
 # produce stack traces.  llkd is excluded, as it needs to inspect
-# the kernel stack for live lock conditions.
-neverallow { domain -$1 -crash_dump userdebug_or_eng(`-llkd') } $1:process ptrace;
+# the kernel stack for live lock conditions. runas_app is excluded, as it can
+# only access debuggable apps.
+neverallow { domain -$1 -crash_dump userdebug_or_eng(`-llkd') -runas_app } $1:process ptrace;
 ')
 
 #####################################