Hardening ESF Access-Control Rules: A Deny-by-Default Catch-All, and Why It Makes "Allow Unknown Resources" Irrelevant
The supplied ESF sample rules are too permissive for most production regions. A generic `**` rule with `deny:*:all` per resource class denies anything your specific rules do not cover, and it also means the "Allow unknown resources" option can never take effect. [1] [4]
Read the full briefing
Scope: Rocket Enterprise Developer / Enterprise Server 12.0 for Linux/UNIX, using the External Security Facility (ESF) with the MLDAP ESM Module (LDAP-based) or the VSAM ESM Module (file-based). Everything below comes from the 12.0 UNIX documentation bundle.
The problem: sample rules are a starting point, not a production policy
Access to resources such as programs, data files and CICS queues is controlled by resource rules held in the security repository, and similar rules restrict ESCWA administration functions and command-line utilities such as casout. Enterprise Server ships sample rules as LDIF files (for example es_default_ldap.ldf) and, for the VSAM ESM Module, as es_default_security.yaml. The documentation states plainly that many of these rules are unnecessary, inappropriate, or too permissive for most production regions, and recommends removing rules for sample applications and unused features (Hardening access-control rules).
How a decision is made
Rules are grouped into classes (data files, programs, CICS transactions, administration commands and so on), and each rule has a name that may contain wildcards. When Enterprise Server needs to authorize an operation, it passes ESF the resource class and name, the user information and the requested access level. The ESM Module finds every rule in that class whose name matches, examines them from the closest match to the most general, and stops at the first rule whose ACL applies to the user, either directly or through group membership. That is the determining rule (Hardening access-control rules).
Within a single ACL, conflicting Access Control Entries (ACEs) are resolved by documented precedence for the MLDAP ESM Module (ACE Precedence):
- Higher-ranked ACEs override lower-ranked ones. In MLDAP ESM Module version 2, rank depends on how many characters of the user or group name replace wildcard characters in the ACE actor, so for user Bob an ACE naming
BOBoutranksB*, which outranks*. - Within the same rank, user ACEs override group ACEs.
- For the same rank and actor, deny ACEs override allow ACEs.
Note the scope caveat: in version 2 the default is a newer algorithm that retrieves all applicable rules and checks them from strongest to weakest match, whereas the prefix-search order described on Resource Rules, Search Order, and Precedence applies only when Compatibility Rule Matching is enabled (and to version 1).
Technique 1: deny by default with a generic rule
The hardening guidance recommends a rule named ** with the ACL deny:*:all in each resource class. It matches every request for which no more-specific rule exists, so a resource name your specific rules do not cover is denied rather than slipping through. The page explains the benefit: it avoids issues if an attacker can specify a resource name your rules do not anticipate (Hardening access-control rules).
Class: DATASET
Rule: **
ACL: deny:*:allThe interaction that matters: "Allow unknown resources" becomes dead
The security facility has an Allow unknown resources option. It permits access to any resource for which every entry on the Security Manager Priority List answers Unknown, meaning no rule covers it; the documentation notes it suits cases where you only want to restrict some resources. Without it (and without Allow unknown users), if every security manager responds Unknown the request is denied (Default Security Facility Configuration).
A catch-all ** rule means no resource in that class is ever unknown, because at minimum the generic rule covers it. The hardening page says exactly this: these rules prevent the option from taking effect (Hardening access-control rules). Practically, if you turn the option on and add the catch-all deny, the deny wins for covered classes. Check this per class, since the catch-all is defined per resource class.
Technique 2: use wildcard hierarchies and group-based ACEs
The documentation gives a concrete example. If everything under the top-level qualifier SYS. should be writable only by the SYSADM group, one rule in the DATASET class covers it:
Rule: SYS.**
ACL: allow:SYSADM group:alter; deny:*:updateExcept where more-specific rules override it, that implements the policy. This works best when cataloged datasets follow a documented qualifier hierarchy. Apply ACEs to groups rather than individual users, since per-user ACEs do not scale (Hardening access-control rules).
Rather than granting a generally privileged group such as SYSADM, you can add an ACE to a specific rule. The page's example is a group allowed to use CICS system transaction CINS but not CFLE, achieved by adding an ACE to the CINS rule.
Technique 3: per-user namespaces (MLDAP username substitution)
When username substitution is enabled in the MLDAP ESM Module, two DATASET rules give each user their own area:
USERS.** deny:*:all
USERS.${user}.** allow:*:alterUser ALICE can then reach everything under USERS.ALICE and nothing else under USERS (Hardening access-control rules).
Operational cautions
- Restrict tracing, debugging and system-information features to users with a legitimate need, which may mean administrators only, or also operators or developers depending on the system type.
- Err toward restriction: relaxing an over-tight rule is easier than revoking permissions after habits and deployments depend on them.
- Keep rules simple and avoid special-case or conflicting rules that require knowing how conflicts are resolved.
- Review rules periodically.
Takeaway
For a production region, start from the sample rules, delete what you do not use, add a ** / deny:*:all catch-all per resource class, then grant access to named groups. Doing so makes Allow unknown resources moot, so every grant must be written down explicitly (Hardening access-control rules).