Installing Policy Workbench on PPC in Azure Kubernetes Service (AKS)

Steps to install Policy Workbench on PPC in AKS.

Before installing Policy Workbench, ensure that the prerequisites are met. For more information about the prerequisites, refer to the section Prerequisites.

To install Policy Workbench on PPC in AKS, first provision the Azure resources using the policy-workbench OpenTofu module and then deploy the Policy Workbench using Helm. The policy-workbench OpenTofu module is published to OCI and must be consumed from a root module. A root module is the working directory for executing the OpenTofu commands.

For more information about OpenTofu modules and the root module, refer to the section Modules in the OpenTofu documentation.

The Policy Workbench is installed depending on one of the following scenarios:

  • Root module is not available.
  • Root module is available.

Prerequisites

Ensure that the jumpbox can connect to the required registries. If not already authenticated, then log in to the required registry.

  • For connecting and deploying from the Protegrity Container Registry (PCR), use the following command and the credentials obtained from the My.Protegrity portal during account creation:
helm registry login registry.protegrity.com:9443
  • For connecting and deploying to the local registry, use your local credentials and local registry endpoint as required.

Ensure that the PPC Cluster is installed and accessible, before installing Policy Workbench on PPC.

For more information about installing PPC, refer to the section Installing PPC.

Required Tools

Ensure that the following tools are available on the jump box on which Policy Workbench is installed.

ToolVersionDescription
OpenTofu>=1.10.0Used to run the installer.
Azure CLIAny versionMust be logged in (az login) with permissions to create Managed Identities and assign Key Vault or Managed HSM roles.
kubectlAny versionRequired for validating the deployment. It must be configured for the target PPC cluster where Policy Workbench is deployed.

Azure Permissions

The following Azure permissions are automatically created by the OpenTofu script.

PermissionPurpose
Microsoft.ManagedIdentity/userAssignedIdentities/writeCreate the managed identity.
Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials/writeCreate the federated identity credential.
Microsoft.KeyVault/vaults/readRead the key vault properties.
Microsoft.Authorization/roleAssignments/writeAssign the Key Vault Crypto Officer role on the key vault.
Microsoft.KeyVault/managedHSMs/readRead the managed HSM properties.
HSM local RBAC: Microsoft.KeyVault/managedHsm/roleAssignments/writeAssign the Crypto User role on the HSM.

Configuring Credentials for the Policy Workbench

Perform the following steps to configure the credentials to access the Policy Workbench from the OCI registry.

  1. Run the following command to create the configuration directory.

    mkdir -p ~/.config/containers
    
  2. Obtain the username and access token from the My.Protegrity portal. For more information about obtaining the credentials from the My.Protegrity portal, refer to the section Configuring Authentication for Protegrity AI Team Edition.

  3. Generate base64 encoded string with padding for username:accesstoken obtained from the My.Protegrity portal.

    Ensure that you specify the username and access token within single quotes when generating the base64 encoded value. For example, 'username:accesstoken'.

  4. Create a file named ~/.config/containers/auth.json with the following content.

    {
        "auths": {
                "registry.protegrity.com:9443": {
                        "auth": "<base64 generated string from step-3>"
                }
        }
}

Installing Policy Workbench when root module is not available

Install the Policy Workbench using the following commands:

  1. Run the following command to create the deployment directory.
# must install from an empty directory
mkdir policy-workbench && cd policy-workbench
  1. Create a root module with a single main.tf file.
terraform {
  required_version = "~> 1.10"

  required_providers {
    azurerm = {
      source  = "registry.opentofu.org/hashicorp/azurerm"
      version = "~> 4.20"
    }
    kubernetes = {
      source  = "registry.opentofu.org/hashicorp/kubernetes"
      version = "~> 2.35"
    }
  }
}

provider "azurerm" {
  features {}
  resource_provider_registrations = "none"
}

data "azurerm_kubernetes_cluster" "this" {
  name                = var.cluster_name
  resource_group_name = var.resource_group_name
}

provider "kubernetes" {
  host                   = data.azurerm_kubernetes_cluster.this.kube_config[0].host
  client_certificate     = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_certificate)
  client_key             = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_key)
  cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].cluster_ca_certificate)
}

module "policy_workbench" {
  source = "oci://<Container_Registry_Path>/policy-workbench/opentofu/modules/policy-workbench/azure?tag=<version>"

  cluster_name                    = var.cluster_name
  oci_host                        = "<Container_Registry_Hostname>"
  resource_group_name             = var.resource_group_name

  azure_keystore = {
    type                = "key_vault"
    name                = var.key_vault_name
    resource_group_name = var.key_vault_resource_group_name
  }

  fips                            = var.fips
  instance_types                  = var.instance_types
}

variable "cluster_name"                    { type = string }
variable "resource_group_name"             { type = string }
variable "key_vault_name"                  { type = string }

variable "key_vault_resource_group_name" {
  type    = string
  default = ""
}

variable "fips" {
  type        = bool
  description = "Use FIPS-enabled nodes for Karpenter. Set to false for non-FIPS."
  default     = true
}

variable "instance_types" {
  type    = list(string)
  default = ["Standard_D8as_v5"]
}

output "helm_install" {
  value = module.policy_workbench.helm_install
}

To use an existing Managed HSM instead of a Standard or Premium Key Vault, replace the keystore block in the main.tf file with the following code block:

azure_keystore = {
  type                = "managed_hsm"
  name                = "<managed-hsm-name>"
  resource_group_name = "<hsm-resource-group>" # omit if same as resource_group_name
}

In the main.tf file, specify the values of the following parameters.

Parameter NameDescriptionValue
<Container_Registry_Path>Location of the Protegrity Container Registry or the local registry where the policy-workbench OpenTofu module is published.
  • registry.protegrity.com:9443 if Protegrity Container Registry is used.
  • Local registry endpoint if a local registry is used.
<Container_Registry_Hostname>OCI registry hostname used for oci_host.registry.protegrity.com
<version>Tag version of the Protegrity Policy Manager, as specified in the product part number. Obtain the product part number from the Policy Manager Readme.1.12.0
azure_keystore.typeType of keystore used.Specify one of the following values:
  • key_vault - Use Standard or Premium Azure Key Vault. Protegrity supports 3072-bit RSA software-backed Master Key type. The Master Key uses the RSA-OAEP-256 algorithm to encrypt the Data Encryption Key (DEK).
  • managed_hsm - Use Azure Key Vault Managed HSM. Protegrity supports 256-bit AES oct-HSM HSM-backed Master Key type. The Master Key uses the AES-256-CBC algorithm to encrypt the Data Encryption Key (DEK).

For more information about the Azure Key Vault, refer to the section About Azure Key Vault in the Azure documentation.
For more information about the Azure Key Vault Managed HSM, refer to the section What is Azure Key Vault Managed HSM? in the Azure documentation.
Note: Protegrity supports only software-protected keys for the Premium Key Vault. Protegrity does not support HSM-protected keys for the Premium Vault.
For more information about software-protected and HSM-protected keys, refer to the Azure documentation.
Important: You cannot migrate among the Standard Key Vault, Premium Key Vault, and Managed HSM.
azure_keystore.nameName of the existing Standard or Premium Key Vault or Managed HSM.Specify one of the following values:
  • var.key_vault_name - Specify this variable if a Standard or Premium Key Vault is used. Set the value of this variable when running the tofu apply command in step 4 of this section.
  • Name of the existing Managed HSM.
azure_keystore.resource_group_nameResource group of the Standard or Premium Key Vault or Managed HSM.Specify one of the following values:
  • var.key_vault_resource_group_name - Specify this value only if a Standard or Premium Key Vault is used. Set the value of this variable when running the tofu apply command in step 4 of this section.
  • Name of the resources group for the existing Managed HSM. Specify this parameter only if the name of the resource group for the Managed HSM differs from the value of the resource_group_name variable.
  1. Ensure that the credentials to install the Policy Workbench from the Protegrity Container Registry have been configured.

    For more information about configuring the credentials, refer to the section Configuring Credentials for the Policy Workbench.

  2. Run the following command to plan and install the Policy Workbench OpenTofu module.

# init, plan, and install
tofu init
tofu plan \
  -var="cluster_name=<PPC-cluster-name>" \
  -var="resource_group_name=<aks-resource-group-name>" \
  -var="key_vault_name=<key-vault-name>"
tofu apply \
  -var="cluster_name=<PPC-cluster-name>" \
  -var="resource_group_name=<aks-resource-group-name>" \
  -var="key_vault_name=<key-vault-name>"

If the Key Vault is in a different resource group, include the following variable:

-var="key_vault_resource_group_name=<key-vault-resource-group-name>"

To override the default Karpenter instance type, include the following variable:

-var='instance_types=["<Instance_type>"]'

To override the default FIPS-enabled mode, include the following variable:

-var='fips=["false"]'

In the command, specify the values of the following variables.

Variable NameDescriptionValueRequired
cluster_nameName of the PPC cluster that you have specified in step 1 while deploying the PPC in AKS.
For more information about deploying the PPC, refer to the section Deploying PPC.
Required
resource_group_nameResource group for the managed identity.Required
key_vault_nameName of the Standard or Premium Key Vault.Required
fipsUse FIPS-enabled nodes for Karpenter.The default value is set to true. Set to false for non-FIPS.Not required
instance_typesVM instance types for the Karpenter NodePool. Must be allowed by Azure Policy.The default value is ["Standard_D8as_v5"]. Specify another value to override the default value.Not required
key_vault_resource_group_nameResource group of the Standard or Premium Key Vault.The default value is the same as the value of the resource_group_name parameter. Specify this value only if the resource group of the Key Vault is different from the value of the resource_group_name parameter.Not required

OpenTofu prints the plan and prompts for confirmation. Enter yes to proceed. To skip the prompt, add the -auto-approve option to the commands.

  1. Run the following command to complete the installation of the Policy Workbench using Helm.
helm upgrade --install policy-workbench \
  oci://<Container_Registry_Path>/policy-workbench/helm/policy-workbench \
  --version <version> \
  --namespace policy-workbench \
  --create-namespace \
  --values policy-workbench-values.yaml

In the command, specify the values of the following variables.

Variable NameDescriptionValue
<Container_Registry_Path>Location of the Protegrity Container Registry or the local registry where the policy-workbench OpenTofu module is published.
  • registry.protegrity.com:9443 if Protegrity Container Registry is used.
  • Local registry endpoint if a local registry is used.
<version>Tag version of the Protegrity Policy Manager, as specified in the product part number. Obtain the product part number from the Policy Manager Readme.1.12.0

The OpenTofu module writes a policy-workbench-values.yaml file in your working directory with cloud-specific keystore settings. Pass it to Helm with the --values parameter.

Note: The tofu output -raw helm_install command prints a ready-to-run Helm command with the correct version and namespace values already filled in.

  1. Run the following command to view the pods created in the policy-workbench namespace.
kubectl get pods -n policy-workbench

Installing Policy Workbench when root module is available

Install the Policy Workbench using the following commands:

  1. Add the policy-workbench OpenTofu module by adding the following code block to an existing root module.
module "policy_workbench" {
  source = "oci://<Container_Registry_Path>/policy-workbench/opentofu/modules/policy-workbench/azure?tag=<version>"

  cluster_name                    = "<PPC-cluster-name>"
  oci_host                        = "<Container_Registry_Hostname>"
  resource_group_name             = "<resource-group>"

  azure_keystore = {
    type                = "key_vault"
    name                = "<key-vault-name>"
    resource_group_name = "<key-vault-resource-group>" # omit if same as resource_group_name
  }

  # fips     = true                  # set to false for non-FIPS nodes
  # instance_types = ["Standard_D8as_v5"]
}

To use an existing Managed HSM instead of a Standard or Premium Key Vault, replace the keystore block in the main.tf file with the following code block:

azure_keystore = {
  type                = "managed_hsm"
  name                = "<managed-hsm-name>"
  resource_group_name = "<hsm-resource-group>" # omit if same as resource_group_name
}

For more information about adding a module to an existing root module, refer to the section Module Blocks in the OpenTofu documentation.

In the main.tf file, specify the values of the following parameters.

Parameter NameDescriptionValue
<Container_Registry_Path>Location of the Protegrity Container Registry or the local registry where the policy-workbench OpenTofu module is published.
  • registry.protegrity.com:9443 if Protegrity Container Registry is used.
  • Local registry endpoint if a local registry is used.
<Container_Registry_Hostname>OCI registry hostname used for oci_host.registry.protegrity.com
<version>Tag version of the Protegrity Policy Manager, as specified in the product part number. Obtain the product part number from the Policy Manager Readme.1.12.0
azure_keystore.typeType of keystore used.Specify one of the following values:
  • key_vault - Use Standard or Premium Azure Key Vault. Protegrity supports 3072-bit RSA software-backed Master Key type. The Master Key uses the RSA-OAEP-256 algorithm to encrypt the Data Encryption Key (DEK).
  • managed_hsm - Use Azure Key Vault Managed HSM. Protegrity supports 256-bit AES oct-HSM HSM-backed Master Key type. The Master Key uses the AES-256-CBC algorithm to encrypt the Data Encryption Key (DEK).

For more information about the Azure Key Vault, refer to the section About Azure Key Vault in the Azure documentation.
For more information about the Azure Key Vault Managed HSM, refer to the section What is Azure Key Vault Managed HSM? in the Azure documentation.
Note: Protegrity supports only software-protected keys for the Premium Key Vault. Protegrity does not support HSM-protected keys for the Premium Vault.
For more information about software-protected and HSM-protected keys, refer to the Azure documentation.
Important: You cannot migrate among the Standard Key Vault, Premium Key Vault, and Managed HSM.
azure_keystore.nameName of the existing Standard or Premium Key Vault or Managed HSM.Specify one of the following values:
  • var.key_vault_name - Specify this variable if a Standard or Premium Key Vault is used. Set the value of this variable when running the tofu apply command in step 4 of this section.
  • Name of the existing Managed HSM.
azure_keystore.resource_group_nameResource group of the Standard or Premium Key Vault or Managed HSM.Specify one of the following values:
  • var.key_vault_resource_group_name - Specify this value only if a Standard or Premium Key Vault is used. Set the value of this variable when running the tofu apply command in step 4 of this section.
  • Name of the resources group for the existing Managed HSM. Specify this parameter only if the name of the resource group for the Managed HSM differs from the value of the resource_group_name variable.
  1. If the root module does not include the hashicorp/azurerm provider version >= 4.20 and hashicorp/kubernetes provider version >= 2.35, then add the following code block to the terraform {} block. Else navigate to the next step.
required_providers {
  azurerm = {
    source  = "registry.opentofu.org/hashicorp/azurerm"
    version = ">= 4.20"
  }
  kubernetes = {
    source  = "registry.opentofu.org/hashicorp/kubernetes"
    version = ">= 2.35"
  }
}
  1. If the root module does not configure the Azure provider with resource_provider_registrations = "none", add the following code block to avoid requiring subscription-level registration permissions.
provider "azurerm" {
  features {}
  resource_provider_registrations = "none"
}
  1. If the root module does not configure the Kubernetes provider for the target AKS cluster, add the following code block.
data "azurerm_kubernetes_cluster" "this" {
  name                = "<PPC-cluster-name>"
  resource_group_name = "<aks-resource-group-name>"
}

provider "kubernetes" {
  host                   = data.azurerm_kubernetes_cluster.this.kube_config[0].host
  client_certificate     = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_certificate)
  client_key             = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_key)
  cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].cluster_ca_certificate)
}
  1. Ensure that the credentials to install the Policy Workbench from the Protegrity Container Registry have been configured.

    For more information about configuring the credentials, refer to the section Configuring Credentials for the Policy Workbench.

  2. Navigate to the directory containing the root module.

  3. Run the following commands to plan and install the Policy Workbench OpenTofu module.

# init, plan, and install
tofu init
tofu plan \
  -var="cluster_name=<PPC-cluster-name>" \
  -var="resource_group_name=<aks-resource-group-name>" \
  -var="key_vault_name=<key-vault-name>"
tofu apply \
  -var="cluster_name=<PPC-cluster-name>" \
  -var="resource_group_name=<aks-resource-group-name>" \
  -var="key_vault_name=<key-vault-name>"

If the Key Vault is in a different resource group, include the following variable:

-var="key_vault_resource_group_name=<key-vault-resource-group-name>"

To override the default Karpenter instance type, include the following variable:

-var='instance_types=["<Instance_type>"]'

To override the default FIPS-enabled mode, include the following variable:

-var='fips=["false"]'

In the command, specify the values of the following variables.

Variable NameDescriptionValueRequired
cluster_nameName of the PPC cluster that you have specified in step 1 while deploying the PPC in AKS.
For more information about deploying the PPC, refer to the section Deploying PPC.
Required
resource_group_nameResource group for the managed identity.Required
key_vault_nameName of the Standard or Premium Key Vault.Required
fipsUse FIPS-enabled nodes for Karpenter.The default value is set to true. Set to false for non-FIPS.Not required
instance_typesVM instance types for the Karpenter NodePool. Must be allowed by Azure Policy.The default value is ["Standard_D8as_v5"]. Specify another value to override the default value.Not required
key_vault_resource_group_nameResource group of the Standard or Premium Key Vault.The default value is the same as the value of the resource_group_name parameter. Specify this value only if the resource group of the Key Vault is different from the value of the resource_group_name parameter.Not required

OpenTofu prints the plan and prompts for confirmation. Enter yes to proceed. To skip the prompt, add the -auto-approve option to the commands.

In the cluster_name field, specify the name of the PPC cluster that you have specified in step 1 while deploying the PPC.

For more information about deploying the PPC, refer to the section Deploying PPC.

  1. Run the following command to complete the installation of the Policy Workbench using Helm.
helm upgrade --install policy-workbench \
  oci://<Container_Registry_Path>/policy-workbench/helm/policy-workbench \
  --version <version> \
  --namespace policy-workbench \
  --create-namespace \
  --values policy-workbench-values.yaml

In the command, specify the values of the following variables.

Variable NameDescriptionValue
<Container_Registry_Path>Location of the Protegrity Container Registry or the local registry where the policy-workbench OpenTofu module is published.
  • registry.protegrity.com:9443 if Protegrity Container Registry is used.
  • Local registry endpoint if a local registry is used.
<version>Tag version of the Protegrity Policy Manager, as specified in the product part number. Obtain the product part number from the Policy Manager Readme.1.12.0

The OpenTofu module writes a policy-workbench-values.yaml file in your working directory with cloud-specific keystore settings. Pass it to Helm with the --values parameter.

Note: The tofu output -raw helm_install command prints a ready-to-run Helm command with the correct version and namespace values already filled in.

  1. Run the following command to view the pods created in the policy-workbench namespace.
kubectl get pods -n policy-workbench

Validating the deployment

Note: Before validating the deployment of the Policy Workbench, ensure that the kubectl context is set to the target PPC cluster. Run kubectl config current-context to verify the current context. Run kubectl config use-context <context-name> to switch the context.

After installation, validate the Policy Workbench deployment using the following steps. The desired outcome of these steps is to get a [] response from the datastores API call using a dedicated workbench user.

  1. Run the following commands to retrieve the gateway host details and generate an admin JWT token.
export GW_HOST="$(kubectl get gateway pty-main -n api-gateway -o jsonpath='{.status.addresses[0].value}')"

TOKEN=$(curl -k -s https://$GW_HOST/pty/v1/auth/login/token \
  -X POST \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'loginname=admin' \
  -d 'password=Protegrity123!' \
-D - -o /dev/null 2>&1 | grep -i 'pty_access_jwt_token:' | sed 's/pty_access_jwt_token: //' | tr -d '\r') && echo "${TOKEN:0:10}"
  1. Create a workbench user using the following command. Due to separation of duties, the datastores API requires a user with workbench roles.
curl -sk -X POST "https://$GW_HOST/pty/v1/auth/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "workbench",
    "password": "<Password>",
    "roles": [
      "workbench_administrator",
      "security_administrator"
    ]
  }'

Note: The password policy requires a minimum of 14 characters, including at least one digit, one uppercase letter, one lowercase letter, and one special character.

  1. Run the following command to get a token for the workbench user.
export TOKEN=$(curl -k -s https://$GW_HOST/pty/v1/auth/login/token \
  -X POST \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'loginname=workbench' \
  -d 'password=<Password>' \
-D - -o /dev/null 2>&1 | grep -i 'pty_access_jwt_token:' | sed 's/pty_access_jwt_token: //' | tr -d '\r')
  1. Run the Policy Management REST API to get datastores.
curl -k -v https://$GW_HOST/pty/v2/pim/datastores \
  -H "Authorization: Bearer $TOKEN"

The expected output is []. This indicates that the Policy Workbench is initialized but the datastore is not yet created.

For more information about the workbench_administrator permissions, refer to the section Workbench Roles and Permissions.

Post-Installation steps

After installing PPW, rotate the certificates to ensure that the certificates on the PPW and PPC are sychronized.

Perform the following steps to rotate the certificates.

  1. Run the following command to rotate all the certificates.
# Renew all certificates using eclipse-issuer
kubectl get certificates --all-namespaces -o json | \
jq -r '.items[] | select(.spec.issuerRef.name=="eclipse-issuer") | "\(.metadata.namespace) \(.metadata.name)"' | \
while read -r ns cert_name; do
  echo "Renewing certificate: $cert_name in namespace: $ns"
  cmctl renew "$cert_name" -n "$ns"
done
  1. Run the following command to verify that the certificates have been rotated.
kubectl get certificates --all-namespaces

The following output appears.

NAMESPACE          NAME                           READY   SECRET                                AGE
api-gateway        ingress-certificate-secret     True    ingress-certificate-secret            5h46m
cert-manager       eclipse-ca                     True    eclipse-ca                            5h46m
policy-workbench   bootstrap-certificate          True    bootstrap-certificate-secret          17m
policy-workbench   cert-certificate               True    cert-certificate-secret               17m
policy-workbench   devops-certificate             True    devops-certificate-secret             17m
policy-workbench   hubcontroller-certificate      True    hubcontroller-certificate-secret      17m
policy-workbench   kmgw-certificate               True    kmgw-certificate-secret               17m
policy-workbench   mbs-certificate                True    mbs-certificate-secret                17m
policy-workbench   protector-certificate          True    protector-certificate-secret          17m
policy-workbench   pty-main-backend-client-cert   True    pty-main-backend-client-certificate   17m
policy-workbench   repository-certificate         True    repository-certificate-secret         17m
policy-workbench   rpproxy-certificate            True    rpproxy-certificate-secret            17m
policy-workbench   rps-certificate                True    rps-certificate-secret                17m
pty-insight        hubcontoller-client-secret     True    hubcontoller-client-secret            5h46m
pty-insight        tls-for-insight                True    tls-for-insight-key-pair              5h46m
pty-loginui        ingress-certificate-secret     True    ingress-certificate-secret            5h46m

The Ready column displays the value True for all the certificates indicating that they have been rotated.


Last modified : July 29, 2026