IBM i Security
Audit Restored IBM i Job Descriptions That Specify a User Profile
Use QSYS2.DISPLAY_JOURNAL to find and decode RJ audit entries for restored IBM i job descriptions that specify a user profile, assess post-restore authority exposure, and build a controlled recovery review.
A restored IBM i job description can quietly reintroduce a named user profile into the way future jobs are started. The RJ audit entry identifies restored job descriptions whose USER parameter specifies a profile, including the current and previous profile values.
This matters after:
- disaster-recovery testing
- production recovery
- system migration
- environment refresh
- application-library restoration
- individual object restoration
The central questions are:
Which job description was restored?
Which library received it?
What profile is now specified?
Was a different profile previously specified?
Who performed the restore?
Which job and program performed the work?
Does the restored configuration match the target environment?
The RJ audit entry
IBM defines audit entry type:
RJ
as restoring a job description that contains a user profile in its USER parameter.
The entry-specific data includes:
ENTRY_TYPE
JOB_DESCRIPTION_NAME
LIBRARY_NAME
OBJECT_TYPE
USER_NAME
ASP_NAME
ASP_NUMBER
PREVIOUS_USER_NAME
For ENTRY_TYPE, the value A means that a job description with a profile specified in USER was restored.
Important service limitation
IBM does not currently document a dedicated function named:
SYSTOOLS.AUDIT_JOURNAL_RJ
For RJ entries, use:
QSYS2.DISPLAY_JOURNAL
CPYAUDJRNE
DISPLAY_JOURNAL exposes the common audit metadata and raw ENTRY_DATA through SQL. CPYAUDJRNE can copy all RJ fields to a formatted outfile.
Find recent RJ entries
SELECT
ENTRY_TIMESTAMP,
SEQUENCE_NUMBER,
JOURNAL_ENTRY_TYPE,
USER_NAME AS RESTORE_RUN_BY,
QUALIFIED_JOB_NAME,
PROGRAM_LIBRARY,
PROGRAM_NAME,
RECEIVER_LIBRARY,
RECEIVER_NAME,
ENTRY_DATA
FROM TABLE(
QSYS2.DISPLAY_JOURNAL(
JOURNAL_LIBRARY => 'QSYS',
JOURNAL_NAME => 'QAUDJRN',
STARTING_RECEIVER_NAME => '*CURAVLCHN',
JOURNAL_ENTRY_TYPES => 'RJ',
STARTING_TIMESTAMP => CURRENT TIMESTAMP - 7 DAYS
)
)
ORDER BY
ENTRY_TIMESTAMP DESC,
SEQUENCE_NUMBER DESC;
Decode the RJ entry-specific data
DISPLAY_JOURNAL returns ENTRY_DATA as a BLOB. In the RJ type-5 layout, the fields begin at these relative positions inside the entry-specific payload:
1 Entry type CHAR(1)
2 Job description name CHAR(10)
12 Library name CHAR(10)
22 Object type CHAR(8)
30 Current user name CHAR(10)
40 ASP name CHAR(10)
50 ASP number CHAR(5)
55 Previous user name CHAR(10)
Use SQL to decode the values:
WITH RJ_ENTRIES AS
(
SELECT
J.*,
CAST(
CAST(SUBSTRING(ENTRY_DATA, 1, 1)
AS CHAR(1) FOR BIT DATA)
AS CHAR(1) CCSID 37
) AS RJ_ENTRY_TYPE,
TRIM(CAST(
CAST(SUBSTRING(ENTRY_DATA, 2, 10)
AS CHAR(10) FOR BIT DATA)
AS CHAR(10) CCSID 37
)) AS JOB_DESCRIPTION,
TRIM(CAST(
CAST(SUBSTRING(ENTRY_DATA, 12, 10)
AS CHAR(10) FOR BIT DATA)
AS CHAR(10) CCSID 37
)) AS JOB_DESCRIPTION_LIBRARY,
TRIM(CAST(
CAST(SUBSTRING(ENTRY_DATA, 22, 8)
AS CHAR(8) FOR BIT DATA)
AS CHAR(8) CCSID 37
)) AS RESTORED_OBJECT_TYPE,
TRIM(CAST(
CAST(SUBSTRING(ENTRY_DATA, 30, 10)
AS CHAR(10) FOR BIT DATA)
AS CHAR(10) CCSID 37
)) AS RESTORED_USER,
TRIM(CAST(
CAST(SUBSTRING(ENTRY_DATA, 40, 10)
AS CHAR(10) FOR BIT DATA)
AS CHAR(10) CCSID 37
)) AS ASP_NAME,
TRIM(CAST(
CAST(SUBSTRING(ENTRY_DATA, 50, 5)
AS CHAR(5) FOR BIT DATA)
AS CHAR(5) CCSID 37
)) AS ASP_NUMBER,
TRIM(CAST(
CAST(SUBSTRING(ENTRY_DATA, 55, 10)
AS CHAR(10) FOR BIT DATA)
AS CHAR(10) CCSID 37
)) AS PREVIOUS_USER
FROM TABLE(
QSYS2.DISPLAY_JOURNAL(
JOURNAL_LIBRARY => 'QSYS',
JOURNAL_NAME => 'QAUDJRN',
STARTING_RECEIVER_NAME => '*CURAVLCHN',
JOURNAL_ENTRY_TYPES => 'RJ',
STARTING_TIMESTAMP => CURRENT TIMESTAMP - 30 DAYS
)
) AS J
)
SELECT
ENTRY_TIMESTAMP,
USER_NAME AS RESTORE_RUN_BY,
QUALIFIED_JOB_NAME,
PROGRAM_LIBRARY,
PROGRAM_NAME,
JOB_DESCRIPTION_LIBRARY,
JOB_DESCRIPTION,
RESTORED_OBJECT_TYPE,
PREVIOUS_USER,
RESTORED_USER,
ASP_NAME,
ASP_NUMBER,
RECEIVER_LIBRARY,
RECEIVER_NAME,
SEQUENCE_NUMBER
FROM RJ_ENTRIES
WHERE RJ_ENTRY_TYPE = 'A'
ORDER BY
ENTRY_TIMESTAMP DESC,
SEQUENCE_NUMBER DESC;
CCSID considerations
The example uses CCSID 37, a common North American EBCDIC CCSID. Use the CCSID appropriate for your system and audit data.
If values appear corrupted:
- confirm the system and job CCSID
- test the matching EBCDIC CCSID
- review the ACS JDBC setting for translating CCSID 65535
- compare the decoded values with
CPYAUDJRNE - do not treat corrupted output as valid security evidence
Find profile changes introduced by restore
The most important records are those where the restore changed the named profile:
SELECT
ENTRY_TIMESTAMP,
RESTORE_RUN_BY,
QUALIFIED_JOB_NAME,
JOB_DESCRIPTION_LIBRARY,
JOB_DESCRIPTION,
PREVIOUS_USER,
RESTORED_USER,
ASP_NAME,
ASP_NUMBER
FROM RECOVERY.RJ_AUDIT_VIEW
WHERE COALESCE(PREVIOUS_USER, '') <>
COALESCE(RESTORED_USER, '')
ORDER BY
ENTRY_TIMESTAMP DESC;
This can reveal:
- a production profile restored into a test partition
- a source-system service profile replacing a target-system profile
*RQDreplaced by a named profile- one named profile replacing another
- a locally hardened job description being overwritten
Find *RQD replaced by a named profile
SELECT
ENTRY_TIMESTAMP,
RESTORE_RUN_BY,
JOB_DESCRIPTION_LIBRARY,
JOB_DESCRIPTION,
PREVIOUS_USER,
RESTORED_USER
FROM RECOVERY.RJ_AUDIT_VIEW
WHERE PREVIOUS_USER = '*RQD'
AND RESTORED_USER <> '*RQD'
ORDER BY
ENTRY_TIMESTAMP DESC;
The final security effect still depends on QSECURITY, object authority, profile authority, submission method, and overrides.
Compare with current state
The RJ entry records what the restore introduced. QSYS2.JOB_DESCRIPTION_INFO shows the current job-description value.
SELECT
R.ENTRY_TIMESTAMP,
R.JOB_DESCRIPTION_LIBRARY,
R.JOB_DESCRIPTION,
R.PREVIOUS_USER,
R.RESTORED_USER,
I.AUTHORIZATION_NAME
AS CURRENT_JOB_DESCRIPTION_USER,
CASE
WHEN I.JOB_DESCRIPTION IS NULL
THEN 'JOBD NOT FOUND'
WHEN COALESCE(I.AUTHORIZATION_NAME, '') =
COALESCE(R.RESTORED_USER, '')
THEN 'CURRENT MATCHES RESTORE'
ELSE 'CHANGED AFTER RESTORE'
END AS CURRENT_STATE
FROM RECOVERY.RJ_AUDIT_VIEW AS R
LEFT JOIN QSYS2.JOB_DESCRIPTION_INFO AS I
ON I.JOB_DESCRIPTION_LIBRARY =
R.JOB_DESCRIPTION_LIBRARY
AND I.JOB_DESCRIPTION =
R.JOB_DESCRIPTION
ORDER BY
R.ENTRY_TIMESTAMP DESC;
A mismatch may be legitimate, but it should be correlated with later JD audit entries and approved change activity.
Correlate RJ and JD activity
A useful timeline is:
RJ Job description restored with a named user
JD USER parameter created or changed later
This helps answer:
Was the restored profile accepted?
Was it corrected after restore?
Who corrected it?
Was it later changed back?
See:
Audit IBM i Job Description USER Changes with SQL
Create a protected evidence table
CREATE TABLE RECOVERY.RJ_AUDIT_EVIDENCE
(
SOURCE_SYSTEM VARCHAR(8) NOT NULL,
RECEIVER_LIBRARY VARCHAR(10) NOT NULL,
RECEIVER_NAME VARCHAR(10) NOT NULL,
SEQUENCE_NUMBER DECIMAL(21, 0) NOT NULL,
ENTRY_TIMESTAMP TIMESTAMP NOT NULL,
RESTORE_RUN_BY VARCHAR(10),
QUALIFIED_JOB_NAME VARCHAR(28),
PROGRAM_LIBRARY VARCHAR(10),
PROGRAM_NAME VARCHAR(10),
JOB_DESCRIPTION_LIBRARY VARCHAR(10),
JOB_DESCRIPTION VARCHAR(10),
PREVIOUS_USER VARCHAR(10),
RESTORED_USER VARCHAR(10),
ASP_NAME VARCHAR(10),
ASP_NUMBER VARCHAR(5),
REVIEW_STATUS VARCHAR(24) NOT NULL,
CHANGE_REFERENCE VARCHAR(128),
REVIEW_NOTES VARCHAR(2048),
PRIMARY KEY
(
SOURCE_SYSTEM,
RECEIVER_LIBRARY,
RECEIVER_NAME,
SEQUENCE_NUMBER
)
);
Useful statuses include:
NEW
EXPECTED
REVIEW REQUIRED
ENVIRONMENT MISMATCH
CORRECTED
APPROVED EXCEPTION
UNAUTHORIZED
Use bounded collection
A scheduled collector should preserve:
Journal
Receiver library
Receiver name
Sequence number
Entry timestamp
Collector
Status
Do not store only sequence number because journal sequences can be reset.
A safe cycle is:
Read a bounded receiver and sequence range
Decode RJ entries
Insert into the protected evidence table
Suppress duplicates
Commit the batch
Advance the checkpoint
Use CPYAUDJRNE when formatted output is preferable
CPYAUDJRNE ENTTYP(RJ)
JRNRCV(*CURCHAIN)
OUTFILE(AUDITLIB/RECOVERY)
The command creates an entry-type-specific output file, typically with an RJ suffix. Query it with SQL after confirming the generated column names with QSYS2.SYSCOLUMNS, ACS schema details, or DSPFFD.
CPYAUDJRNE supports every audit entry type and copies all formatted fields, but it requires *AUDIT special authority.
Why a restored JOBD can be risky
A restored job description may be valid on the source system but unsafe on the target:
The profile has more authority on the target
The profile should not exist in nonproduction
The profile references production integration credentials
The target expected USER(*RQD)
The restore overwrote a local hardening change
The job description is publicly usable
The RJ entry shows that the configuration was restored. It does not prove that the profile was later used.
Determine where the job description is used
Investigate:
- job scheduler entries
- subsystem job entries
- autostart job entries
- workstation entries
SBMJOBwrappers- CL and RPG source references
- third-party schedulers
- deployment automation
- operational runbooks
A restored value becomes an active exposure when a job-initiation path uses it.
Auditing and authority requirements
RJ evidence depends on save-and-restore auditing being active and the required QAUDJRN receivers being retained.
Review:
QAUDCTL
QAUDLVL
QAUDLVL2
*SAVRST coverage
QAUDJRN receiver retention
For QSYS2.DISPLAY_JOURNAL, the caller needs appropriate authority to the journal, its library, and every requested receiver and receiver library. Use a dedicated audit-reporting profile rather than broad special authority.
Recovery sign-off checklist
Collect RJ entries for the recovery window
Decode and validate each restored JOBD profile
Compare source and target environment policy
Review every profile difference
Correlate later JD entries
Validate current JOBD state
Review JOBD and profile authority
Identify scheduler and submission paths
Test critical jobs
Preserve receiver and sequence evidence
Obtain owner approval
Final takeaway
A restored job description can carry a user identity from one environment into another.
The RJ audit entry preserves:
The restored job description
Its library
The current named profile
The previous named profile
The ASP
The restore job
The effective user
The receiver and sequence
IBM does not currently provide a dedicated formatted AUDIT_JOURNAL_RJ SQL service.
Use QSYS2.DISPLAY_JOURNAL to retrieve the entry, decode the documented RJ format, preserve the evidence, and compare it with the target environment’s approved security model.
A successful restore confirms that an object returned. It does not confirm that the restored identity is safe.
Comments
Share your thoughts, questions, or real-world IBM i experiences related to this article.