Automating Individual Secret Folders in OPA with Workflows

Okta Privileged Access has a secrets function, where a folder hierarchy can be built and policies applied to allow groups of users to access shared secrets. Whilst it’s not it’s primary use case, it could also be used to provide an individual secrets folder mechanism where users in Okta could have their own personal secrets folder.

This article explores how automation, with Okta Workflows, could be used to simplify creation of folders and associated policies for this.

For more information on secrets and the APIs you can see Using the Secrets API with Okta Privileged Access. However that article is focussed on accessing secrets with APIs, with a bit of info on Folder management, and nothing on the policies/rules invovled.

Introduction

One of the primary use cases for Okta Privileged Access (OPA) is secrets management, with credentials stored in the OPA vault. A hierarchy of secret folders can be defined, with policy applied at different levels of the folder tree to grant permissions to manage or access the secrets. For example, you might have departmental high-level folders with a small group of departmental admins managing them, but team-specific folders under that with a local administration group allowed to administer the folder and secrets, and a group of users who can access the secrets therein. You might have an IT department top-level folder managed by an IT dept admin group, then folders for DBA, Web, App Server etc. each with their own admins and users.

This approach is suitable for a structured organisation. But could it be applied to personal folders for personal secrets? Yes, but the challenge is the creation and maintenance of the individual folders, the individual (personal) groups to access them and the policies and rules to control access into the folders. This is where the OPA API comes in. You can automate the creation and destruction of these objects programmatically using the APi and some programming language.

In this article we walk through the creation of the various objects for personal folders using Okta Workflows. In the following example there is a main flow and a set of sub flows that will:

  1. Be passed an Okta username, validate that user in Okta, validate they are assigned to the Okta Privileged Access app in Okta (and if not, assign them), then validate the user is in OPA itself
  2. Create an OPA group for that user and assign the user to it in OPA
  3. Create a folder for that user under a common “individual folders” top-level folder in OPA
  4. Create a policy and rule that allows that OPA group to access that OPA folder with all folder/secret permissions

The details of each workflow will be described later. However many call the relevant OPA APIs directly with the Custom API Action card on the Okta Privileged Access connector in Workflows. This is because the connector does not have action cards for all of the admin API functions needed for this use case.

The Outcome

Lets start with the end result of the flow. It has been built to consume an Okta username. It was built that way to show the flow, but could be structured to consume a list of usernames (such as in a CSV file).

When the flow completes, the user will see the okta Privileged Access tile on their Dashboard (if they didn’t beforehand).

Selecting the tile, they are taken to the Okta Privileged Access UI with the functions that they can access. In this case they are not an administrator so they only see the MY PRIVILEGED ACCESS menu items. Under the Secrets menu item, they see a single folder named <username>-Folder (which is under the Individual_Secret_Folders top-level folder, but they can’t access that).

Within that folder, they can create (and manage) both folders and secrets.

They could create (and manage) their own folder hierarchy within their -Individual folder. They could also create (and manage) secrets anywhere in that hierarchy.

Once a secret is created, they can reveal the values at any time they want. In this case as they are personal secrets, the policy rule does not enforce MFA or access approval conditions on the reveal (you could build them into the workflow that defines the policy).

Thus the user has their own personal folder in the vault for storing their personal secrets. This was all done by one execution of a workflow.

The Workflows that Implement this Automation

This section will walk through the configuration of the solution.

Environment Setup

The following was configured in the environment for the workflows to function.

In Okta Workflows, both an Okta connector and an Okta Privileged Access connector were created to the local Okta/OPA.

In OPA, a new Resource Group and Project were created.

A top-level folder called “Individual-Secrets” was created in that Resource Group/Project.

Finally the Service User that the OPA connector uses was assigned to a group and that group assigned to a policy to allow the Workflows to create folders in that top-level folder AND be able to create policies and rules. In this case there is a policy assigned to the Individual-Secrets folder that allows the folder permissions on that folder and any sub-folders, but not the ability to manage or reveal secrets.

This implies that this user could manage folders within the individual folders the workflow will create. You could apply a deny-type policy rule for this workflows service user once you created the folder and policy, but then workflows could not clean up after the user no longer needs a personal folder. Of course a super administrator can change the policies. You should focus on policy design if implementing a mechanism like this. It can’t be bulletproof as you still need superadmins, but you could wrap other controls around the use of superadmin accounts.

Overview of the Flows

There are five flows in the solution, a main flow and four subflows called from the main flow.

Lets walk through them. Note that the flows do not contain a lot of fault handling – consider them proofs-of-concept and you would need to make them more resilient in production.

M00 – The Main Flow

The main flow (M00 – Create Individual Folder) is the high-level flow that prompts for an Okta username.

It will setup some fixed arguments for the top-level folder (RG ID, Project ID and Folder ID) and the OPA application ID (in Okta). All of these could be dynamically discovered using APIs and actions in Workflows, but this shortcut was chosen. These values do not change across executions of the workflow (all individual folders would be stored in the one top-level folder).

Next it checks that the user is a valid Okta user, returning some user profile attributes like first and last names.

It calls a subflow (M10) to verify that the user is assigned to the OPA app in Okta and if not, it assigns them.

The next card (Compose) builds the OPA username from the firstname and lastname. Again this could be done programmatically by looking at the user app profile for that user on the OPA app, but we are simplifying for this example. The default configuration of OPA has a firstname.lastname format.

The username is converted to lowercase as most of the OPA APIs are case-sensitive and usernames in OPA are lowercase.

The OPA Connector Find Users action is used to verify that this user is in OPA. It will return the number of found users. In this case it will only continue the flow if exactly one user is found.

The rest of the flow calls subflows to create an OPA group for that user (M20), create a folder for that user (M30) and create a policy to allow the user to manage their folder and secrets (M40).

The M20 and M30 flows return the Group and Folder IDs that are used in the M40 flow.

M10 – To Check the Okta User

This flow is passed the Okta user ID and OPA app ID from the main flow. It will try (inside a try/if error function) to find the user in the app using the Okta Get Assigned User for Application card.

If the call fails, it checks if it’s a 404 and if so assigns the user to the app using an Okta Assign User to Application for SSO And Provisioning card.

It has a 30 second delay built in to allow the provisioning of the new user from Okta to OPA.

M20 – To Create an Individual Group in OPA

The M20 flow has two parts. The first part will define a group name (<username>-Individual) and then use the Create a Group API to create it in OPA.

The second part uses the Add a User to a Group API to assign the user. Note that this API requires the OPA username NOT the ID.

It returns the ID of the new group to the calling flow.

M30 – To Create an Individual Folder in OPA

This flow creates an individual folder in the top-level folder. It is passed the IDs of the resource group, project and top-level folder as well as the username.

Three compose cards build: The foldername (<username>-Folder), a description for the folder and the URL for the API.

Then it uses the Create a Secret Folder API to create the folder in OPA.

It returns the ID of the new folder to the calling flow.

M40 – To Create a Policy with Rule for the Folder and Group

This last flow will run a single API, the Create a Security Policy API, to create the policy with rule and assign it to both the user group and the folder. Note that the product docs do not currently contain an example of creating a policy w/rule for a secret folder.

This API requires a fairly complex Body object to be passed to it. like the following:

{
  "rules": [
    {
      "privileges": [
        {
          "privilege_type": "secret",
          "privilege_value": {
            "secret_create": true,
            "_type": "secret",
            "secret_update": true,
            "folder_delete": true,
            "secret_delete": true,
            "folder_update": true,
            "secret_reveal": true,
            "folder_create": true,
            "list": true
          }
        }
      ],
      "resource_type": "secret_based_resource",
      "resource_selector": {
        "selectors": [
          {
            "selector_type": "secret_folder",
            "selector": {
              "secret_folder": {
                "id": "4693e3b6-913f-4ffd-93eb-67d5da04073c",
                "type": "secret_folder"
              },
              "_type": "secret_folder"
            }
          }
        ],
        "_type": "secret_based_resource"
      },
      "name": "Owner Folder Management"
    }
  ],
  "name": "nigel.newbie-Policy",
  "active": true,
  "principals": {
    "user_groups": [
      {
        "id": "d24608d0-988a-44be-8100-b0c31ad64c98"
      }
    ]
  },
  "description": "Policy to allow nigel.newbie full rights to their own secrets folder."
}

It has a name and description, and a state of “active” (i.e. the policy will be enabled when created). It has two other top-level components:

  • principals – defining the id of the user group (i.e. the individual group created in M20).
  • rules – defining a single rule to allow all secret/folder permissions against the users folder (i.e. the individual folder created in M30).

The flow comprises a series of Object Construct and List Construct cards to build up the privileges, rules and principals object in the complex structure required of the API.

With the Body object main components built, it then defines a policy name and description, and wraps all of the fields into the Body object. It then calls the API to create the policy with rule.

It does not return anything to the calling flow. If the API fails, the flow and calling flow will show the API error.

This concludes the flows used to build this solution.

Conclusion

This article has provided an example of how Okta Workflows and the OPA APIs can be used to create a personal secrets folder for a user and the groups and policy to control access to that folder. It shows both the APIs to achieve this as well as how they could be structured into a flow with Workflows.

This addresses the requirement for providing personal secrets management within the Okta Privileged Access vault, and alleviating the manual work required if this was to be done in the Okta Privileged Access UI.

Leave a Reply