Security on IBM i: object authority, user profiles, and keeping your data safe

IBM i has a reputation for being secure. That reputation is earned — the security model is granular, well-designed, and has been refined over decades. But a well-designed security model only protects you if it is configured correctly. IBM i systems running with default settings, overpowered user profiles, or security level 20 are not secure, regardless of what the platform is capable of.

This post covers how IBM i security actually works — the object authority model, user profiles, system security levels, and the practical steps that make the difference between a system that is secure and one that just feels like it should be.

The object authority model

Everything on IBM i is an object — programs, files, libraries, commands, devices, job descriptions. Every object has an owner and an access control list that specifies exactly what each user or group can do with it.

The authority types for a typical database file:

  • *READ — read records
  • *ADD — add new records
  • *UPD — update existing records
  • *DLT — delete records
  • *EXECUTE — open the file (required along with data authorities)
  • *ALL — full control including changing authorities
  • *CHANGE — read, add, update, delete (but not authority management)
  • *USE — read and execute only
  • *EXCLUDE — explicitly denied — no access regardless of group membership

For programs and commands, *EXECUTE is the key authority — a user needs it to call a program or run a command.

Checking authority on an object

/* See who has authority to an object */
DSPOBJAUT OBJ(MYLIB/CUSTMAST) OBJTYPE(*FILE)

/* Check what authority a specific user has */
CHKOBJ OBJ(MYLIB/CUSTMAST) OBJTYPE(*FILE) AUT(*CHANGE)

DSPOBJAUT shows the full authority list — the owner, the public authority, and any specific user or group authorities. This is the first command to run when someone says they cannot access a file or program.

From SQL, you can query object authorities across an entire library:

SELECT OBJECT_NAME, OBJECT_TYPE,
       USER_NAME, OBJECT_AUTHORITY,
       DATA_READ, DATA_ADD, DATA_UPDATE, DATA_DELETE
  FROM QSYS2.OBJECT_PRIVILEGES
  WHERE OBJECT_SCHEMA = 'MYLIB'
    AND OBJECT_TYPE = '*FILE'
  ORDER BY OBJECT_NAME, USER_NAME

Granting and revoking authority

/* Grant change authority to a user */
GRTOBJAUT OBJ(MYLIB/CUSTMAST) OBJTYPE(*FILE) +
           USER(JSMITH) AUT(*CHANGE)

/* Grant execute authority to a group profile */
GRTOBJAUT OBJ(MYLIB/ORDERPGM) OBJTYPE(*PGM) +
           USER(APPUSERS) AUT(*EXECUTE)

/* Revoke all authority from a user */
RVKOBJAUT OBJ(MYLIB/PAYROLLF) OBJTYPE(*FILE) +
           USER(TEMPUSER) AUT(*ALL)

/* Grant authority to everything in a library */
GRTOBJAUT OBJ(MYLIB/*ALL) OBJTYPE(*ALL) +
           USER(APPUSERS) AUT(*USE)

SQL equivalents work too and are useful for scripting:

GRANT SELECT, INSERT, UPDATE ON MYLIB.CUSTMAST TO JSMITH;
REVOKE ALL PRIVILEGES ON MYLIB.PAYROLLF FROM TEMPUSER;

Public authority — the most important default

Every object has a public authority — the access level granted to any user not specifically listed. This is where most IBM i security problems start.

If public authority on your customer file is *CHANGE, every user on the system can read, add, update, and delete customer records — including users who should never touch that data. Newly created objects inherit their public authority from the library’s creation default, which on many systems defaults to *CHANGE.

The secure default is *EXCLUDE. Grant explicit authority to the users and groups that need it, and deny everyone else by default.

/* Set public authority to exclude on an existing object */
GRTOBJAUT OBJ(MYLIB/CUSTMAST) OBJTYPE(*FILE) +
           USER(*PUBLIC) AUT(*EXCLUDE)

/* Set the default for new objects created in a library */
CHGLIB LIB(MYLIB) CRTAUT(*EXCLUDE)

User profiles

Every person and every batch job runs under a user profile. The user profile controls what the user can access, what resources they consume, and what they can do on the system.

Key attributes of a user profile:

Special authorities — system-level powers that bypass object authority checks. The dangerous ones:

  • *ALLOBJ — access to every object on the system regardless of authority settings. Only system administrators should have this.
  • *SECADM — create and manage user profiles. Users with this can grant themselves *ALLOBJ.
  • *JOBCTL — control any job on the system — end, hold, change priority.
  • *SPLCTL — full control of all spooled files on the system.
  • *AUDIT — change audit settings.

Most application users should have no special authorities. Developers typically need none or *JOBCTL at most. *ALLOBJ should be reserved for a small number of named administrators and the system service account.

/* Create a restricted application user */
CRTUSRPRF USRPRF(APPUSER1) +
           PASSWORD(*NONE) +
           SPCAUT(*NONE) +
           LMTCPB(*YES) +
           TEXT('Application batch user')

/* Check what special authorities a user has */
DSPUSRPRF USRPRF(JSMITH) OUTPUT(*PRINT)

LMTCPB(*YES) restricts the user to their initial program — they cannot get to a command line. Essential for end users who should only run application menus.

Group profiles

Managing authority user by user does not scale. Group profiles let you define an authority set once and assign users to the group.

/* Create a group profile */
CRTUSRPRF USRPRF(SALESGRP) +
           PASSWORD(*NONE) +
           TEXT('Sales department group')

/* Assign a user to the group */
CHGUSRPRF USRPRF(JSMITH) GRPPRF(SALESGRP)

/* Grant authority to the group — all members inherit it */
GRTOBJAUT OBJ(MYLIB/SALESRPT) OBJTYPE(*FILE) +
           USER(SALESGRP) AUT(*USE)

A user inherits the authorities of their group profile in addition to their own specific authorities. When someone joins a new team, add them to the appropriate group. When someone leaves, remove them from the group. No individual object authority changes needed.

Adopted authority — how programs access what users cannot

Adopted authority is one of the most important and most misunderstood concepts in IBM i security. It allows a program to run with the authority of its owner rather than the authority of the user calling it.

The classic use case: your application needs to read and update the payroll file, but you do not want to give every payroll clerk direct access to that file. Instead:

  1. The payroll program is owned by a profile (say PAYOWNER) that has *CHANGE on the payroll file
  2. The program is compiled with USRPRF(*OWNER)
  3. Payroll clerks are given *EXECUTE on the payroll program — nothing else
  4. When a clerk runs the program, it runs with PAYOWNER‘s authority — it can access the payroll file
  5. If the clerk tries to open the payroll file directly (from a query tool, ACS, or command line), they get access denied
/* Compile with adopted authority */
CRTBNDRPG PGM(MYLIB/PAYROLLPGM) SRCFILE(MYLIB/QRPGLESRC) +
           USRPRF(*OWNER)

/* Check if a program adopts authority */
DSPPGM PGM(MYLIB/PAYROLLPGM)

This pattern — restrict direct file access, control everything through programs — is the foundation of application-layer security on IBM i.

System security level (QSECURITY)

The system value QSECURITY controls how strictly IBM i enforces security:

  • Level 10 — no security. Any user can access anything. Never acceptable.
  • Level 20 — password security only. All objects are accessible to all users. Surprisingly common on older systems.
  • Level 30 — object security. Authority is checked on every object access. This is the minimum acceptable level.
  • Level 40 — level 30 plus protection against programs that bypass security by calling internal interfaces directly.
  • Level 50 — highest. Full C2-equivalent security. Required for many compliance frameworks.
/* Check current security level */
DSPSYSVAL SYSVAL(QSECURITY)

/* Change security level (requires IPL to take effect) */
CHGSYSVAL SYSVAL(QSECURITY) VALUE('40')

If your system is running at level 20, object authority settings are completely ignored — public authority, group authorities, specific user authorities — none of it matters. Every user has full access to everything. Upgrading to level 30 is the single most impactful security change you can make on such a system, and it requires an IPL (reboot).

Auditing — tracking what happened

IBM i has a built-in security audit journal (QAUDJRN) that records security-relevant events. When it is active, every authority failure, every user profile change, every sign-on, and every object deletion is recorded.

/* Enable auditing system-wide */
CHGSYSVAL SYSVAL(QAUDLVL) VALUE(*AUTFAIL *CREATE *DELETE *PGMFAIL *SECURITY)

/* Enable the audit journal if not already active */
CHGSECAUD QAUDLVL(*AUDLVL)

Query the audit journal from SQL:

-- Recent authority failures
SELECT ENTRY_TIMESTAMP, USER_NAME, JOB_NAME,
       OBJECT_NAME, OBJECT_LIBRARY, VIOLATION_TYPE
  FROM TABLE(QSYS2.DISPLAY_JOURNAL(
    'QSYS', 'QAUDJRN',
    JOURNAL_ENTRY_TYPES => 'AF',
    STARTING_TIMESTAMP  => CURRENT_TIMESTAMP - 24 HOURS
  )) AS X
  ORDER BY ENTRY_TIMESTAMP DESC

-- Recent user profile changes
SELECT ENTRY_TIMESTAMP, USER_NAME, JOB_NAME, ENTRY_DATA
  FROM TABLE(QSYS2.DISPLAY_JOURNAL(
    'QSYS', 'QAUDJRN',
    JOURNAL_ENTRY_TYPES => 'CP',
    STARTING_TIMESTAMP  => CURRENT_TIMESTAMP - 7 DAYS
  )) AS X
  ORDER BY ENTRY_TIMESTAMP DESC

Journal entry type AF is authority failures — someone tried to access an object they are not allowed to access. This is the most useful audit type for investigating security incidents. CP is user profile changes.

Password policies

Several system values control password policy:

/* Minimum password length */
CHGSYSVAL SYSVAL(QPWDMINLEN) VALUE(10)

/* Password expiry in days */
CHGSYSVAL SYSVAL(QPWDEXPITV) VALUE(90)

/* Prevent reuse of previous passwords */
CHGSYSVAL SYSVAL(QPWDRQDDIF) VALUE(8)

/* Require mixed case */
CHGSYSVAL SYSVAL(QPWDLMTCHR) VALUE(*NONE)
CHGSYSVAL SYSVAL(QPWDRQDDGT) VALUE(1)

/* Lock profile after failed attempts */
CHGSYSVAL SYSVAL(QMAXSIGN) VALUE(5)
CHGSYSVAL SYSVAL(QMAXSGNACN) VALUE(3)  /* 3 = disable profile */

QMAXSGNACN(3) disables a profile after too many failed sign-on attempts. This prevents brute-force attacks but also means your helpdesk will re-enable locked profiles — which is the right trade-off.

A security review checklist

If you have never done a security review on your IBM i system, start here:

  1. Check QSECURITY — if it is 20, upgrading to 30 is the priority above everything else.
  2. Find users with *ALLOBJ — should be a very short list of named administrators only.
  3. Check public authority on sensitive files — payroll, HR, financial data should be *EXCLUDE.
  4. Find disabled users who are still active — former employees whose profiles were not disabled.
  5. Check default passwords — profiles where the password matches the profile name.
  6. Verify QAUDJRN is active — if you are not logging, you cannot investigate incidents.
  7. Review batch job user profiles — batch jobs often run under overpowered profiles unnecessarily.

SQL queries for items 2, 4, and 5:

-- Users with *ALLOBJ special authority
SELECT USER_NAME, STATUS, LAST_USED_TIMESTAMP
  FROM QSYS2.USER_INFO
  WHERE SPECIAL_AUTHORITIES LIKE '%*ALLOBJ%'
  ORDER BY USER_NAME

-- Profiles not used in 90 days (potential former employees)
SELECT USER_NAME, STATUS, LAST_USED_TIMESTAMP, TEXT_DESCRIPTION
  FROM QSYS2.USER_INFO
  WHERE STATUS = '*ENABLED'
    AND LAST_USED_TIMESTAMP < CURRENT_TIMESTAMP - 90 DAYS
    AND USER_NAME NOT IN ('QSYS', 'QSECOFR', 'QTCP', 'QSRVBAS')
  ORDER BY LAST_USED_TIMESTAMP

-- Profiles where password may equal profile name
SELECT USER_NAME, STATUS, PASSWORD_EXPIRATION_INTERVAL
  FROM QSYS2.USER_INFO
  WHERE NO_PASSWORD_INDICATOR = 'NO'
    AND STATUS = '*ENABLED'
  ORDER BY USER_NAME

IBM i security is not set-and-forget. User profiles accumulate, authorities drift, and applications add permissions that are never cleaned up. Running these queries quarterly — and acting on what they show — keeps the security model honest.

Next post: Error handling in RPG — building programs that fail gracefully and tell you why.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top