blastwall is a proof of concept for using SELinux user confinement as an exploit firewall for privileged automation. The diagrams below are the argument, not decoration: they show where this model sits beside BPF LSM precision, how it moves through RHEL operations, and where AAP should decide to run, skip, or remediate.

Recent events make the argument in Privileged Automation Security feel less theoretical. Blastwall is a concrete sketch of that concern: privileged automation should arrive constrained, observable, and policy-gated before it can touch the rest of the fleet.

The Problem

The failure mode I am trying to avoid is simple: automation gets the same broad local shape as an operator, but it executes faster, across more hosts, and with less human friction. If that automation lands as an unconfined identity, every mistake and every exploit path starts from a position I do not want to defend.

Copy Fail is the concrete example here. Anthony Green's block-copyfail shows the precise BPF LSM answer: inspect the AF_ALG bind argument and deny the vulnerable authencesn shape. Blastwall asks a different operational question: if the risky path should be unavailable to privileged automation, can I make that part of the same SELinux, IdM, AAP, and content-delivery model RHEL operators already understand?

Copy Fail: Precision Tool vs Automation Boundary This is the fork in the road. BPF LSM answers the exact kernel-argument question; Blastwall answers the identity and rollout question.
flowchart LR
    COPY["Copy Fail mitigation idea"] --> BPF["block-copyfail<br/>BPF LSM precision"]
    COPY --> BW["Blastwall<br/>SELinux automation boundary"]

    BPF --> BPFHOOK["socket_bind hook<br/>inspect authencesn"]
    BPFHOOK --> BPFDENY["Deny exact algorithm"]

    BW --> IDM["IdM maps identity<br/>to blastwall_u"]
    IDM --> AAP["AAP preflight<br/>chooses safe hosts"]
    AAP --> SELINUX["SELinux denies<br/>alg_socket for automation"]

The Argument

I do not think FreeIPA should author SELinux policy. I want IdM to map named automation identities into SELinux users and roles that already exist on the endpoint. I also do not want AAP discovering halfway through a job that the host was never in the right confinement state.

Local Policy

Managed RHEL hosts carry a versioned policy that defines blastwall_u, blastwall_r, and the confined automation domain.

IdM Mapping

IdM maps selected automation identities into that SELinux user through HBAC-linked policy and scoped sudo.

AAP Gate

AAP reads IdM state with eigenstate.ipa before running and fails closed on unsuitable hosts.

What AAP And IdM Add IdM is the policy system of record, AAP consumes that policy before execution, and SELinux enforces the boundary after login.
flowchart TB
    IDM["IdM / FreeIPA<br/>identity + host + policy truth"] --> EIGEN["eigenstate.ipa<br/>read policy state"]
    EIGEN --> AAP["AAP preflight<br/>gate and target selection"]
    AAP --> SSH["SSH to managed host"]
    SSH --> PAM["SSSD + pam_selinux<br/>apply SELinux user map"]
    PAM --> BW["blastwall_u confined session"]
    BW --> LOCAL["Local root work<br/>inside SELinux boundary"]
    BW --> BLOCK["Exploit surfaces denied<br/>by versioned policy"]
Architecture Flow This is the end-to-end control path: inventory, HBAC, host markers, preflight, SELinux map, sudo, login, and the deny rule.
flowchart LR
    AAP["AAP job<br/>automation identity"] --> INV["eigenstate.ipa.idm<br/>IdM-backed inventory"]
    INV --> HBAC["HBAC-scoped hosts<br/>blastwall-automation-ssh"]
    INV --> MARKERS["Host markers<br/>current or stale policy"]
    HBAC --> PREFLIGHT["Preflight gate"]
    MARKERS --> PREFLIGHT
    PREFLIGHT --> MAP["SELinux user map<br/>blastwall-root-local-map"]
    PREFLIGHT --> SUDO["Sudo policy<br/>blastwall-root-local-sudo"]
    PREFLIGHT --> RUN["Run job on selected hosts"]
    RUN --> LOGIN["SSH login via SSSD + pam_selinux"]
    LOGIN --> DOMAIN["blastwall_u:blastwall_r:blastwall_t<br/>alias: blastwall_root_local_t"]
    DOMAIN --> DENY["CIL deny<br/>no alg_socket access"]
IdM Relationship Model The IdM objects are deliberately ordinary: group, hostgroup, HBAC, SELinux map, and sudo rule.
flowchart TB
    GROUP["IdM group<br/>blastwall-automation"] --> HBAC["HBAC rule<br/>blastwall-automation-ssh"]
    HOSTGROUP["IdM hostgroup<br/>blastwall-managed-hosts"] --> HBAC
    SERVICE["HBAC service<br/>sshd"] --> HBAC
    HBAC --> MAP["SELinux user map<br/>blastwall-root-local-map"]
    MAP --> SEUSER["blastwall_u:s0"]
    GROUP --> SUDO["Sudo rule<br/>blastwall-root-local-sudo"]
    HOSTGROUP --> SUDO
    SUDO --> ROOT["RunAs root<br/>no unconfined role/type option"]

Why I Would Build This

I would build this because the logistics matter. In a RHEL automation estate, a versioned SELinux policy RPM is often easier to stage, promote, audit, and roll back than a new set of dynamically attached probes. That does not make SELinux more precise than BPF LSM. It makes the mitigation fit the machinery already wrapped around RHEL operations.

The point is not to replace kernel patches. The point is to make privileged automation start constrained while the real fix moves through the fleet. If the exploit can be mitigated by denying a broad surface for automation identities, I want that denial to have an artifact name, a rollout state, and an inventory-visible coverage claim.

Why The Logistics Matter The useful mitigation is not only the rule. It is the path from policy source to artifact, rollout, verification, IdM marker, and AAP preflight.

How It Scales

That turns emergency mitigation into ordinary operational state. Hosts are not merely patched or unpatched. For a given job, they are suitable or unsuitable based on identity mapping, HBAC, sudo policy, local SELinux enforcement, and the coverage markers AAP can see before it touches the endpoint.

Coverage Expansion Model A new exploit surface should become a versioned policy scope and an inventory-visible rollout state, not untracked local emergency state.
Host Suitability Markers Markers are not proof by themselves. They are the inventory-visible claim written only after local verification succeeds.
Candidate Selection With Multiple Coverages As policy expands, AAP can prefer hosts that satisfy the exact coverage required by a job and skip or remediate stale hosts.
flowchart TD
    JOB["AAP job declares required coverage"] --> REQ["Required markers<br/>policy version + scopes"]
    REQ --> H1{"Host A markers<br/>0.1.0 alg_socket"}
    REQ --> H2{"Host B markers<br/>0.2.0 alg_socket + userns"}
    H1 -->|missing new scope| STALE["Eligible but stale<br/>skip or remediate"]
    H2 -->|all required scopes| SELECT["Preferred candidate"]
    STALE --> REMEDIATE["Run policy update workflow"]
    REMEDIATE --> MARKER["Refresh IdM marker"]
    MARKER --> SELECT

Runtime Enforcement

The final decision still happens on the host. The point of the IdM and AAP work is to make sure the session arrives in the right SELinux user and role before local root work begins.

Runtime Enforcement Flow This is where the preflight decision turns into a host-local SELinux decision for the mapped automation session.
sequenceDiagram
    participant A as AAP
    participant I as IdM / FreeIPA
    participant S as SSSD + pam_selinux
    participant H as Managed RHEL host
    participant K as SELinux kernel policy

    A->>I: Read inventory, HBAC, SELinux map, sudo policy
    I-->>A: Eligible hosts + confinement policy state
    A->>I: hbactest automation identity against host:sshd
    I-->>A: access granted or denied
    A->>H: SSH as automation identity
    H->>S: Resolve SELinux user map at login
    S-->>H: Launch session as blastwall_u:blastwall_r:blastwall_t
    A->>H: Run sudo for local-root task
    H->>K: Enforce blastwall_t permissions
    K-->>H: Deny alg_socket create/bind/send/recv

The Tradeoff

BPF LSM is the precision tool. It can inspect kernel hook arguments and preserve unrelated AF_ALG use. Blastwall is the identity, policy, and delivery model. It blocks a broader SELinux surface for a narrower subject: privileged automation mapped into blastwall_u.

That tradeoff is often acceptable for automation. Many jobs should not need AF_ALG, raw sockets, BPF, perf, user namespace creation, or ptrace. Blocking those surfaces for automation identities is part of the point.

Important Limitation SELinux cannot match the authencesn argument. Blastwall accepts a broader deny for the narrower automation subject.
flowchart TD
    EXPLOIT["Copy Fail path"] --> SOCK["AF_ALG socket"]
    SOCK --> BIND["bind(authencesn...)"]
    BIND --> VULN["vulnerable kernel path"]

    BPF["block-copyfail<br/>BPF LSM approach"] --> PRECISE["Inspect sockaddr_alg<br/>deny only authencesn"]
    SELINUX["Blastwall<br/>SELinux approach"] --> BROAD["Deny alg_socket class<br/>for automation domain"]

    PRECISE --> SOCK
    BROAD --> SOCK

Repository Layout

PathPurpose
policy/SELinux reference-policy module and CIL deny rule.
scripts/Local install, cleanup, and IdM command helpers.
inventory/eigenstate.ipa.idm inventory source for AAP.
playbooks/Preflight, deployment, and verification playbooks.
poc-calabi/End-to-end lab workflow against a generic automation endpoint.