SELinux on OpenShift: stop chmod 777-ing your way out
Read AVC denials, write a targeted policy module, and keep SCCs strict instead of granting privileged.
Something breaks, a log says 'Permission denied' on a file whose mode is clearly 0644, and within thirty seconds someone types setenforce 0. The problem 'goes away' — because you just turned off the seatbelt. SELinux denials are readable and the real fix is usually three commands, so it's worth learning to read them instead of reaching for the switch.
Every denial is logged as an AVC (Access Vector Cache) record. That record tells you exactly what was blocked and in which context:
ausearch -m AVC -ts recenttime->Tue Jun 10 10:42:01 2025type=AVC avc: denied { read } for pid=2114 comm="nginx" name="index.html" scontext=...:httpd_t tcontext=...:user_home_t ausearch -m AVC -ts recent | audit2whyWas caused by: the file has the wrong SELinux type.the fix is a file context, not setenforce 0Read it left to right: the subject nginx (httpd_t) was denied read on a file labelled user_home_t. SELinux isn't confused — a web server has no business reading a file typed as someone's home directory. The label is wrong, so fix the label.
Fix the label, not the enforcement
Set the correct context so it persists across a relabel — chcon alone is temporary and gets wiped by the next restorecon. Use semanage fcontext to record the rule, then restorecon to apply it. When the app genuinely needs a capability, a boolean is the sanctioned switch.
# persistent: teach the policy the correct type for this pathsemanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"restorecon -Rv /srv/www# some needs are just a boolean away — no custom policy requiredsetsebool -P httpd_can_network_connect on
On OpenShift and Kubernetes
Containers get SELinux too. On OpenShift, Security Context Constraints (SCCs) assign each pod an MCS category pair, so two containers on the same node literally cannot read each other's volume files even as root. When a mounted volume throws permission errors, the culprit is almost always the label — set seLinuxOptions or let the platform relabel the mount rather than loosening the SCC.
Where this goes next
Once reading denials is routine, generate a proper module for the legitimate ones: ausearch ... | audit2allow -M myapp builds a loadable policy you can review and ship, instead of a pile of booleans nobody remembers enabling.