diff --git a/te_macros b/te_macros
index 9313938240578ede9d0e9ea4eb14a589df23353d..9f885bf4fe1437416f6600207849349a162bb96b 100644
--- a/te_macros
+++ b/te_macros
@@ -306,6 +306,20 @@ allow $1 klog_device:chr_file { create open write unlink };
 allow $1 device:dir { write add_name remove_name };
 ')
 
+#####################################
+# create_pty(domain)
+# Allow domain to create and use a pty, isolated from any other domain ptys.
+define(`create_pty', `
+# Each domain gets a unique devpts type.
+type $1_devpts, fs_type;
+# Label the pty with the unique type when created.
+type_transition $1 devpts:chr_file $1_devpts;
+# Allow use of the pty after creation.
+allow $1 $1_devpts:chr_file { open getattr read write ioctl };
+# Note: devpts:dir search and ptmx_device:chr_file rw_file_perms
+# allowed to everyone via domain.te.
+')
+
 #####################################
 # Non system_app application set
 #
diff --git a/untrusted_app.te b/untrusted_app.te
index c91543ed86932065570537c8f41e74f13722cafb..80f60da604336cfca4da08911968bb36e54c2510 100644
--- a/untrusted_app.te
+++ b/untrusted_app.te
@@ -38,7 +38,7 @@ allow untrusted_app port:{ tcp_socket udp_socket } name_bind;
 
 # Allow the allocation and use of ptys
 # Used by: https://play.google.com/store/apps/details?id=jackpal.androidterm
-allow untrusted_app devpts:chr_file rw_file_perms;
+create_pty(untrusted_app)
 
 # Used by Finsky / Android "Verify Apps" functionality when
 # running "adb install foo.apk".