Contents
Contents

Case Study - Driving Okta Group Membership from PeopleSoft

A question that comes up on almost every identity management project is deceptively simple: where should the rules for group membership live?

When you integrate PeopleSoft with an identity provider like Okta, the default recommendation from the cloud vendor is almost always the same: sync your raw database attributes (department, job code, enrollment status) into Okta, and then use Okta’s native group rules engine to dynamically assign users to groups.

It sounds clean, but in my experience, this approach creates an organizational nightmare.

In this case study, I’ll walk through a real-world project where we rejected Okta’s native rule builder and instead built a custom PeopleSoft-driven sync engine. By shifting the group membership logic back into PeopleSoft queries and security roles, we aligned technical implementation with organizational ownership.

The Real-World Requirement

We were working with a multi-institution university system that needed to manage access controls for tens of thousands of users. In Okta, application access, licensing, and security policies are governed by groups. We had to populate several distinct categories of groups:

  • Affiliation groups: Faculty, Staff, Adjuncts, Students
  • Academic department groups: College of Engineering, School of Education
  • Physical locations: Denver Campus, Online Campus
  • Role-based authorizations: Budget Approvers, Department Chairs, Teaching Assistants
  • Time-bound cohorts: Spring Semester Enrolled Students, Class of 2026

These memberships are highly dynamic. If an employee transfers departments or a student drops all their classes, their group assignments need to change immediately.

Three Ways to Solve the Group Problem

We evaluated three potential designs, balancing technical complexity against long-term maintenance.

Option 1: Active Directory Dynamic Groups

In this model, PeopleSoft syncs raw HR attributes to Active Directory (AD) attributes (e.g., custom extension attributes). We then define dynamic security groups in AD using LDAP filters.

(&(objectCategory=person)(extensionAttribute1=dept:Engineering)(extensionAttribute2=type:Faculty))
  • Why it looked good: It uses native AD capabilities, and memberships update automatically as attributes change.
  • Why we rejected it: It forces AD administrators to write and maintain complex business logic about academic data they don’t understand (e.g., distinguishing an active student from an enrolled student). If a group assignment broke, debugging required mentally parsing raw LDAP syntax across nested AD structures.

Option 2: Okta Native Group Rules

This is the vendor-recommended path. We would push all relevant PeopleSoft attributes into the Okta user profile, then write rules in Okta’s expression language to populate groups.

profile.department == "College of Engineering" && profile.status == "Active" && profile.userType == "Faculty"
  • Why it looked good: It uses Okta’s built-in, visually editable rules engine. No custom sync code required.
  • Why we rejected it: It creates a “game of telephone.” The HR and academic departments own the policies defining who gets access. Under this design, when a policy changed, the business users had to explain it to an Okta administrator, who would then attempt to translate it into an Okta expression. Furthermore, ERP data is full of messy edge cases (like retired faculty who retain library access, or dual-enrollment students) that are incredibly painful to model in a simple cloud rules engine.

Option 3: PeopleSoft Queries and Security Roles

In this model, we treat PeopleSoft as the absolute source of truth for both the data and the rules. We define group membership using standard PeopleSoft security roles or public queries. A batch process (Application Engine: CHG_OKTA_GPSYNC) compares PeopleSoft’s calculated membership against current Okta group membership, determines the differences (adds and removes), and pushes the changes to Okta.

  • Why we chose it: It puts the rules in the hands of the people who actually understand the data. The security and HR teams can write SQL queries or assign security roles in PeopleSoft without needing to understand Okta’s administration console. It also allowed us to write complex SQL joins that would be impossible in Okta’s profile rules.

The Group Sync Architecture

The solution we built uses a declarative configuration model in PeopleSoft.

  flowchart LR
    subgraph peoplesoft ["PeopleSoft"]
        Config["Configuration\n(Role or Query)"] --> AE["Sync Engine\n(CHG_OKTA_GPSYNC)"]
        Data["Business Data\n(JOB, ENROLLMENT)"] --> AE
        AE --> Diff{"Calculate Diff\n(Adds & Removes)"}
    end
    subgraph gateway ["Integration Gateway"]
        Diff -->|Async Web Service| IB["Integration Broker\nQueue"]
    end
    subgraph cloud ["Cloud"]
        IB -->|REST API| Okta["Okta API"]
    end

We configure each group mapping in a custom setup table. The sync engine runs nightly (or more frequently for high-priority groups), pulls the current membership from Okta, executes the local PeopleSoft query or role, calculates the diff, and queues the changes.

Configuration Database Design

PS_CHG_OK_GP_CFG (Sync Rules)

Field Purpose
CHG_OKTA_GRP_ID The Okta internal GUID (e.g., 00g1a2b3c4d5e6f...)
OPRID_ACTIVE Toggle to enable/disable the sync rule
CHG_OK_DATA_SRC Data source type: Q (Query) or R (Role)
PS_QRY_NAME Public Query name (if data source is Query)
PS_ROLE_ID Security Role name (if data source is Role)
CHG_ALLOW_EXCPTN If checked, preserve manually added Okta members (additive sync)
CHG_REPORT_ONLY Run in dry-run mode (generate report, make no changes)
CHG_IDP_TYPES Comma-separated list of IDP User Types to target

PS_CHG_OK_GP_HST (Audit / Diff Log)

Field Purpose
CHG_OKTA_GRP_ID Okta Group GUID
SYNC_RUN_DTTM Timestamp of the sync run
OPRID PeopleSoft Operator ID being evaluated
CHG_OKTA_ID The cached Okta GUID for the user
CHG_SYNC_ACTION Action calculated: A (Add), D (Delete), I (Invalid), N (No Change)
DESCRLONG Details or audit notes (e.g., if preserved via exception flag)

The IDP User Type Multiplier

One of the trickiest details of this integration was handling users with multiple roles. In higher education, it is common for an adjunct faculty member to also be a student, or a staff member to take classes.

Our identity architecture provisioned distinct Okta accounts for these different roles to isolate security contexts (e.g., jsmith@univ.edu for their staff account and jsmith@student.univ.edu for their student account).

When syncing a group like “Engineering Faculty,” we only wanted to add the user’s Faculty Okta account, not their Student account. The CHG_IDP_TYPES configuration field solves this. The sync engine uses this field to filter our local cross-reference table (PS_CHG_OPR_OKTA_ID) to fetch the Okta GUID matching that specific identity type.

Example 1: Campus-Wide Student Group (Query-Driven)

For a large, system-wide student group, we configure the sync to run against a public query:

  • Okta Group ID: 00gydbhibjQUGIKMNORF
  • Data Source: Query (CHG_ACTIVE_STUDENTS)
  • IDP Types: Student
  • Allow Exception: Unchecked (Okta group must match PeopleSoft exactly)

The SQL Query (CHG_ACTIVE_STUDENTS)

Note how we join the business table (PS_ENROLLMENT) to the Okta cross-reference table (PS_CHG_OPR_OKTA_ID). Because business tables store EMPLID and the cross-reference table is keyed by OPRID, we join through PSOPRDEFN to correctly map the keys:

SELECT DISTINCT a.EMPLID, b.CHG_OKTA_ID
FROM PS_ENROLLMENT a
JOIN PSOPRDEFN c ON a.EMPLID = c.EMPLID
JOIN PS_CHG_OPR_OKTA_ID b ON c.OPRID = b.OPRID
WHERE a.TERM_BEGIN_DATE <= %CurrentDate%
  AND a.TERM_END_DATE > %CurrentDate%
  AND a.ENROLL_STATUS = 'E'
  AND b.CHG_IDP_UTYPE = 'Student'

The sync engine runs this query, compares it to the membership retrieved from the Okta API, and pushes the diff.

Example 2: Faculty Group with Exceptions (Hybrid)

Sometimes, you need automated group management but still need to allow manual overrides (e.g., adding a visiting scholar who isn’t in the HR system yet).

  • Okta Group ID: 00gydbhibj8IkWQ7bF3
  • Data Source: Query (CHG_ENG_FACULTY)
  • IDP Types: Faculty, Adjunct
  • Allow Exception: Checked (Additive-only sync)

The SQL Query (CHG_ENG_FACULTY)

SELECT DISTINCT a.EMPLID, b.CHG_OKTA_ID
FROM PS_JOB a
JOIN PSOPRDEFN c ON a.EMPLID = c.EMPLID
JOIN PS_CHG_OPR_OKTA_ID b ON c.OPRID = b.OPRID
WHERE a.SETID_DEPT = 'ENG'
  AND a.JOB_FUNCTION = 'FACULTY'
  AND a.EFF_STATUS = 'A'
  AND a.EFFDT = (SELECT MAX(EFFDT) FROM PS_JOB
                 WHERE EMPLID = a.EMPLID AND EFFDT <= %CurrentDate%)
  AND b.CHG_IDP_UTYPE IN ('Faculty', 'Adjunct')

Because Allow Exception is checked, the sync engine will:

  1. Queue an add request for any faculty member in the query who is missing from the Okta group.
  2. If it finds someone in the Okta group who is not in the query results, it logs a “Delete” action in the audit history but does not send a delete call to the Okta API. This preserves manual additions while automating the bulk of the population.

Lessons in Ownership and Safety

This design taught us a few key lessons about building large-scale security integrations:

1. Separation of Concerns vs. Separation of Context

Okta is the policy enforcement point, but it has no business context. The people who understand HR data and academic enrollment rules are the business analysts running PeopleSoft. Keeping the rules in PeopleSoft allows the analysts to update SQL queries in Query Manager and deploy new group criteria immediately, without having to wait for a security administrator to modify Okta rules.

2. The “Report Only” Safety Net

When you automate group syncs, a bad query can de-provision thousands of users in minutes. We built a CHG_REPORT_ONLY flag into the configuration. When checked, the sync engine runs the entire diff process and writes the results to our custom audit log (PS_CHG_OK_GP_HST) and outputs a CSV, but makes zero API calls. We always run new sync mappings in report-only mode for a few days to verify the diff before turning it loose on the production API.

3. Cleanup of Invalid Users

We also had to handle the case of Okta accounts that existed but had no cross-reference data in PeopleSoft. The sync engine processes these “orphaned” accounts by deleting them synchronously during the run rather than queuing them. Because our async queue depends on a valid local database key to track transactions, we handle these anomalous records immediately and log the cleanup action to the standard system log.

Conclusion

Driving authorization groups from the ERP isn’t the most fashionable approach—modern cloud architects will always push for cloud-native rule engines. But for complex, rule-heavy environments like higher education or large enterprises, putting the logic inside PeopleSoft trades minor operational complexity for absolute context. It ensures that the team that owns the data also owns the rules.

Author Profile
Chris Malek

Chris Malek is a PeopleTools® Technical Consultant with over two decades of experience. He is available for consulting engagements.

Work with Chris
Subscribe to Updates
SWS Bolt-On
PeopleSoft Simple Web Services

SWS turns SQL into production REST APIs — ready for AI, modern apps, and partner integrations. One install, unlimited potential.

  • Configuration-driven, no coding required
  • JSON, XML, and CSV output
  • Works across all PeopleSoft pillars
  • Built on 25+ years of PeopleSoft expertise
Read More & Purchase
SWS Bolt-On
PeopleSoft Simple Web Services

A powerful PeopleSoft bolt-on that makes REST web services easy. You bring the SQL, SWS handles the rest.

  • Go from idea to production in minutes
  • Zero code migrations after install
  • JSON, XML, and CSV output supported
  • No PeopleCode or Integration Broker expertise required
Read More & Purchase
SWS Bolt-On
PeopleSoft Simple Web Services

Traditional PeopleSoft web services cost $3,600–$13,000 each to develop. SWS deploys production REST APIs in under 5 minutes through configuration alone.

  • No PeopleCode or Integration Broker expertise required
  • Works across Campus Solutions, HCM, and Financials
  • Built-in pagination, caching, and nested data structures
  • Trusted by institutions across higher education and government
Read More & Purchase
SWS Bolt-On
PeopleSoft Simple Web Services

Turn PeopleSoft data into clean REST APIs for AI integrations, modern applications, and vendor data feeds. Configuration-driven — no PeopleCode required.

  • Deploy production APIs in under 5 minutes
  • AI and LLM ready (RAG, chatbots, intelligent search)
  • JSON, XML, and CSV output
  • Zero modifications to delivered PeopleSoft objects
Read More & Purchase
psLens Platform
psLens Operations & Intelligence

Look up any record, field, page, or component, audit security, and monitor Integration Broker across every database — in seconds.

  • 30+ object types browsable
  • 16 real-time alert types
  • Read-only by design
  • No App Designer or SQL required
Learn More
psLens Platform
psLens Operations & Intelligence

A web console built for the PeopleSoft community — operational monitoring, security auditing, and metadata browsing in one tool.

  • Sub-second object search
  • Catch stuck IB messages before users do
  • Audit service permissions from one screen
  • Works in any browser
Learn More
psLens Platform
psLens Operations & Intelligence

On-demand security and operational reports for your PeopleSoft environment — no client install required.

  • 14 on-demand reports
  • Markdown export for AI/LLM workflows
  • No shared tenancy
  • Built on 25+ years of PeopleSoft expertise
Learn More
psLens Platform
psLens Operations & Intelligence

Research any PeopleSoft object and monitor system health from a single browser tab — no App Designer, no SQL.

  • 30+ PeopleSoft object types browsable
  • Real-time alerts before users report problems
  • Read-only and secure
  • Private alpha — early access now
Learn More