diff --git a/policy/modules/contrib/milter.fc b/policy/modules/contrib/milter.fc
index 622df0b2de..c992658120 100644
--- a/policy/modules/contrib/milter.fc
+++ b/policy/modules/contrib/milter.fc
@@ -1,19 +1,25 @@
/etc/mail/dkim-milter/keys(/.*)? gen_context(system_u:object_r:dkim_milter_private_key_t,s0)
+/etc/openarc/keys(/.*)? gen_context(system_u:object_r:openarc_milter_private_key_t,s0)
# those are duplicate with dkim.fc
/usr/bin/dkim-filter -- gen_context(system_u:object_r:dkim_milter_exec_t,s0)
/usr/bin/opendkim -- gen_context(system_u:object_r:dkim_milter_exec_t,s0)
+/usr/bin/openarc -- gen_context(system_u:object_r:openarc_milter_exec_t,s0)
+
/usr/bin/opendmarc -- gen_context(system_u:object_r:dkim_milter_exec_t,s0)
/usr/bin/milter-greylist -- gen_context(system_u:object_r:greylist_milter_exec_t,s0)
/usr/bin/sqlgrey -- gen_context(system_u:object_r:greylist_milter_exec_t,s0)
/usr/bin/milter-regex -- gen_context(system_u:object_r:regex_milter_exec_t,s0)
/usr/bin/spamass-milter -- gen_context(system_u:object_r:spamass_milter_exec_t,s0)
+/usr/sbin/openarc -- gen_context(system_u:object_r:openarc_milter_exec_t,s0)
+
/var/lib/milter-greylist(/.*)? gen_context(system_u:object_r:greylist_milter_data_t,s0)
/var/lib/sqlgrey(/.*)? gen_context(system_u:object_r:greylist_milter_data_t,s0)
/var/lib/spamass-milter(/.*)? gen_context(system_u:object_r:spamass_milter_state_t,s0)
+/run/openarc(/.*)? gen_context(system_u:object_r:openarc_milter_data_t,s0)
/run/opendmarc(/.*)? gen_context(system_u:object_r:dkim_milter_data_t,s0)
/run/milter-greylist(/.*)? gen_context(system_u:object_r:greylist_milter_data_t,s0)
/run/milter-greylist\.pid -- gen_context(system_u:object_r:greylist_milter_data_t,s0)
@@ -24,5 +30,6 @@
/var/spool/milter-regex(/.*)? gen_context(system_u:object_r:regex_milter_data_t,s0)
/var/spool/postfix/spamass(/.*)? gen_context(system_u:object_r:spamass_milter_data_t,s0)
+/var/spool/openarc(/.*)? gen_context(system_u:object_r:openarc_milter_data_t,s0)
/var/spool/opendkim(/.*)? gen_context(system_u:object_r:dkim_milter_data_t,s0)
/var/spool/opendmarc(/.*)? gen_context(system_u:object_r:dkim_milter_data_t,s0)
diff --git a/policy/modules/contrib/milter.if b/policy/modules/contrib/milter.if
index 562833a816..562e26f198 100644
--- a/policy/modules/contrib/milter.if
+++ b/policy/modules/contrib/milter.if
@@ -131,3 +131,22 @@ interface(`milter_delete_dkim_pid_files',`
files_search_pids($1)
delete_files_pattern($1, dkim_milter_data_t, dkim_milter_data_t)
')
+
+#######################################
+##
+## Delete openarc PID files.
+##
+##
+##
+## Domain allowed access.
+##
+##
+#
+interface(`milter_delete_openarc_pid_files',`
+ gen_require(`
+ type openarc_milter_data_t;
+ ')
+
+ files_search_pids($1)
+ delete_files_pattern($1, openarc_milter_data_t, openarc_milter_data_t)
+')
diff --git a/policy/modules/contrib/openarc.fc b/policy/modules/contrib/openarc.fc
new file mode 100644
index 0000000000..b238b9c4cf
--- /dev/null
+++ b/policy/modules/contrib/openarc.fc
@@ -0,0 +1,11 @@
+/etc/openarc/keys(/.*)? gen_context(system_u:object_r:openarc_milter_private_key_t,s0)
+
+/etc/rc\.d/init\.d/openarc -- gen_context(system_u:object_r:openarc_milter_initrc_exec_t,s0)
+
+/usr/bin/openarc -- gen_context(system_u:object_r:openarc_milter_exec_t,s0)
+
+/usr/lib/systemd/system/openarc\.service -- gen_context(system_u:object_r:openarc_milter_unit_t,s0)
+
+/usr/sbin/openarc -- gen_context(system_u:object_r:openarc_milter_exec_t,s0)
+
+/var/run/openarc(/.*)? gen_context(system_u:object_r:openarc_milter_data_t,s0)
diff --git a/policy/modules/contrib/openarc.if b/policy/modules/contrib/openarc.if
new file mode 100644
index 0000000000..64348c6ee9
--- /dev/null
+++ b/policy/modules/contrib/openarc.if
@@ -0,0 +1,79 @@
+## Authenticated Received Chain milter.
+
+########################################
+##
+## Allow a domain to talk to OpenARC via Unix domain socket
+##
+##
+##
+## Domain allowed access.
+##
+##
+#
+interface(`openarc_stream_connect',`
+ gen_require(`
+ type openarc_milter_data_t, openarc_milter_t;
+ ')
+
+ stream_connect_pattern($1, openarc_milter_data_t, openarc_milter_data_t, openarc_milter_t)
+')
+
+########################################
+##
+## Reload the openarc service (systemd).
+##
+##
+##
+## Domain allowed access.
+##
+##
+#
+interface(`openarc_reload',`
+ gen_require(`
+ type openarc_milter_unit_t;
+ class service { reload status };
+ ')
+
+ allow $1 openarc_milter_unit_t:service { reload status };
+')
+
+########################################
+##
+## All of the rules required to
+## administrate an OpenARC environment.
+##
+##
+##
+## Domain allowed access.
+##
+##
+##
+##
+## Role allowed access.
+##
+##
+##
+#
+interface(`openarc_admin',`
+ gen_require(`
+ type openarc_milter_t, openarc_milter_initrc_exec_t, openarc_milter_private_key_t;
+ type openarc_milter_data_t;
+ ')
+
+ allow $1 openarc_milter_t:process { ptrace signal_perms };
+ ps_process_pattern($1, openarc_milter_t)
+
+ init_startstop_service($1, $2, openarc_milter_t, openarc_milter_initrc_exec_t)
+
+ init_labeled_script_domtrans($1, openarc_milter_initrc_exec_t)
+ domain_system_change_exemption($1)
+ role_transition $2 openarc_milter_initrc_exec_t system_r;
+ allow $2 system_r;
+
+ files_search_etc($1)
+ admin_pattern($1, openarc_milter_private_key_t)
+
+ files_search_pids($1)
+ files_search_runtime($1)
+ admin_pattern($1, openarc_milter_data_t)
+')
diff --git a/policy/modules/contrib/openarc.te b/policy/modules/contrib/openarc.te
new file mode 100644
index 0000000000..44c22ce406
--- /dev/null
+++ b/policy/modules/contrib/openarc.te
@@ -0,0 +1,78 @@
+policy_module(openarc, 0.1)
+
+########################################
+#
+# Declarations
+#
+
+milter_template(openarc)
+
+type openarc_milter_initrc_exec_t;
+init_script_file(openarc_milter_initrc_exec_t)
+
+type openarc_milter_private_key_t;
+files_security_file(openarc_milter_private_key_t)
+
+type openarc_milter_unit_t;
+systemd_unit_file(openarc_milter_unit_t)
+
+init_daemon_run_dir(openarc_milter_data_t, "openarc")
+
+########################################
+#
+# Local policy
+#
+
+allow openarc_milter_t self:capability { dac_override dac_read_search setgid setuid };
+allow openarc_milter_t self:process { getsched signal signull };
+allow openarc_milter_t self:unix_stream_socket create_stream_socket_perms;
+
+read_files_pattern(openarc_milter_t, openarc_milter_private_key_t, openarc_milter_private_key_t)
+
+# /proc/sys/kernel/ngroups_max
+kernel_read_kernel_sysctls(openarc_milter_t)
+
+corecmd_exec_shell(openarc_milter_t)
+
+corenet_udp_bind_generic_node(openarc_milter_t)
+corenet_udp_bind_all_unreserved_ports(openarc_milter_t)
+corenet_udp_bind_generic_port(openarc_milter_t)
+
+# Look up username for dropping privs
+auth_use_nsswitch(openarc_milter_t)
+
+sysnet_dns_name_resolve(openarc_milter_t)
+
+dev_read_urand(openarc_milter_t)
+# for cpu/online
+dev_read_sysfs(openarc_milter_t)
+
+# Allow creation of a pid file /run/openarc/openarc.pid
+files_pid_filetrans(openarc_milter_t, openarc_milter_data_t, { dir file })
+files_read_usr_files(openarc_milter_t)
+files_search_spool(openarc_milter_t)
+
+miscfiles_read_generic_certs(openarc_milter_t)
+
+optional_policy(`
+ mta_read_config(openarc_milter_t)
+')
+
+optional_policy(`
+ # set up unix socket
+ postfix_search_spool(openarc_milter_t)
+')
+
+optional_policy(`
+ require {
+ type postfix_smtpd_t;
+ type openarc_milter_t;
+ type var_run_t;
+ class sock_file { create getattr unlink write };
+ }
+ allow openarc_milter_t var_run_t:sock_file { create getattr unlink };
+ allow postfix_smtpd_t var_run_t:sock_file write;
+')
+
+mta_read_config(openarc_milter_t)
+mta_sendmail_exec(openarc_milter_t)
diff --git a/policy/modules/system/init.te b/policy/modules/system/init.te
index d2c0219b62..187687de53 100644
--- a/policy/modules/system/init.te
+++ b/policy/modules/system/init.te
@@ -1589,6 +1589,11 @@ optional_policy(`
milter_setattr_all_dirs(initrc_t)
')
+optional_policy(`
+ milter_delete_openarc_pid_files(initrc_t)
+ milter_setattr_all_dirs(initrc_t)
+')
+
optional_policy(`
mta_manage_aliases(initrc_t)
mta_manage_config(initrc_t)