diff --git a/policy/modules/services/rootlesskit.fc b/policy/modules/services/rootlesskit.fc
new file mode 100644
index 000000000..613ebd9b9
--- /dev/null
+++ b/policy/modules/services/rootlesskit.fc
@@ -0,0 +1,3 @@
+/usr/bin/rootlesskit -- gen_context(system_u:object_r:rootlesskit_exec_t,s0)
+/usr/bin/rootlessctl -- gen_context(system_u:object_r:rootlesskit_exec_t,s0)
+/usr/bin/rootlesskit-docker-proxy -- gen_context(system_u:object_r:rootlesskit_exec_t,s0)
diff --git a/policy/modules/services/rootlesskit.if b/policy/modules/services/rootlesskit.if
new file mode 100644
index 000000000..2be598d70
--- /dev/null
+++ b/policy/modules/services/rootlesskit.if
@@ -0,0 +1,106 @@
+## Policy for RootlessKit
+
+########################################
+##
+## Execute rootlesskit in the caller domain.
+##
+##
+##
+## Domain allowed access.
+##
+##
+#
+interface(`rootlesskit_exec',`
+ gen_require(`
+ type rootlesskit_exec_t;
+ ')
+
+ can_exec($1, rootlesskit_exec_t)
+')
+
+########################################
+##
+## Execute rootlesskit in the rootlesskit domain.
+##
+##
+##
+## Domain allowed to transition.
+##
+##
+#
+interface(`rootlesskit_domtrans',`
+ gen_require(`
+ type rootlesskit_t, rootlesskit_exec_t;
+ ')
+
+ corecmd_search_bin($1)
+ domtrans_pattern($1, rootlesskit_exec_t, rootlesskit_t)
+')
+
+########################################
+##
+## Execute rootlesskit in the rootlesskit
+## domain, and allow the specified role
+## the rootlesskit domain.
+##
+##
+##
+## Domain allowed to transition.
+##
+##
+##
+##
+## The role to be allowed the rootlesskit domain.
+##
+##
+#
+interface(`rootlesskit_run',`
+ gen_require(`
+ type rootlesskit_t;
+ ')
+
+ role $2 types rootlesskit_t;
+
+ rootlesskit_domtrans($1)
+')
+
+########################################
+##
+## Role access for rootlesskit.
+##
+##
+##
+## The prefix of the user role (e.g., user
+## is the prefix for user_r).
+##
+##
+##
+##
+## User domain for the role.
+##
+##
+##
+##
+## User exec domain for execute and transition access.
+##
+##
+##
+##
+## Role allowed access.
+##
+##
+##
+#
+template(`rootlesskit_role',`
+ gen_require(`
+ type rootlesskit_t;
+ type rootlesskit_exec_t;
+ ')
+
+ rootlesskit_run($3, $4)
+
+ optional_policy(`
+ systemd_user_daemon_domain($1, rootlesskit_exec_t, rootlesskit_t)
+ ')
+')
+
diff --git a/policy/modules/services/rootlesskit.te b/policy/modules/services/rootlesskit.te
new file mode 100644
index 000000000..31168801d
--- /dev/null
+++ b/policy/modules/services/rootlesskit.te
@@ -0,0 +1,43 @@
+policy_module(rootlesskit)
+
+########################################
+#
+# Declarations
+#
+
+container_engine_domain_template(rootlesskit)
+type rootlesskit_exec_t;
+container_user_engine(rootlesskit_t)
+application_domain(rootlesskit_t, rootlesskit_exec_t)
+mls_trusted_object(rootlesskit_t)
+
+########################################
+#
+# Rootlesskit local policy
+#
+
+# rootlesskit fails without this access
+allow rootlesskit_t self:tun_socket { relabelfrom relabelto };
+
+can_exec(rootlesskit_t, rootlesskit_exec_t)
+
+domain_use_interactive_fds(rootlesskit_t)
+
+# any dir not readable or file not stat-able causes rootlesskit to hang
+# when --copy-up would access it; the below rules cover at least the
+# access needed for rootless docker (copying /etc and /run)
+files_list_all(rootlesskit_t)
+files_getattr_all_files(rootlesskit_t)
+files_getattr_all_pipes(rootlesskit_t)
+files_getattr_all_sockets(rootlesskit_t)
+
+kernel_read_sysctl(rootlesskit_t)
+
+auth_use_nsswitch(rootlesskit_t)
+
+userdom_exec_user_bin_files(rootlesskit_t)
+
+optional_policy(`
+ dbus_list_system_bus_runtime(rootlesskit_t)
+ dbus_system_bus_client(rootlesskit_t)
+')