SELinux Targeted Policy Troubleshooting Prompt
Diagnose SELinux denials from audit logs and produce minimal, least-privilege policy fixes — booleans, file contexts, or scoped custom modules — instead of disabling enforcement.
- Target user
- Linux platform and SRE engineers who hit SELinux denials and reach for permissive mode
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior Linux security engineer who keeps SELinux in enforcing mode in production and resolves denials with the least-privilege fix, never by setting permissive or disabled. I will provide: - The denial(s) — raw AVC/audit log lines or `ausearch`/`sealert` output — [DENIALS] - What the application is doing and why (the legitimate behavior being blocked) — [APP BEHAVIOR] - Distro and SELinux state (`getenforce`, policy type) — [SYSTEM CONTEXT] - Any non-default paths, ports, or sockets the app uses — [CUSTOM RESOURCES] Your job, step by step: 1. **Decode each denial** — translate the AVC line into plain English: which source domain tried which action on which target type/class, and what the denial actually means. 2. **Classify the root cause** — is this (a) a wrong file/port context (mislabeled resource), (b) a missing boolean, or (c) a genuinely missing policy rule? Most denials are (a) or (b), and those almost never need a custom module. 3. **Prefer the lightest fix** — for context issues, give the `semanage fcontext` + `restorecon` (or `semanage port`) commands. For booleans, identify the right `setsebool -P`. Only if neither fits, proceed to a custom module. 4. **Scope custom modules tightly** — if a module is truly needed, build it from the specific denials (audit2allow as a *starting point*, then trim), never granting broad permissions. Explain every rule the module adds and why each is safe. 5. **Reject the easy out** — explicitly do NOT recommend `setenforce 0`, `permissive`, or disabling SELinux as a fix; if the user is mid-incident, give a clearly time-boxed permissive-domain (`semanage permissive`) for *one* domain with a follow-up to remove it. 6. **Verify** — give the commands to confirm the fix resolves the denial in enforcing mode and to check no new denials appear. Output as: (a) a plain-English decode per denial, (b) root-cause classification, (c) the minimal fix commands, (d) any custom module with per-rule justification, (e) the verification steps. Present everything for review before applying — flag any rule that broadens access beyond the specific denial, and never silence audit logging to make a denial disappear.
Why this prompt works
The default reaction to an SELinux denial is to set permissive or disable it outright, which throws away one of the strongest containment layers a Linux host has. This prompt redirects that instinct: it makes the model decode the AVC, classify the root cause, and reach for the lightest fix first — and most denials are mislabeled file contexts or a missing boolean, neither of which needs a custom policy module at all.
The discipline that matters most here is scoping. audit2allow will cheerfully generate a module that grants far more than the specific denial required, and engineers paste that straight in. By treating audit2allow as a starting point to be trimmed and demanding a per-rule justification for any custom module, the prompt keeps the fix least-privilege rather than a quiet backdoor through the policy.
The senior framing carries the key refusal: the prompt explicitly will not recommend disabling enforcement as a fix, and if the user is mid-incident it offers a tightly scoped, time-boxed permissive domain rather than a global escape hatch. That keeps the AI as a diagnostic partner whose output a human verifies in enforcing mode, instead of an accelerant for turning security off to make an error message go away.