SWS Security Setup
Categories:
SWS has several layers of security for the web services. Additionally, security is required for a few custom components that are delivered with SWS that power-user use to configure SWS. We will discuss those here.
For SWS, there are two main areas of security.
- API users who need to use call an SWS web service.
- Security for Administrators to create and update SWS configurations.
- This security is just needed by trusted users who will be configuring SWS web services.
SWS API User Security
SWS is based on PeopleSoft REST framework. The security mechanism that exists for REST is based on standard PeopleSoft PSOPRDEFN
OPRIDs
and passwords. We will walk through how this works and the best practices in this section. SWS is backed by a custom PeopleSoft REST Service.
For API users that need to invoke SWS web services, they need to be setup as a valid PeopleSoft user.
The technical design of SWS is actually structured around one PeopleSoft service operation called CHG_SWS_GET
. All SQL statements that you deploy as a web service are handled by this one service operation and PeopleCode Handler. Therefore, all API users will need this base service operation as part of their security.
There are a few layers to security with SWS:
- PeopleSoft OPRID and Password
- The basic auth token provided must be a valid PeopleSoft OPRID and password. The PeopleSoft IB will authenticate the OPRID and password. If the OPRID is not valid or the password is incorrect, the IB will return an error.
- The REST Service Account OPRID’s access to the Service Operation
CHG_SWS_GET
- The authenticated OPRID must have access to the
CHG_SWS_GET
service operation. If the OPRID does not have access, the IB will return an error.
- The authenticated OPRID must have access to the
- The SWS Configuration Security setup for the Path.
- The authenticated OPRID must have access to the SWS configuration for the path. If the OPRID does not have access, the SWS will return an error.
- The configured SQL or PsoftQL could also have data security configured to limit what data is returned to the client.
@startuml
participant "HTTP Client" as client
participant "PeopleSoft IB" as psib
participant "SWS Handler" as pssws
client -> psib: HTTP Request\nBasic Auth Token
psib -> psib: Authenticate\nOPRID and Password
psib -> psib: Check Access\nTo Service Operation
psib -> pssws: Call Service Operation\nCHG_SWS_GET
pssws -> pssws: Lookup SWS\nConfiguration
pssws -> pssws: Is User Authorized?
pssws -> pssws: Convert Configuration into SQL
pssws -> pssws: Get Data
pssws -> client: Return Data
@enduml
The handler PeopleCode in the CHG_SWS_GET operation actually performs some additional checks on the current user to determine if they have access to execute the SQL statement at the path. Those permission lists are configured on the SWS setup table (COMPONENT: CHG_SWS_CONF_TBL). If an API user tries to invoke a SWS SQL statement and they do NOT have security, the SQL will NOT be run.
What is required to create an API User for SWS?
- Create a new OPRID that represents the client using the application.
- Give that OPRID a complex password. This password stored in PSOPRDEFN will be used in the authentication.
- Give that OPRID access to the Service Operation
CHG_SWS_GET
- You can use the role
CHG_SWS_USER
for this purpose.
- You can use the role
- Give that user access to some other unique permission list that identifies it and that you can use to secure the SWS setup.
- When the clients tries to trigger an SWS web service, the API User OPRID must have a permission list configured on the SQL statement. Each SWS SQL statement is tagged with permission lists that are allowed to execute it.
You can use the security objects we delivered as part of the project or use your own permission lists based on your own standard.
SWS API Delivered Security:
- Permission List: CHG_SWS_USER
- Service: CHG_SWS, Service Operation: CHG_SWS_GET
- Role: CHG_SWS_USER
- Permission List: CHG_SWS_USER
Example User ID and Basic Authentication Code
Let’s imagine we want to set up a test API user account to manually test web services.
- Create a new OPRID called
Z_TEST_API_USER
- Create a complex randomly generated password. We will use
proctor-consular-esther-hull-flood
for this example. - The EMPLID can be set to nothing.
- Set the other required fields to your system’s normal default values for a low-level non-privileged account.
- Create a complex randomly generated password. We will use
- Give OPRID
Z_TEST_API_USER
the roleCHG_SWS_USER
- Create a permission list called
Z_TEST_API_USER
. This will not have any real permission in the security tab. We will use it in the SWS configuration. - Create a new role called
Z_TEST_API_USER
and assign it theZ_TEST_API_USER
permission list. - Grant user
Z_TEST_API_USER
the newZ_TEST_API_USER
role.
Now that we have our OPRID and password we can generate an HTTP Basic Authentication token using the following scheme.
- Concatenate the OPRID and password together with a colon. That gives us:
Z_TEST_API_USER:proctor-consular-esther-hull-flood
- Base64 encode that concatenated string.
Z_TEST_API_USER:proctor-consular-esther-hull-flood
–>Wl9URVNUX0FQSV9VU0VSOnByb2N0b3ItY29uc3VsYXItZXN0aGVyLWh1bGwtZmxvb2Q=
- Many text editors and HTTP test clients like Postman have base64 encoding functions built in. There are also tools online that will do this but I would not trust those with my production passwords.
- The base64 encoded output servers as the token and is used in an HTTP Basic authorization header in the following form:
Authorization: Basic Wl9URVNUX0FQSV9VU0VSOnByb2N0b3ItY29uc3VsYXItZXN0aGVyLWh1bGwtZmxvb2Q=
Security Best Practices
For these best practices, we are going to imagine three fictional internal systems that will be calling SWS web services that we can use in our example.
- Stellar Wind - Internal Payment System
- PRISM - Internal CRM system
- MYSTIC - Internal Marketing System
Based on those three systems, we will show you the recommended security setup for these API users. Your security team may vary this depending on your own standards.
- For each client or external system calling your web service, create a new and unique OPRID. Do not reuse a super user or real user account for this. Create a new account that only has the minimum API security and no PIA login ability.
- For our three internal systems that may look like:
- OPRID: Z_STELLAR_WIND_API_USER
- OPRID: Z_PRISM_API_USER
- OPRID: Z_MYSTIC_API_USER
- Do not share API user accounts across systems.
- Shared accounts make password rotation nearly impossible since you have to coordinate with more than one group.
- Shared accounts also make auditing more difficult.
- Having separate accounts makes it easy for you to shut off one system and not impact the others.
- For our three internal systems that may look like:
- Each API User should have a complex password that is generated by a password manager.
- Store your passwords in some sort of password database.
- Do NOT email passwords to users. Emails persist forever.
- The API Users should store the password in a secure location that easily facilitates password rotation.
- The password should NOT be hard coded in the source code.
- This could be an environment variable or something more advanced like Hashicorp Vault
- Each API user may have a distinct permission list that identifies it and that you can use in SWS. The API user may have access to other PeopleSoft APIs. We often recommend creating a permission list and a role that is equal to the OPRID. Your security standard may be different. We find this simple model for API client OPRIDs is effective and allows visibility into what permissions an API user has. (OPRID = ROLENAME = CLASSID). API Clients tend to have very specific permissions that are not shared across other users.
- For our three internal systems that may end up looking like this:
- OPRID: Z_STELLAR_WIND_API_USER
- ROLE: CHG_SWS_USER
- Permission List: CHG_SWS_USER
- ROLE: Z_STELLER_WIND_API_USER
- Permission List: Z_STELLER_WIND_API_USER
- ROLE: CHG_SWS_USER
- OPRID: Z_PRISM_API_USER
- ROLE: CHG_SWS_USER
- Permission List: CHG_SWS_USER
- ROLE: Z_PRISM_API_USER
- Permission List: Z_PRISM_API_USER
- ROLE: CHG_SWS_USER
- OPRID: Z_MYSTIC_API_USER
- ROLE: CHG_SWS_USER
- Permission List: CHG_SWS_USER
- ROLE: Z_MYSTIC_API_USER
- Permission List: Z_MYSTIC_API_USER
- ROLE: CHG_SWS_USER
- OPRID: Z_STELLAR_WIND_API_USER
- For our three internal systems that may end up looking like this:
Our Integration Broker book has a detailed section on how REST Security in PeopleSoft works. That is great reference.
SWS Administrator Security
For user’s who will be maintaining SWS configuration, they need access to the setup component for SWS. You can use the permission list and role that we delivered with the project or use one that works with your security standard.
SWS Administrator Delivered Security:
- Permission List:
CHG_SWS_ADMIN
- MENU:
CHG_TOOLS
, COMPONENT:CHG_SWS_CONF_TBL
- Service:
CHG_SWS
, Service Operation:CHG_SWS_GET
- MENU:
- Role:
CHG_SWS_ADMIN
- Permission List:
CHG_SWS_ADMIN
- Permission List:
Research Queries
This SQL will find the user’s who have access to the SWS Web Services.
- User’s who have access to Service Operation:
CHG_SWS_PSOFTQL_POST
should be extremely limited.
-- Find User's who have access to the
-- SWS Web Services
SELECT
A.OPRID ,
B.ROLENAME ,
C.CLASSID ,
O.IB_OPERATIONNAME,
AU.CLASSID
FROM
PSOPRDEFN A ,
PSROLEUSER B ,
PSROLECLASS C ,
PSOPERATION O,
PSAUTHWS AU
WHERE
A.OPRID = B.ROLEUSER
AND B.ROLENAME = C.ROLENAME
AND O.IB_OPERATIONNAME LIKE 'CHG_SWS%'
AND O.IB_OPERATIONNAME = AU.IB_OPERATIONNAME
AND AU.CLASSID = C.CLASSID
ORDER BY
A.OPRID,
B.ROLENAME;
Find user’s who can access CHG_SWS_GET and the path’s they can execute
--- Find user's who can access CHG_SWS_GET and the path's they can execute
SELECT
A.OPRID ,
B.ROLENAME ,
C.CLASSID ,
O.IB_OPERATIONNAME,
SWSC.CHG_DE_PATH
FROM
PSOPRDEFN A ,
PSROLEUSER B ,
PSROLECLASS C ,
PSOPERATION O,
PSAUTHWS AU, PS_C_SWS_CONF_TBL SWSC, PS_C_SWS_CONF_PL SWSPL
WHERE
A.OPRID = B.ROLEUSER
AND B.ROLENAME = C.ROLENAME
AND O.IB_OPERATIONNAME = 'CHG_SWS_GET'
AND O.IB_OPERATIONNAME = AU.IB_OPERATIONNAME
AND AU.CLASSID = C.CLASSID
AND SWSPL.CLASSID = AU.CLASSID
AND SWSC.GUID = SWSPL.GUID;