Explained: RACF

Codelooru jcl

A bank teller logs into the mainframe every morning. She can view account balances and initiate transfers. She cannot access the payroll database. She cannot modify account interest rates. She cannot run the overnight batch jobs. She does not know any of this is being enforced. She just sees the transactions she is permitted to run and nothing else.

That enforcement is RACF. Every access attempt, by every user, by every batch job, by every started task, passes through RACF before z/OS acts on it. RACF decides whether the access is permitted, logs the attempt, and returns a simple answer: allowed or denied. No part of the mainframe circumvents this. CICS calls RACF. DB2 calls RACF. JES calls RACF. The file system calls RACF. It is the single security enforcement point for the entire operating environment.

This post assumes you have read Architecture: Mainframe. It covers how RACF is structured, what a profile is, how the access decision is made, and how RACF integrates with the subsystems covered earlier in this series.


What RACF Is

RACF (Resource Access Control Facility) is IBM's access control product for z/OS, first introduced in 1976. It is the dominant security product in the mainframe world. The two alternatives, CA-ACF2 and CA-Top Secret, exist but are far less common. When mainframe security professionals say "security," they usually mean RACF.

RACF is part of the z/OS Security Server: a component of z/OS that provides the interface between the operating system and the security product. That interface is called SAF (System Authorization Facility). When a subsystem like CICS or DB2 needs to check whether a user has access to a resource, it issues a SAF call. SAF routes that call to RACF. RACF performs the check and returns the result. This routing layer means that RACF can, in principle, be replaced by another SAF-compliant security product without changing any of the subsystems that call SAF.

RACF stores all its data in the RACF database: a set of VSAM datasets that hold every user profile, every group profile, and every resource profile on the system. The database is read at IPL and a cached copy is maintained in memory for performance. Every RACF command that creates, modifies, or deletes a profile updates both the in-memory cache and the on-disk database. The database is the source of truth for the entire security posture of the system.


The Three Profile Types

Everything in RACF is a profile: a record in the RACF database that describes a security entity and its attributes. There are three fundamental profile types.

User Profiles

A user profile exists for every user ID defined to the system. It records the user's password (hashed), their default group, their account status (active or revoked), and a set of optional segments that extend the profile for specific subsystems.

The base segment of a user profile contains the attributes that apply system-wide. The most significant user attributes are:

  • SPECIAL: the user is a RACF administrator. A user with SPECIAL can define and modify any profile on the system. This is the mainframe equivalent of root. SPECIAL users are tightly controlled and audited.
  • OPERATIONS: the user has full access to all DASD and tape datasets, regardless of the profiles protecting those datasets. Used for storage administrators and backup operators who need to access any dataset on the system.
  • AUDITOR: the user can read any RACF profile and review audit records, but cannot modify anything. Used for security auditors and compliance staff.
  • REVOKE: the user ID is suspended. A revoked user cannot log in. Used when an employee leaves or when a compromised account needs to be locked immediately.

The optional segments extend the user profile for subsystem-specific attributes. The TSO segment holds the user's default logon procedure and account number for TSO sessions. The OMVS segment holds the z/OS UNIX UID and home directory, required for any user who accesses z/OS UNIX System Services. The CICS segment holds CICS-specific operator authority. Without the correct segment, a user cannot use the corresponding subsystem.

Group Profiles

A group profile represents a collection of users. Groups are the primary mechanism for scaling access management: rather than granting access to individual users, administrators grant access to groups and manage users by adding them to or removing them from groups.

Groups in RACF are hierarchical. A group can have subgroups. A user's access includes the permissions of their default group and any groups they are connected to. Connections are managed with the `CONNECT` command and can be granted different levels of group authority: USE (a regular member), CREATE (can add users to the group), CONNECT (can connect users to the group), or JOIN (full administrative authority within the group).

Every user must have a default group. When a user logs in, RACF establishes their security context using their default group. A user can switch their active group during a session if they are connected to multiple groups, which changes which group-level permissions apply for that session.

Resource Profiles

A resource profile protects a specific resource or a set of resources. There are two categories: dataset profiles and general resource profiles.

Dataset profiles protect VSAM files, sequential datasets, and partitioned datasets. Their names follow the hierarchical dataset naming convention. A profile named `PAYROLL.**` protects all datasets whose name starts with `PAYROLL.`, using a wildcard. A profile named `PAYROLL.MASTER.DATA` protects exactly that one dataset.

General resource profiles protect everything else: CICS transactions, DB2 connections, JES spool access, TSO commands, MVS operator commands, started task user IDs, z/OS UNIX files, and any other resource type that a subsystem registers with SAF. These profiles live in named resource classes. The class `TCICSTRN` protects CICS transaction IDs. The class `DSNR` protects DB2 subsystem connections. The class `FACILITY` is a general-purpose class used for a wide range of system facility protections.

RACF DATABASE (VSAM) USER PROFILES TELLER01 Default group: TELLERS BATCHJOB Default group: BATCH SECADMIN SPECIAL attribute Segments: TSO, OMVS, CICS… GROUP PROFILES TELLERS Members: TELLER01, TELLER02… BATCH Members: BATCHJOB, RPTJOB… PAYROLL Subgroup of: FINANCE Hierarchy: FINANCE → PAYROLL RESOURCE PROFILES PAYROLL.** (DATASET) UACC(NONE), TELLERS=READ ACCT (TCICSTRN) UACC(NONE), TELLERS=READ DB1P.BATCH (DSNR) UACC(NONE), BATCH=JOIN Discrete and generic profiles Figure 1: The three RACF profile types — users, groups, and resources — all stored in the RACF database.

The Access Decision

When a user or program tries to access a resource, RACF performs a check that follows a specific chain of logic. Understanding this chain is the key to understanding why access is granted or denied in any given situation.

The check begins when a subsystem issues a SAF call. SAF routes it to RACF, passing the user ID, the resource name, and the class of the resource, along with the access level being requested (READ, UPDATE, CONTROL, or ALTER for datasets; READ or higher for general resources).

RACF first checks whether the resource class is active. If the class is not active (not enabled in the RACF `SETROPTS` settings), RACF allows the access without further checking. This is why activating all relevant classes is a security baseline requirement.

If the class is active, RACF searches for a protecting profile. For dataset access, it looks for the most specific profile that matches the dataset name: a discrete profile for that exact name first, then the most specific generic profile. For `PAYROLL.MONTHLY.REPORT`, RACF would check for an exact match first, then `PAYROLL.MONTHLY.*`, then `PAYROLL.**`, then `PAYROLL.*`, using the most specific match it finds.

Once the protecting profile is found, RACF evaluates access in this order:

  1. Does the user have a specific entry on the profile's access list? If yes, that entry's access level is used.
  2. Is the user a member of a group that has an entry on the access list? If yes, the group's access level is used. If multiple groups match, the highest access level wins.
  3. Neither the user nor any of their groups are on the access list: the UACC (Universal Access Authority) of the profile applies. UACC is the default access for anyone not explicitly listed. A UACC of `NONE` means no access by default. A UACC of `READ` means anyone on the system can read the resource without being explicitly listed.
  4. If no protecting profile exists at all, RACF uses a system-wide default. If `SETROPTS PROTECTALL` is active, unprotected datasets are inaccessible. If it is not active, unprotected resources may be accessible without any RACF check.

The access levels in ascending order of authority are: NONE, READ, UPDATE, CONTROL, and ALTER. A user with ALTER access on a dataset can read it, write to it, scratch it, and rename it. A user with READ access can only read it. The requested access level must be less than or equal to the permitted level for the check to pass.

SAF call from subsystem (CICS, DB2, z/OS) User ID + resource name + class + access level Is the resource class active? No ALLOW Yes Find most specific protecting profile Discrete first, then generic User ID on access list? Yes Use user's access level No User's group on access list? Yes Use group's access level No Apply UACC (default access) NONE = deny, READ/UPDATE/etc = allow ALLOW access DENY access Figure 2: The RACF access decision chain, from SAF call to allow or deny.

Discrete vs. Generic Profiles

A discrete profile protects exactly one named resource. The profile name matches the resource name character for character. A discrete profile for `HR.PAYROLL.MASTER` protects only that one dataset.

A generic profile uses wildcard characters to protect a set of resources with a single profile. RACF supports two wildcards: `*` matches any characters within a single qualifier, and `**` matches any characters across multiple qualifiers.

`HR.*` matches `HR.PAYROLL` but not `HR.PAYROLL.MASTER` (because `*` does not cross the dot boundary). `HR.**` matches `HR.PAYROLL.MASTER`, `HR.EMPLOYEES.FILE`, and anything else starting with `HR.`. Generic profiles dramatically reduce the number of profiles needed to manage a large installation. A bank with tens of thousands of datasets does not define a discrete profile for each one: it defines a handful of generic profiles based on the naming conventions already enforced by the high-level qualifier rules.

When multiple generic profiles could match a resource name, RACF uses the most specific match. `HR.PAYROLL.*` is more specific than `HR.**` and takes precedence for a name like `HR.PAYROLL.MASTER`.


The RACF Database and In-Memory Cache

Making a RACF check on every single dataset open, every CICS transaction, and every DB2 SQL call would be prohibitively slow if it required a disk read each time. RACF addresses this through in-memory caching.

Generic profiles for a class can be loaded into memory using the RACLIST command. Once RACLISTed, all lookups for that class hit the in-memory copy rather than the database. For high-volume classes like `TCICSTRN` (CICS transactions), RACLIST is essential: a busy production CICS region may check RACF thousands of times per second.

When a profile is updated while it is RACLISTed, the in-memory copy must be refreshed explicitly with `SETROPTS RACLIST(classname) REFRESH`. Forgetting this refresh is a common operational mistake: the database is updated but the in-memory copy still has the old rule, so access control does not change until the refresh is done.

User profile information is cached in an in-memory control block called the ACEE (Access Control Environment Element), created at logon time and retained for the duration of the user's session. The ACEE contains the user's group connections, attributes, and security classification. Changing a user's profile mid-session does not take effect until the next logon, because the ACEE was built at logon from the database state at that time.


RACF and CICS

CICS is deeply integrated with RACF. Every CICS region runs under a region user ID: a RACF user ID defined in the STARTED class that is automatically assigned to the CICS address space when it starts. This user ID must have the necessary access to CICS datasets, DB2 connections, and MQ resources. It represents the region itself, not any individual user.

Individual users sign on to CICS either explicitly (by running the CESN transaction and entering their credentials) or implicitly (when their terminal is preset with a user ID by the terminal definition). Once signed on, CICS establishes the user's identity for security checking purposes.

RACF checks in CICS occur at several points:

  • Transaction authorization: when a user invokes a transaction code, CICS calls RACF to check whether the user has at least READ access to the transaction's profile in the `TCICSTRN` class. If not, CICS rejects the transaction before running the program.
  • Resource authorization: when a CICS program issues `EXEC CICS READ` on a file, CICS checks the user's access to that file's profile in the `DATASET` class.
  • Program authorization: CICS can optionally check whether a user is permitted to execute a specific program, using the `PROGRAM` resource class.

This layered checking means that even if a user can invoke a transaction, they may still be blocked from the underlying data that transaction tries to access. Security is enforced at every level, not just at the front door.


Key RACF Commands

RACF is administered through a set of commands issued at TSO, through ISPF panels, or via batch JCL. The core commands every mainframe developer will encounter:

  • `ADDUSER userid`: creates a new user profile.
  • `ALTUSER userid`: modifies an existing user profile. Used to reset passwords, revoke accounts, and add or change subsystem segments.
  • `LISTUSER userid`: displays a user profile's contents. The standard tool for checking what groups a user belongs to and what attributes they have.
  • `CONNECT userid GROUP(groupname)`: adds a user to a group.
  • `ADDSD 'dataset.name'`: creates a dataset profile. The `**` wildcard in the name creates a generic profile.
  • `RDEFINE classname profile.name`: creates a general resource profile.
  • `PERMIT 'resource.name' CLASS(classname) ID(userid) ACCESS(level)`: adds an entry to a resource profile's access list. This is the command used to grant a user or group access to a resource.
  • `LISTDSD PREFIX(hlq)`: lists all dataset profiles whose names start with the given prefix. Used to audit what profiles exist for a given application.
  • `SETROPTS`: controls system-wide RACF options, including which classes are active, password rules, and auditing settings.
/* Define a generic dataset profile for all payroll data */
ADDSD 'PAYROLL.**' UACC(NONE)

/* Grant the TELLERS group read access */
PERMIT 'PAYROLL.**' CLASS(DATASET) ID(TELLERS) ACCESS(READ)

/* Grant the PAYROLL group full access */
PERMIT 'PAYROLL.**' CLASS(DATASET) ID(PAYROLL) ACCESS(ALTER)

/* Protect the ACCT CICS transaction */
RDEFINE TCICSTRN ACCT UACC(NONE)
PERMIT ACCT CLASS(TCICSTRN) ID(TELLERS) ACCESS(READ)

/* Refresh the in-memory cache */
SETROPTS RACLIST(TCICSTRN) REFRESH

Auditing

Every RACF access check can generate an SMF record. RACF writes type 80 SMF records for security events: successful accesses, failed accesses, profile changes, and user logons and logoffs. These records are the audit trail that compliance teams, security analysts, and external auditors rely on.

Auditing can be configured at the profile level. A dataset profile can be set to log all successful accesses (`AUDIT(SUCCESS(READ))`), all failures (`AUDIT(FAILURE(READ))`), or both. System-wide auditing options in `SETROPTS` establish baseline audit logging for all classes.

The RACF AUDITOR attribute gives designated users read-only access to all profiles and audit records. Security auditors use the RACF report writer (IRRADU00 utility) to generate reports from the SMF type 80 records: who accessed which datasets, which accounts have been revoked, which users have the SPECIAL attribute. These reports are a standard deliverable for SOX, PCI-DSS, and other compliance frameworks in mainframe environments.


Summary

RACF is the security layer that every other mainframe subsystem relies on. Its three-profile model, users, groups, and resources, combined with the access list and UACC mechanism, gives security administrators precise, scalable control over who can access what. The generic profile system makes that control manageable at scale without requiring a profile per dataset.

The access decision chain is deterministic and auditable. Every check follows the same logic: specific user entry, then group entry, then UACC, then system default. When access is unexpectedly denied or unexpectedly permitted, the answer is always in one of those four places.

RACF's integration with CICS, DB2, JES, and z/OS itself means security is enforced at every layer. A user signing into a CICS terminal faces RACF checks for their identity, their transaction, the files that transaction accesses, and the programs it invokes. No single bypass grants access to everything. That depth of enforcement, built into every subsystem from the ground up, is what makes z/OS security unlike any other platform.

Part of the Mainframe Decoded series — IBM Z and z/OS, clearly explained for engineers.



×