# PeopleTools Access Audit

LLMS index: [llms.txt](/llms.txt)

---

<div class="alert alert-primary border shadow-sm mb-4" role="note">
  <div class="d-flex flex-column flex-lg-row align-items-lg-center justify-content-between gap-3">
    <div>
      <strong>New to psLens?</strong> This page documents one specific report. To see how it runs in the product, what
      the output looks like, and how teams use it in practice, start with a live walkthrough.
    </div>
    <div class="d-flex flex-wrap gap-2">
      <a class="btn btn-sm btn-primary" href="/contact/">Book a Demo</a>
      <a class="btn btn-sm btn-outline-primary" href="/docs/reports/">Browse Reports</a>
    </div>
  </div>
</div><div id="pslens-context-panel" class="card border-info mb-4 d-none">
  <div class="card-header bg-light text-info py-2 fw-bold d-flex align-items-center border-bottom border-info-subtle">
    <i class="bi bi-info-circle-fill me-2"></i>
    <span>Tailored Operational Context</span>
  </div>
  <div class="card-body p-0">
    <ul class="list-group list-group-flush">
      <li id="row-db" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Target Database:</strong>
        <span id="ctx-db" class="badge bg-secondary font-monospace">&mdash;</span>
      </li>
      <li id="row-type" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Context Type:</strong>
        <span id="ctx-type" class="badge bg-light text-dark border font-monospace text-uppercase">&mdash;</span>
      </li>
      <li id="row-severity" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Alert Severity:</strong>
        <span id="ctx-severity" class="badge">&mdash;</span>
      </li>
      <li id="row-time" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Triggered Time:</strong>
        <span id="ctx-time" class="text-muted small">&mdash;</span>
      </li>
      <li id="row-details" class="list-group-item py-2 d-none">
        <strong id="label-details" class="d-block mb-1">Firing Context:</strong>
        <code id="ctx-details" class="d-block p-2 bg-light border rounded small"
          style="white-space: pre-wrap; word-break: break-all;">&mdash;</code>
      </li>
    </ul>
  </div>
</div>

<script>
  (function () {
    const params = new URLSearchParams(window.location.search);
    const metadata = params.get('metadata');
    if (!metadata) return;

    try {
      
      const base64 = metadata.replace(/-/g, '+').replace(/_/g, '/');
      const jsonStr = decodeURIComponent(escape(window.atob(base64)));
      const data = JSON.parse(jsonStr);

      if (data) {
        let hasData = false;

        if (data.db) {
          document.getElementById('ctx-db').textContent = data.db;
          document.getElementById('row-db').classList.remove('d-none');
          hasData = true;
        }

        if (data.type) {
          document.getElementById('ctx-type').textContent = data.type;
          document.getElementById('row-type').classList.remove('d-none');
          hasData = true;
        }

        if (data.severity) {
          const severityBadge = document.getElementById('ctx-severity');
          const severity = data.severity.toLowerCase();
          severityBadge.textContent = severity.toUpperCase();
          if (severity === 'critical') {
            severityBadge.className = 'badge bg-danger';
          } else if (severity === 'warning') {
            severityBadge.className = 'badge bg-warning text-dark';
          } else {
            severityBadge.className = 'badge bg-info';
          }
          document.getElementById('row-severity').classList.remove('d-none');
          hasData = true;
        }

        if (data.t) {
          const date = new Date(data.t * 1000);
          document.getElementById('ctx-time').textContent = date.toLocaleString();
          document.getElementById('row-time').classList.remove('d-none');
          hasData = true;
        }

        if (data.details) {
          document.getElementById('ctx-details').textContent = data.details;

          
          const labelDetails = document.getElementById('label-details');
          if (data.type === 'object') {
            labelDetails.textContent = 'Object Metadata Details:';
          } else if (data.type === 'report') {
            labelDetails.textContent = 'Report Description:';
          } else {
            labelDetails.textContent = 'Firing Context:';
          }

          document.getElementById('row-details').classList.remove('d-none');
          hasData = true;
        }

        if (hasData) {
          document.getElementById('pslens-context-panel').classList.remove('d-none');
        }
      }
    } catch (e) {
      console.error('Failed to parse operational context metadata:', e);
    }
  })();
</script>

## PeopleTools Access Audit Report

**Report ID:** `security-peopletools-access`
**Category:** Security
**Default Parameter:** `activeOnly = false`

## Purpose

Special PeopleTools access (Application Designer, Data Mover, Object Security, Query, Import Manager, 2-Tier Client) is granted on the PeopleTools tab of a permission list and recorded in `PSAUTHITEM`. This report lists every user who holds any of that access and the path that grants it: permission list to role to user.

## What It Detects

For each PeopleTools application, the permission lists that grant it, the roles that carry those permission lists, and the users in those roles. Each grant is marked **Full** (edit) or **Read-only** based on `PSAUTHITEM.DISPLAYONLY`. Each user is marked **Active** or **Locked** from `PSOPRDEFN.ACCTLOCK`.

The tools tracked are the `MENUNAME` values PeopleSoft uses for standalone tools access:

- `APPLICATION_DESIGNER` — Application Designer
- `OBJECT_SECURITY` — Object Security (Definition Security tool)
- `DATA_MOVER` — Data Mover
- `IMPORT_MANAGER` — Import Manager
- `QUERY` — Query
- `CLIENTPROCESS` — 2-Tier Client

## Tables Queried

- `PSCLASSDEFN` — permission list names and descriptions.
- `PSAUTHITEM` — tools access grants (`MENUNAME`, `DISPLAYONLY`).
- `PSROLECLASS` — which roles include each permission list.
- `PSROLEUSER` — which users hold each role.
- `PSOPRDEFN` — account lock status (`ACCTLOCK`) and primary permission list (`OPRCLASS`).
- `PSOPROBJ` — Definition Security grants: permission list to object group, with `DISPLAYONLY` (edit vs read-only).
- `PSOBJGROUP` — object group membership (which definitions belong to a custom group).

## Report Output

Four sections:

1. **Summary** — count of permission lists and distinct users per tool, plus the total number of users with any special access.
2. **Access by Tool** — each tool with its permission lists (Full or Read-only), descriptions, and the roles that carry them.
3. **Access by User** — every in-scope user with their account status, the tools they hold and at what level, a **Def. Security** column (can they edit definitions), and the permission lists and roles that grant them.
4. **Definition Security (Object Security)** — object group grants (`PSOPROBJ`): which permission lists can edit or read the definitions in each object group, and which users that reaches via primary permission list and roles.

Permission lists, roles, and users link back to their psLens detail pages.

## Parameters

|  Parameter   | Default |                            Description                             |
| ------------ | ------- | ------------------------------------------------------------------ |
| `activeOnly` | `false` | When `true`, restrict the user sections to unlocked accounts only. |

## Interpreting Results

- **Full vs Read-only.** Read-only Application Designer access can open and inspect definitions but not save changes. Full access can modify them. Treat Full access in a production database as the higher risk.
- **Locked users.** Locked accounts still hold the grant. They appear so you can audit dormant access that would return if the account is unlocked. Set `activeOnly = true` to hide them.
- **Object Security.** Access to the Object Security tool lets a user change Definition Security itself, which governs which definitions developers can edit.

## Definition Security details

Holding Application Designer access lets a developer open the tool. What definitions they can edit is controlled by Definition Security object groups (`PSOBJGROUP`) linked to permission lists through `PSOPROBJ`. The `DISPLAYONLY` flag on that link is the difference between read-only and edit access.

The delivered **PEOPLETOOLS** object group holds the system definitions and is read-only by default. An **Edit** grant on it (`DISPLAYONLY = 0`) means the permission list can modify delivered PeopleTools objects in Application Designer — a high-privilege grant worth auditing.

The report applies these grants to users through both their primary permission list (`PSOPRDEFN.OPRCLASS`) and their roles, and labels which path reaches each user. Permission-list-level grants are reported exactly from `PSOPROBJ`; the user roster is the set reached through those permission lists.
