We recently identified a gap in our user authorization model, and we are developing a solution. First, a little background info...
We have four separate staging environments:
|Staging environment||Description||User authorizations|
|EXP||Experimental: testing new versions, new features, and anything that requires interrupting the system|
|DEV||Development: design, creation, and initial testing of workflows and related scheduling objects|
|ITE||Integrated Testing Environment: testing & validation of workflows using real-world data|
In DEV and ITE, we ensure that users can execute only objects that belong to their particular project, and we control this using a naming convention. All objects begin with a three-character project prefix. Users belong to one or more user group associated with these project prefixes. Each user group grants rights to work with objects of that project prefix.
In PROD, normal users are not allowed to execute objects. Instead, objects must be scheduled using a JSCH object, and these schedule objects are executed automatically as an administrative user when they are deployed to production. This administrative user has broad authorizations in the production system, because it must be able to execute objects belonging to any project prefix. In production, almost all tasks run as this administrative user. Up until now, we have not checked the scripting tabs of objects being deployed to PROD to ensure that users are not doing things the should not. We recently discovered that some users have been using such statements to execute objects outside of their project. These statements — e.g.,
ACTIVATE_UC_OBJECT, would fail in DEV or ITE because they would be run as ordinary users that lack broad access rights; but in PROD, because the calling tasks are started automatically as an administrative user, these statements essentially run unchecked.
We would ideally prefer to solve this problem by executing the schedules are project-specific users — technical (non-personal) users that have limited execution authority for a specific project prefix, but no broader access rights. Unfortunately, until the Automation Engine provides a mechanism for user impersonation, this approach will not be feasible.
So until this User impersonation enhancement is delivered, we need to make sure users are not inserting
ACTIVATE_UC_OBJECT statements into their objects that run objects to which they would normally not have access. This means during a deployment to production, we must check, line-by-line, the content of the scripting tabs of all relevant object types, look for
ACTIVATE_UC_OBJECT statements, and validate that the name of the executable objects referenced in such statements begin with the same project prefix as the calling object.
I already had a script that extracted the scripting lines of z/OS jobs, parse_zOS_jobs_in_transport_case.sh, so I took the code from this script and merged it into the more general transport case parsing script, parse_transport_case.sh. Version 0.7 of this script, posted earlier today, is now capable of printing all scripting tab content of relevant objects — objects with one or more scripting tab. These are: CALL, EVNT, JOBF, JOBG, JOBI, JOBP, JOBS, JSCH, and SCRI.
I wrote a separate script, validate_obj_script.sh, that parses the scripting tab content and performs the required validation of
ACTIVATE_UC_OBJECT statements. I will post this script once it is complete. I realized earlier today that I still have some work to do before it’s ready, because the scope of potentially problematic scripting statements is much broader than just
AE scripting statements that could cause harm include:
|ACTIVATE_UC_OBJECT||Execute an arbitrary object in the system.||Task|
|CANCEL_UC_OBJECT||Terminate an active task.||Task|
|CREATE_OBJECT||Create a calendar, login, or static VARA object.||Object|
|MODIFY_OBJECT||Modify a calendar, login, or static VARA object.||Object|
|MODIFY_SYSTEM||Perform various system administration tasks.||System|
|MODIFY_TASK||Modify a task within an active workflow.||Task|
|MODIFY_UC_OBJECT||Modifiy an attribute of an active task.||Task|
|MOVE_OBJECT||Move an object to a different folder.||Object|
|REMOVE_OBJECT||Remove an AE object from the system.||Object|
|:REPLACE_STRUCTURE||Replace the structure of a workflow with the structure of another workflow.||Task|
|RERUN_UC_OBJECT||Continue a workflow that has been rolled back.||Task|
|RESTART_UC_OBJECT||Restart a task.||Task|
|ROLLBACK_UC_OBJECT||Roll back a task.||Task|
|SET_SYNC||Perform an action defined in a SYNC object.||Sync|
|:SET_UC_SETTING||Change system settings during system operation.||System|
|:SHUTDOWN||Shut down the Automation Engine completely.||System|
|:TERMINATE||Stop an agent or Automation Engine server process.||System|
|TOGGLE_OBJECT_STATUS||Stop or start the automatic processing of a task.||Task|
|TOGGLE_SYSTEM_STATUS||Stop or start the automatic processing of a client.||System|