Bulk Imports of Sudo Rules for Okta Privileged Access using Workflows

This article showcases two new features of Okta Privileged AccessSudo command bundles and the Okta Privileged Access Workflows connector. It shows how a standard workflow mechanism can be used for bulk-loading sudo commands, specifically for commands to work with OpenLDAP.

Introduction

Okta recently released two new capabilities to Okta Privileged Access.

The first is Sudo command bundles, where sets of commands can be bundled together and distributed to Linux servers as sudo command files (sudoers.d files). This allows for a more granular access model between user-level access and admin-level access available beforehand.

The second is an Okta Privileged Access Workflows connector. This provides workflows actions for many of the Okta Privileged Access APIs, and where there isn’t a card provided, there’s a Custom API Action card. Use of the connector significantly simplifies running APIs as you configure the authentication when you setup the connector and don’t need to worry about it when building and running the workflows.

Combining these two features, we can implement a bulk import mechanism for Sudo command bundles. This article explores a mechanism built in Okta Workflows to import a CSV file with a set of commands and create a command bundle in Okta Privileged Access.

The article uses a pair CSV files for two sets of OpenLDAP commands. But you could build out a library of command set files and import them into Okta Privileged Access as needed.

An Example – Importing OpenLDAP Commands

In this section we look at an implementation of the utility, to import two sets of OpenLDAP commands for an Ubuntu implementation.

OpenLDAP Commands

OpenLDAP has two sets of commands:

  • A set of commands for use of the product, like ldapsearch for searching for objects in the directory. These are found in /usr/bin and all start with “ldap“,
  • A set of commands for administration of the product. These include a set of “slap” executables found in /usr/sbin. There are other administrative commands, such as dpkg-reconfigure slapd.

A standard installation of OpenLDAP will have both sets of commands executable by anyone, relying on directory-level access control to restrict who can do what.

We have chosen these commands as an example for the import as they are easy to define. If you were to implement them as sudo command bundles in Okta Privileged Access you should tighten up “world” permissions on the files on the relevant server.

The Import Files

The import mechanism we are showing here imports a single CSV file for each sudo command bundle in Okta Privileged Access. They have a fixed structure (that will be explained later in this article). The name of the file is used as the name of the sudo command bundle. The filename cannot have spaces.

The first file is OpenLDAP_Ubuntu_User_commands. It contains all of the /usr/bin/ldap* commands.

The second file is OpenLDAP_Ubuntu_Admin_commands. it contains all of the /usr/sbin/slap* commands and also the /usr/sbin/dpkg-reconfigure slapd command.

Using files like this means you can maintain a library of the command bundles outside of Okta Privileged Access, perhaps leveraging some version control mechanism.

Command Bundles after Import

After these files have been imported using the Workflows-based import mechanism, you see two sudo command bundles. They are named the same as the filename so that they can be easily tracked back to the source files. The user associated with them is the service user assigned to the Workflows connector.

Looking at the user commands bundle, we can see the name and description (it can be entered at import time or otherwise the import mechanism will take and – or _ from the name).

If we scroll down the command bundle, we see the various commands that were in the CSV file.

Similarly the admin commands can be seen in the other sudo command bundle.

The import mechanism will only create the command bundles, it does not do anything with policies or rules. Also, if a command bundle has been created and assigned to a policy rule, you cannot re-import the CSV (e.g. to update the list of commands) whilst it is assigned to a policy rule. You need to remove it from the policy rule, update the command bundle and then reassign. You could automate this using the actions in the Okta Privileged Access Workflows connector, but it has not been done in this exercise.

Policies and Rules

To test out the new command bundles, we created a new policy and set a group of Principals.

Within the policy, two rules were created, one for the user command bundle and one for the admin command bundle. As always, controls/conditionals are assigned based on risk (i.e. MFA and session recording for user commands, Access Request and session recording for admin commands).

Within each rule, the appropriate sudo command bundle was assigned.

The rules and policy were saved and the policy enabled.

The User Experience

When one of the Principals of the new policy attempts to connect to the server, the list of access methods includes the two sudo level individual account options corresponding to the new policy rules.

In this case the Linux admin selects the LDAP-admin-commands option. When they try to run one of the slap* commands without sudo they are denied. But with sudo they can run the command.

This concludes looking at how the import tool is used and what it produces.

The Import Mechanism

The import mechanism is built in Okta Workflows and leverages the Okta Privileged Access connector. It relies on a standard import file structure. These could be CSV files, but in this example the workflows have been built to consume Google Sheets documents on a Google Drive.

Import File Structure

The import file is structured as follows (the file shown deliberately has garbage data).

The columns are:

  • CommandType – one of executable (an executable with or without arguments), raw (complete command with executable plus a fixed set of arguments) or directory (execute any file in this directory). If any other values are used, the utility may break or produce unexpected results.
  • Command – the executable (for executable), executable+arguments (for raw) or directory (for directory). If it is a directory it must have the trailing slash.
  • ArgsType – for executables, one of custom (expecting a list of arguments), none (no arguments allowed) or any (any arguments are acceptable). If the CommandType is raw or directory, you don’t specify an ArgsType.
  • Args – the arguments to be passed to the executable. This is only valid for executables where the ArgsType is custom.
  • Notes – this is information to make managing the file easier, the values aren’t used in creating the command bundle in Okta Privileged Access

The column headings must be as shown above (no spaces).

Workflows

The import mechanism is implemented in Okta Workflows with a single table and four workflows.

Connectors

The flows below use two connections in addition to the normal workflows functions:

  • An Okta Privileged Access connector, and
  • A Google Drive connector (note that the two Google Drive cards are looking for a folder called sudo rules)

These must be configured before the workflows can run.

The Table

A Workflows table is used as a temporary storage location for the import file contents. This is because Workflows cannot process a CSV file directly – the CSV needs to be imported into a table and then each row can be processed.

The table headings are the same as the import file shown above: CommandType, Command, ArgsType, Args and Notes.

The table is wiped at the start of each import.

The Flows

There are four flows, the main flow and three helper flows.

Some of the flows include the new Okta Privileged Access Workflows connector. We will explore the main flow and the sub flow using this connector. The other two subflows (helper flows) are using fairly standard workflows cards to massage data and won’t be explored in detail.

The Main Flow

The main flow is set as a Delegated Flow so can be run by anyone authorised in the Okta Admin Console (they do not need to be Workflows administrators). You might have a group of Okta Privileged Access administrators who you also grant the relevant Okta admin rights to invoke this delegated flow.

The workflow has the following flow:

  1. Get the filename and description (optionally) from the requester, and if the filename is empty, abort the flow.
  2. If a description was not set, build one from the filename (replace -_ with spaces)
  3. Import the CSV file and store it in the Workflows table
  4. Get each command (table row) and format them into the body object needed for the API
  5. Check for an existing sudo command bundle and if found, delete it
  6. Use the API to create the new command bundle

The import step (3. above) looks like the following.

In this case we have built the import mechanism to import from a specific folder on a Google Drive (you could also import using other connectors like Excel Online). In this set of cards we search the specific folder for a file matching the filename and then use the File ID returned to Download the file into Okta Workflows. We then clear the temporary table and import the CSV file into the table (note that there’s no mapping, so the CSV headers must match the column names).

This results of this are shown in The Table section above.

The next section of the flow (4. above) will build the Body object that needs to be passed to the API to create the bundle.

The table of commands is read into a list and that list is transformed into an object to suit the API. An object is then built for the other arguments in the body. The resulting body looks like the following.

The last sections of the main flow (5. and 6. above) will use a helper flow to check for and delete any existing command bundle with the same name, then use the API to create the new bundle.

We are using the Okta Privileged Access Connector Custom API Action card with POST to create the new command bundle. There are no actions in the connector for the sudo command bundles, but you can access any API via the Custom API Action card without having to worry about authentication credentials (which you would if you just used the Workflows HTTP Connector).

The Relative URL for the API is /sudo_command_bundles. It is passing in the body as shown above to create the command bundle.

This concludes the main flow.

Note that at the time of writing this article, the API documentation for the sudo_command_bundles endpoint is not available.

Subflow To Check and Delete An Existing Command Bundle

The SUB – Find and Delete Existing Bundle helper flow also uses the Okta Privileged Access connector to run some API commands and is worth exploring. The role of this flow is to check if there is an existing command bundle of the same name and if so, delete it. This is because you cannot have two command bundles with the same name.

The first part of the flow will build a query parameter (count=200) and then use the Custom API Action to GET from /sudo_command_bundles. This means it will get up to 200 command bundles. It then extracts the list from the Body of the response.

Then there are some cards to find the current name in the existing list of command bundles and continue if one is found.

The last part of the flow will get the item found, extract the id of the bundle and use it to build the Relative URL for the API (/sudo_command_bundles/<id>). This is then used in a Custom API Action DELETE card to delete the existing bundle.

This concludes this subflow.

Running the Import Tool

Let’s now walk through the creation of the test sudo bundle shown above. As mentioned, the main flow begins with a Delegated Flow card. So an admin who has access goes to the Delegated flows menu item.

They can see the MAIN flow to import sudo commands, and click the Run button.

They enter a filename and optionally a description and click Run.

The flow will run in the background. To see the results, you can look at the Okta System Log.

In this case there is an event to show that the Delegated flow ran (with a SUCCESS status). After this there are two PAM events to show an older command bundle of the same name being deleted and the new one being created.

If we go to the new Sudo command bundle we see the name based on the filename and the description as entered.

The command bundle also shows the commands in that file, such as the following.

If these were real commands, the command bundle could be attached to a policy rule and tested.

Conclusion

This article has shown how we can implement a bulk import mechanism for Sudo command bundles in Okta Privileged Access using Okta Workflows and the new Okta Privileged Access Workflows connector. We have walked through an example of two sets of OpenLDAP commands and how the import mechanism is configured.

The article has highlighted the use of the Custom API Action card that comes with the connector and how it can be used to GET, POST and DELETE bundles with the /sudo_command_bundles API endpoint.

You could use this mechanism to build a library of command sets and import them into Okta Privileged Access as needed. This may be simpler than manually adding them to the Okta Privileged Access UI.

See also: