BEWARE: The Requires: policycoreutils will add huge dependencies. To avoid dependency bloat it should be tried :
a. to work without manual scripts (e.g. file bug against selinux-policy and request that your package will be handled), or

a. split the SELinux related part into an own subpackage in a way like

a. move current main package (without the SELinux stuff) into e.g. a -core subpackage, keep SELinux in main and require -core by main. Unexperienced people will get the expected result (correctly labeled program) by "yum install <package>" while people without SELinux can install only -core.

Creating new types

Problem: You need to define new types for your application

Solution: You need to create an SELinux module, defining the new types and how they should be dealt with.

Example: The mock application makes a chroot to build packages. The content of the chroot needs a special type to identify files that may need the execmod feature, and mock itself needs to run in its own domain, which is allowed to do execmem and execheap when building packages for mono or java applications.

Make a directory to create and build the policy module for the package, e.g. /usr/share/selinux/packages/mock and change to that directory.

Some applications might not need one or more of the type enforcement (*.te), file context (*.fc), or interface (*.if) files; these can be created as empty files if nothing is needed for them.

You can ship the *.{te,fc,if} files as additional SOURCE files in your package, do the compiling in %install, and load the module with the semodule command in %post (see the Pure-FTPd example below).

The preferred place for the module is in the directory /usr/share/selinux/packages/<package name>.
Any place could potentially be used, though semodule has restricted rights to read files itself, which makes a location under /usr preferable.
We also need to standardize on some location, and this location makes it easy to find all the available modules.

A more detailed guide to bundling policy modules within RPM packages can be found in ["PackagingDrafts/SELinux/PolicyModules"]

Adding an existing SELinux policy to an application

Problem: There are applications in Extras that perform the same task as applications in Core. They should be protected by SELinux in the same way.

Solution: Label the new binaries the same way as the already-protected ones. Check that all the functionalities still work and that you have no AVC messages. If you do, extend the policy with an SELinux module.

Example: Pure-FTPd is an FTP server available in Extras. It should be protected is the same manner that vsftpd is in Core. Thus the file /usr/sbin/pure-ftpd should be labelled ftpd_exec_t. But Pure-FTPd has additional features: it is capable of taking its user list from MySQL, PostgreSQL or LDAP. We have to write a module to allow it to connect to these servers.
To do that, we ship the file pureftpd.te (the filename cannot contain dashes) in the package, containing this:

To build the policy, we need to add BuildRequires: selinux-policy-targeted, checkpolicy.

The build requirement of selinux-policy-targeted is necessary because of Bug #190561 ; once this is fixed, it will be possible to use a build requirement of selinux-policy instead.

It is also better to package all SELinux-related files and scriptlets in a separate rpm, named <package>-selinux. This way, the administrator can choose to enable SELinux protection or not.

Scriptlets: The -selinux package should load the policy on install, and set the file contexts. It should unload the policy on uninstall, set back the file contexts, and it should replace the policy module on upgrades. The daemon needs to be restarted when it is relabeled, but not when the policy module is replaced. We chose a set of scriptlets very similar to the ones we use for init scripts :