diff --git a/domain.te b/domain.te
index a317050842b901f8cc6e340398f03045031eead6..f5078c0a5847eabc6b5f1860b7edd26aa995b02d 100644
--- a/domain.te
+++ b/domain.te
@@ -304,6 +304,7 @@ neverallow domain { cache_file cache_backup_file }:file execute;
 neverallow {
   domain
   -untrusted_app
+  -priv_app
   -shell
 } {
   data_file_type
diff --git a/priv_app.te b/priv_app.te
new file mode 100644
index 0000000000000000000000000000000000000000..ff47f8e8f4eb481a5b5846b5cd2847873ff1fed4
--- /dev/null
+++ b/priv_app.te
@@ -0,0 +1,93 @@
+###
+### A domain for further sandboxing privileged apps.
+###
+type priv_app, domain;
+app_domain(priv_app)
+# Access the network.
+net_domain(priv_app)
+# Access bluetooth.
+bluetooth_domain(priv_app)
+
+# Some apps ship with shared libraries and binaries that they write out
+# to their sandbox directory and then execute.
+allow priv_app app_data_file:file rx_file_perms;
+
+# Allow the allocation and use of ptys
+# Used by: https://play.privileged.com/store/apps/details?id=jackpal.androidterm
+create_pty(priv_app)
+
+allow priv_app drmserver_service:service_manager find;
+allow priv_app mediaserver_service:service_manager find;
+allow priv_app nfc_service:service_manager find;
+allow priv_app radio_service:service_manager find;
+allow priv_app surfaceflinger_service:service_manager find;
+allow priv_app app_api_service:service_manager find;
+allow priv_app system_api_service:service_manager find;
+allow priv_app persistent_data_block_service:service_manager find;
+
+# Traverse into /mnt/media_rw for bypassing FUSE daemon
+# TODO: narrow this to just MediaProvider
+allow priv_app mnt_media_rw_file:dir search;
+
+# Access to /data/media.
+allow priv_app media_rw_data_file:dir create_dir_perms;
+allow priv_app media_rw_data_file:file create_file_perms;
+
+# Used by Finsky / Android "Verify Apps" functionality when
+# running "adb install foo.apk".
+allow priv_app shell_data_file:file r_file_perms;
+allow priv_app shell_data_file:dir r_dir_perms;
+
+# b/18504118: Allow reads from /data/anr/traces.txt
+allow priv_app anr_data_file:file r_file_perms;
+
+# Allow GMS core to access perfprofd output, which is stored
+# in /data/misc/perfprofd/. GMS core will need to list all
+# data stored in that directory to process them one by one.
+userdebug_or_eng(`
+  allow priv_app perfprofd_data_file:file r_file_perms;
+  allow priv_app perfprofd_data_file:dir r_dir_perms;
+')
+
+###
+### neverallow rules
+###
+
+# Receive or send uevent messages.
+neverallow priv_app domain:netlink_kobject_uevent_socket *;
+
+# Receive or send generic netlink messages
+neverallow priv_app domain:netlink_socket *;
+
+# Too much leaky information in debugfs. It's a security
+# best practice to ensure these files aren't readable.
+neverallow priv_app debugfs:file read;
+
+# Do not allow privileged apps to register services.
+# Only trusted components of Android should be registering
+# services.
+neverallow priv_app service_manager_type:service_manager add;
+
+# Do not allow privileged apps to connect to the property service
+# or set properties. b/10243159
+neverallow priv_app property_socket:sock_file write;
+neverallow priv_app init:unix_stream_socket connectto;
+neverallow priv_app property_type:property_service set;
+
+# Do not allow priv_app to be assigned mlstrustedsubject.
+# This would undermine the per-user isolation model being
+# enforced via levelFrom=user in seapp_contexts and the mls
+# constraints.  As there is no direct way to specify a neverallow
+# on attribute assignment, this relies on the fact that fork
+# permission only makes sense within a domain (hence should
+# never be granted to any other domain within mlstrustedsubject)
+# and priv_app is allowed fork permission to itself.
+neverallow priv_app mlstrustedsubject:process fork;
+
+# Do not allow priv_app to hard link to any files.
+# In particular, if priv_app links to other app data
+# files, installd will not be able to guarantee the deletion
+# of the linked to file. Hard links also contribute to security
+# bugs, so we want to ensure priv_app never has this
+# capability.
+neverallow priv_app file_type:file link;
diff --git a/seapp_contexts b/seapp_contexts
index b0c61cfed7864165042071fb971e783f06fc28fc..d8d224038188409bd36c9b21e14ff86e73dc9063 100644
--- a/seapp_contexts
+++ b/seapp_contexts
@@ -5,6 +5,7 @@
 #	seinfo (string)
 #	name (string)
 #	path (string)
+#	isPrivApp (boolean)
 # isSystemServer=true can only be used once.
 # An unspecified isSystemServer defaults to false.
 # isOwner=true will only match for the owner/primary user.
@@ -14,6 +15,8 @@
 # A user string selector that ends in * will perform a prefix match.
 # user=_app will match any regular app UID.
 # user=_isolated will match any isolated service UID.
+# isPrivApp=true will only match for applications preinstalled in
+#       /system/priv-app.
 # All specified input selectors in an entry must match (i.e. logical AND).
 # Matching is case-insensitive.
 #
@@ -24,8 +27,10 @@
 #	  (4) Fixed user= string before user= prefix (i.e. ending in *).
 #	  (5) Longer user= prefix before shorter user= prefix.
 #	  (6) Specified seinfo= string before unspecified seinfo= string.
+#	      ':' character is reserved and may not be used.
 #	  (7) Specified name= string before unspecified name= string.
 #	  (8) Specified path= string before unspecified path= string.
+# 	  (9) Specified isPrivApp= before unspecified isPrivApp= boolean.
 #
 # Outputs:
 #	domain (string)
@@ -83,4 +88,5 @@ user=shared_relro domain=shared_relro
 user=shell seinfo=platform domain=shell type=shell_data_file
 user=_isolated domain=isolated_app levelFrom=user
 user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
+user=_app isPrivApp=true domain=priv_app type=app_data_file levelFrom=user
 user=_app domain=untrusted_app type=app_data_file levelFrom=user
diff --git a/tools/check_seapp.c b/tools/check_seapp.c
index ae4f7e3e03d9b4c9641e02029c6b1235f33a91f9..5a03b7f365884a379dfb944f71db3eb7b9152cba 100644
--- a/tools/check_seapp.c
+++ b/tools/check_seapp.c
@@ -209,6 +209,7 @@ key_map rules[] = {
                 { .name = "seinfo",         .type = dt_string, .dir = dir_in,  .data = NULL },
                 { .name = "name",           .type = dt_string, .dir = dir_in,  .data = NULL },
                 { .name = "path",           .type = dt_string, .dir = dir_in,  .data = NULL },
+                { .name = "isPrivApp",      .type = dt_bool,   .dir = dir_in,  .data = NULL },
                 /*Outputs*/
                 { .name = "domain",         .type = dt_string, .dir = dir_out, .data = NULL },
                 { .name = "type",           .type = dt_string, .dir = dir_out, .data = NULL },