---
title: "Workflows"
description: "Contains the different workflows of nctl and npm"
diataxis: how-to
applies_to:
  product: "nirmata-control-hub"
audience: ["platform-engineer","cluster-admin"]
last_updated: 2026-04-16
url: https://docs.nirmata.io/docs/control-hub/how-to/
---


This section contains information about the different workflows for NCTL and Nirmata Control Hub.

---

## Onboard a Cluster in Nirmata Control Hub




## Prerequisites


- [Helm](https://helm.sh/docs/intro/install/) installed on your machine
- `kubectl` access to the target cluster
- A Nirmata account (Create a trial account at [try.nirmata.io](https://try.nirmata.io/))

## Obtaining Your API Token

To get your API token for cluster onboarding:

1. Log in to your Nirmata Control Hub account
2. Navigate to the Settings section in the left toolbar
3. Expand the Settings tab and click on Profile
4. In the Profile view, locate the "Generate API Key" button in the top right corner
5. Click the button and follow the instructions to create your API key
6. Copy and securely store your API key - you'll need it during the cluster installation process

## Installation Steps

#### 1. Add Nirmata Helm Repository

First, add the Nirmata Helm repository to your local Helm configuration:

```bash
helm repo add nirmata https://nirmata.github.io/kyverno-charts/
helm repo update nirmata
```text

#### 2. Install Nirmata Enterprise for Kyverno


```bash
helm install kyverno nirmata/kyverno \
  -n kyverno \
  --create-namespace \
  --set features.policyExceptions.namespace="kyverno" \
  --set features.policyExceptions.enabled=true \
  --set admissionController.replicas=3 \
  --version 3.3.9
```text

#### 3. Install Kyverno Operator


```bash
helm install kyverno-operator nirmata/nirmata-kyverno-operator \
  -n nirmata-system \
  --create-namespace \
  --devel \
  --set enablePolicyset=true \
  --version v0.7.0
```text

#### 4. Install Nirmata Kube Controller

Install the Nirmata Kube Controller with your specific configuration:

```bash
helm install nirmata-kube-controller nirmata/nirmata-kube-controller \
  -n nirmata \
  --create-namespace \
  --set nirmataURL=wss://nirmata.io/tunnels \
  --set cluster.name=<your-cluster-name> \
  --set namespace=nirmata \
  --set apiToken=<your-api-token> \
  --set features.policyExceptions.enabled=true \
  --set features.policySets.enabled=true \
  --version=0.2.8
```text

Replace `<your-cluster-name>` with your desired cluster name and `<your-api-token>` with your Nirmata API token.

#### 5. Verify Installation

1. Log in to your Nirmata Control Hub account
2. Navigate to the Clusters view
3. Verify that your cluster appears in the list and shows as connected

#### Deploy the Pod Security policies from the [Nirmata policy repository](https://github.com/nirmata/kyverno-policies/tree/main/pod-security) using Nirmata Policy Set or any other preferred deployment method. Nirmata will surface violations, guide remediation, and integrate with workflows to streamline policy enforcement at scale.

## Cleanup

If you need to remove the cluster from Nirmata Control Hub, follow these steps:

1. Uninstall the Helm releases:
```bash
helm uninstall nirmata-kube-controller -n nirmata
helm uninstall kyverno -n kyverno
helm uninstall kyverno-operator -n nirmata-system
```text

2. Delete the namespaces:
```bash
kubectl delete ns kyverno
kubectl delete ns nirmata-system
kubectl delete ns nirmata
```

3. Remove the cluster from Nirmata Console:

   - Log in to Nirmata Control Hub
   - Navigate to the Clusters view
   - Click on the cluster you want to remove
   - Click the "Remove" button to remove it from the Nirmata Console

## Troubleshooting

If you encounter any issues during the installation:

1. Verify that all prerequisites are met
2. Check that your API token is valid
3. Ensure your cluster has sufficient resources
4. Verify network connectivity to Nirmata services

For additional support, please contact Nirmata support or visit our [documentation portal](https://docs.nirmata.io).


---

## Onboarding Cluster with Custom CA Certs in Nirmata Control Hub



## Custom Kyverno Configuration for Custom Kubernetes Certificates

This guide walks you through onboarding a cluster in **Nirmata Control Hub** with **Kyverno configured to use custom Kubernetes certificates**, particularly those signed by your internal Certificate Authority (CA).

### 1. Generate or Use CA-Signed Certificates

If using your organization's internal CA, generate/provide certs for `kyverno-svc.kyverno.svc` and `kyverno-cleanup-controller.kyverno.svc`. **Must be CA-signed, not self-signed.**

#### Wildcard Certificates

For wildcard certs (e.g., `*.rancher.test or *.test.aws`), SANs must include `kyverno-svc.kyverno.svc` and `kyverno-cleanup-controller.kyverno.svc`.

### 2. Verify Subject Alternative Names (SANs)

Ensure certs include these SANs **before creating secrets**:

#### For `kyverno-svc`:

- `kyverno-svc`
- `kyverno-svc.kyverno`
- `kyverno-svc.kyverno.svc`

#### For `kyverno-cleanup-controller`:

- `kyverno-cleanup-controller`
- `kyverno-cleanup-controller.kyverno`
- `kyverno-cleanup-controller.kyverno.svc`

Inspect SANs with [Step CLI](https://smallstep.com/docs/step-cli): `step certificate inspect your-admission-cert.crt --short`

### 3. Create Kubernetes Secrets for Kyverno

Create secrets in the `kyverno` namespace (replace `<namespace>`).

####  Admission Controller Secrets

```bash
kubectl create secret tls kyverno-svc.kyverno.svc.kyverno-tls-pair --cert=your-admission-cert.crt --key=your-admission-key.key -n <namespace>
kubectl create secret generic kyverno-svc.kyverno.svc.kyverno-tls-ca --from-file=rootCA.crt=your-ca.crt -n <namespace> 
```text


#### Cleanup Controller Secrets

```bash

kubectl create secret tls kyverno-cleanup-controller.kyverno.svc.kyverno-tls-pair --cert=your-cleanup-cert.crt --key=your-cleanup-key.key -n <namespace>
kubectl create secret generic kyverno-cleanup-controller.kyverno.svc.kyverno-tls-ca --from-file=rootCA.crt=your-ca.crt -n <namespace> 

```


####  Important: Do not rename these secrets.


## Nirmata Enterprise for Kyverno and Operator Installation Guide

Version Details: Nirmata Enterprise for Kyverno: v1.13.4-n4k.nirmata.2 | Nirmata Enterprise for Kyverno Helm Chart: v3.3.9 | Kyverno Operator Helm Chart: v0.5.8

### 1. Overview 

Install Nirmata Enterprise for Kyverno and the Kyverno Operator using Helm. This guide also provides a complete container image list for deployments in air-gapped or private registry environments.

### 2. Install Nirmata Enterprise for Kyverno (Kyverno)

```bash
helm repo add nirmata https://nirmata.github.io/kyverno-charts/
helm repo update nirmata
```

```bash 
helm install kyverno nirmata/kyverno -n kyverno --create-namespace --set features.policyExceptions.namespace="kyverno" --set features.policyExceptions.enabled=true --set admissionController.replicas=3 --version 3.3.9
```

### 3. Install Kyverno Operator

```bash

helm install kyverno-operator nirmata/nirmata-kyverno-operator -n nirmata-system --create-namespace --devel --set enablePolicyset=true --version v0.5.8 --set "policies.policySets=[]" 
```text

### 4. Uninstall & Cleanup

```bash

helm uninstall kyverno -n kyverno
helm uninstall kyverno-operator -n nirmata-system
kubectl delete ns kyverno
kubectl delete ns nirmata-system
```

Remove any persistent CRDs or leftover Kyverno resources if needed.

### 5. Container Image List (For Private Registry Usage)
Ensure these images are in your private registry:

Nirmata Enterprise for Kyverno Images:

```bash 
 reg.nirmata.io/nirmata/kyverno:v1.13.4-n4k.nirmata.2
 reg.nirmata.io/nirmata/kyvernopre:v1.13.4-n4k.nirmata.2
 reg.nirmata.io/nirmata/background-controller:v1.13.4-n4k.nirmata.2
 reg.nirmata.io/nirmata/cleanup-controller:v1.13.4-n4k.nirmata.2
 reg.nirmata.io/nirmata/reports-controller:v1.13.4-n4k.nirmata.2
```

Kyverno Operator Images: 
```bash 
ghcr.io/nirmata/nirmata-kyverno-operator:v0.4.5
```

Nirmata Kube-controller Images: 

```bash 
ghcr.io/nirmata/nirmata-kube-controller:v3.10.5   ghcr.io/nirmata/opentelemetry-collector:0.92.0
```

✅ Tip: Ensure all required images are in the private registry for air-gapped environments.


---

## Image Verification using Nirmata



## Table of Contents
1. [Steps for Image Verification](#steps-for-image-verification)
2. [Prerequisites](#prerequisites)
3. [Sign Image using cosign](#sign-image-using-cosign)
4. [Configure Kyverno to use a custom certificate for ImageRegistry (Optional)](#configure-kyverno-to-use-a-custom-certificate-for-imageregistry)
5. [Verify Image using Kyverno](#verify-image-using-kyverno)

## Steps for Image Verification

Below are the steps to verify images before deployment to Kubernetes runtime environments:

1. Deploy Enterprise Kyverno to the Workload cluster
2. (Optional) If your local image registry uses a custom CA, configure Kyverno to use this custom CA for verifying locally hosted images
3. Leverage cosign cli to sign the images. Ensure that the node where cosign is installed has the private CA added to its keystore
4. Deploy the image verification Kyverno policy
5. Confirm image verification based on policy pass/fail

## Prerequisites

- Install cosign: [Installation Guide](https://docs.sigstore.dev/cosign/system_config/installation/)
- (Optional) When using a local registry with a custom certificate authority (CA), retain the full certificate chain for use during configuration

## Sign Image using cosign

To sign your container images, you'll need to generate a key pair and use it to sign your images. This process ensures the authenticity and integrity of your container images.

### Generate key pair
```bash
cosign generate-key-pair
```text
This command creates two files: `cosign.key` (private key) and `cosign.pub` (public key).

### Sign the image
```bash
cosign sign --key cosign.key harbor.nirmata.co/test/nginx:1.18
```text
Replace `harbor.nirmata.co/test/nginx:1.18` with your actual image reference in the format `<registry>/<repository>/<image>:<tag>`  


Confirm the image signature by logging in to the image registry.

## Configure Kyverno to use a custom certificate for ImageRegistry

> **Note**: This step is only required if you are using a private registry with custom certificates. If you are using a public registry or a private registry with standard certificates, you can skip this section and proceed to [Verify Image using Kyverno](#verify-image-using-kyverno).

To enable Kyverno to verify images from a registry with a custom CA, you need to provide the CA certificates to Kyverno.

1. Create a configMap with all root and intermediate certificates (full chain) of the private CA:

```bash
kubectl create cm kyverno-certs --from-file=ca-certificates=harbor-ca.crt -n kyverno
```text

2. Mount the configmap as volume in Kyverno admission controller deployment:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kyverno
  namespace: kyverno
spec:
  template:
    spec:
      containers:
      - args:
        - --autogenInternals=true
        - -v=4
        image: ghcr.io/kyverno/kyverno:v1.7.0-rc1
        name: kyverno
        volumeMounts:
        - mountPath: /.sigstore
          name: sigstore
        - name: ca-certificates
          mountPath: /usr/local/share/ca-certificates/ca-certificates.crt
          subPath: ca-certificates.crt
      volumes:
      - name: sigstore
      - name: ca-certificates
        configMap:
          name: kyverno-certs
          items:
          - key: ca-certificates
            path: ca-certificates.crt
```text

> **Important Note**: The certificate mount path (`/usr/local/share/ca-certificates/ca-certificates.crt`) may vary depending on your node's operating system. Adjust this path according to your environment.

## Verify Image using Kyverno

1. Create a Kyverno image verify policy (Note: change the key in the policy yaml with the one created in the above step)

   You can find example image verification policies in the [Nirmata Kyverno Policies repository](https://github.com/nirmata/kyverno-policies) under the `VerifyImage` directory. These policies provide templates for implementing image verification in your cluster.

2. Test the image verification by attempting to deploy pods with different images:

```bash
# This should succeed if the image is properly signed
kubectl run pod --image=harbor.nirmata.co/test/nginx:1.18 -n demo

# This should fail if the image is not signed or signed with a different key
kubectl run pod --image=harbor.nirmata.co/test1/nginx:1.15 -n demo
```text

The first command should succeed if the image is properly signed with your cosign key. The second command should fail if the image is either unsigned or signed with a different key, demonstrating that the image verification policy is working as expected.



Navigate to Monitor --> Events in Nirmata to check the blocked pod events and view the policy reference details.




---

## Automatic Report Scheduling


Automatic report scheduling is the capability to be able to share Policy Reports with Teams on a recurring basis. If enabled, the reports are shared via emails for the namespaces that each Team has access to.

To set up automatic report scheduling for Teams:

1. Log into Nirmata Control Hub and go to **Identity & Access**>**Teams**. The page shows the list of Teams with the total number of members associated with each particular Team. The provisioned Team along with the associated users should be visible within the list.
2. Go to the provisioned Team and click on the **Schedule** button located at the right top corner to schedule email notifications containing the policy reports.

![image](/images/npm-provisioned-group.png)

3. The schedule can be set to hourly, daily, weekly, or monthly.<br>
    **a.** To schedule reports hourly:<br>
        - Click on the **hourly** tab.<br>
        - Click **Save**.<br>
    **b.** To schedule reports daily:<br>
        - Click on the **daily** tab.<br>
        - Select the time from the dropdown list.<br>
        - Click **Save**.<br>
    **c.** To schedule reports weekly:<br>
        - Click on the **weekly** tab.<br>
        - Select the day and time from the dropdown lists.<br>
        - Click **Save**.<br>
    **d.** To schedule reports monthly:<br>
        - Click on the **monthly** tab.<br>
        - Select the date and time from the dropdown lists.<br>
        - Click **Save**.<br>
4. Upon scheduling, the policy reports will be sent automatically to the email address of the respective members of the Teams at the specified times.

![image](/images/email-report.png)

---

## Automatic Namespace Assignment


Automatic Namespace Assignment is the capability to automatically assign namespace owners to teams in Nirmata Control Hub. The namespace must contain an annotation with the namespace owner key, and the annotation value must correspond to the team name in Nirmata.

To set up automatic namespace assignment for Teams:

1. Log into Nirmata Control Hub and go to **Identity & Access**>**Teams**. The page shows the list of Teams with the total number of members associated with each particular Team.
2. Click on the **Configure** button located at the top right corner of the screen to open the **Team Settings** dialogue box.
3. In the **Team Settings** dialogue box, click on the toggle beside `Enable auto namespace access` to allow automatic access of namespaces to Teams.
4. Next, use the default namespace owner key that is provided or enter your own key under the `Enter namespace owner key` field.
5. Finally, click **Save**.

![image](/images/automatic_namespace_assignment.png)

---

## Automatic User Role Mapping


Role mapping in Automatic User Provisioning refers to the assigning of roles to users that have been provisioned to a Team in the Nirmata Control Hub from Azure Active Directory. It is possible only when SAML Single Sign-On (SSO) is enabled in Nirmata Control Hub for the user and Azure Active Directory is set up as the SAML SSO provider. Refer to [this documentation](https://docs.nirmata.io/docs/control-hub/identityaccess/security-assertion-markup-language-saml/single-signon-with-saml-for-azuread/) for setting up Azure Active Directory to use it as the SAML SSO provider and enabling SAML SSO in Nirmata Control Hub for the user.

To map roles for provisioned users in a Team:

1. Log into the [Azure portal](https://portal.azure.com) with your account credentials. Then, go to **Home**>**Microsoft Entra ID**. Enterprise applications and groups can be created from here. Refer to [this documentation](https://docs.nirmata.io/docs/control-hub/how-to/auto_user_provisioning/#setting-up-npm-in-active-directory) for creating an enterprise application and a group and adding that group within that application.
2. After that, go to the **Default Directory** and click on **App registrations** under **Manage** to view your application among the list of registered applications. The `Owned applications` tab opens by default.
3. Next, click on the `All applications` tab and search the created application. Click on it to view the application details. The overview page opens by default.
4. Now, click on the **App roles** tab under **Manage** on the left to create the required app role and view the already created roles.
5. Then, click on the **Create app role** button on the top which will open the dialog box for creating the app role. The app roles can be created depending on the level of permissions. By default, without an app role, the `devops` role is assigned to a user. Hence, there is no need to create a particular `devops` role as an app role. <br>
    a. Enter the name of your role under `Display name`, e.g. admin, platform.<br>
    b. Click on `Users/Groups` as the `Allowed member types`.<br>
    c. Specify the `Value` as `admin` or `platform` depending on your preference.<br>
    d. Give a detailed description of the role under `Description` that will appear during app assignment and consent experiences.<br>
    e. The enablement of the role is checked by default.<br>
    e. Click **Apply**.<br>

![image](/images/create_role.png)

6. After creating the application role, go to the application created earlier and click on the **Assign users and groups** for assigning the created app-role to an user.
7. Click on the **Add user/group** button on the top. The `Add Assignment` page opens.
8. Select the user to whom the role will be assigned by clicking on `None Selected` under `Users and groups`.<br>
     a. Search the user from the search directory.<br>
     b. Next, click on the checkbox beside the user and click `Select`.<br>
     c. After that, click on `None Selected` under `Select a role` to assign the created app role.<br>
     d. Now, click on the created role from the list and click `Select`.<br>
     e. Finally, click on the **Assign** button to add the user to your application with the assigned role.<br>

![image](/images/assign_role.png)

9. The user can log into the Nirmata Control Hub tenant with Azure Active Directory as the SAML SSO provider and will get the assigned role.


---

## Pipeline Scanning


## Pipeline Scanning Workflow

[nctl scan](https://docs.nirmata.io/docs/nctl/commands/nctl_scan/) can be used within the local CLI environment; however, its true potential is unlocked when utilized within CI pipelines to scan code repositories.

<img src="/images/scan_action_workflow.png" />

Platform or security team administrators are responsible for defining the policies that an organization needs to adhere to. These policies are stored as YAML files in Git repositories, as OCI images in the OCI registry, or are made available as Helm charts. The DevOps users or IT team is responsible for managing the configuration files, whether they are Kubernetes manifests, IaC files, or any JSON specs stored in Git repositories.

Users who want to make changes to the manifests in these repositories will create a pull request (PR). CI pipelines are configured to trigger on various actions, such as creating a PR, merging code to the main branch, or running at regular intervals.

## Setting up the CI Pipeline
NCTL works with any CI pipeline (GitHub Action, GitLab CI, Jenkins, Harness CI, etc.).


---

## Automatic User Provisioning


Automatic User Provisioning is the automatic syncing of users and teams in the Nirmata Control Hub when they are provisioned from Azure Active Directory. This requires creating an enterprise application in Active Directory and setting up the Nirmata Control Hub with it. Refer to the [official Azure docs](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/add-application-portal) for more information on creating and managing Enterprise Applications.

### Setting up Nirmata Control Hub in Active Directory

To create an enterprise application and set up Nirmata Control Hub in the Azure Active Directory:

1. Log into the [Azure portal](https://portal.azure.com) with your account credentials. Then, go to **Home**>**Microsoft Entra ID**. Enterprise applications and groups can be created from here.
2. Click on **Enterprise applications** under **Manage** to view the list of all enterprise applications associated with your organization.
3. Create a new application by clicking on the **New application** button. This opens the Microsoft Entra App Gallery, which is a catalogue consisting of applications and cloud platforms that make it easy to deploy and configure single sign-on (SSO) and automated user provisioning.
4. Click on **Create your own application** to create and integrate your application with the Nirmata Control Hub. Give an application name and click on create. This will create the application and the page lists out the important properties of the application like *Name, Application ID, and Object ID*.

![image](/images/add-application.png)

5. Next, click on the **Provision User Accounts** tile and click on the **Get Started** button to integrate the application with Nirmata Control Hub. To do so:<br>
    a. Select the **Provisioning Mode** as **Automatic** from the dropdown.<br>
    b. After that, fill out the **Tenant URL** with the Nirmata Control Hub URL `https://nirmata.io/users/api/scim/v2` and **Secret Token** with the API key found in the Nirmata Control Hub profile.<br>
    c. Next, click on the **Test connection** button which will return with a success message when the connection gets established.<br>
    d. Finally, click on **Save** to save the configuration settings and complete the integration.<br>

    ![image](/images/provisioning-getting-started.png)

### Adding Users and Groups

1. A group must be created to do the provisioning. For that, go back to the **Default Directory** and click on **Groups** under **Manage** to view the list of groups available for your organization.
2. Click on the **New group** button to create a new group and assign users to it. To do so:<br>
    a. The default **Group type** is set to **Security**. If not, select the **Group type** as **Security** from the dropdown.<br>
    b. Enter the group name.<br>
    c. The **Membership type** is set to **Assigned** by default. If not, select the **Membership type** as **Assigned** from the dropdown.<br>
    d. You are the default owner of the group. Select any other owners of the group by clicking on `No owners selected` under `Owners`.<br>
    e. Click on the checkbox beside the users you want to select as owners and then, click on `Select`.<br>
    f. Assign members to the group by clicking on `No members selected` under `Members`.<br>
    g. Click on the checkbox beside the users you want to select as members and then, click on `Select`.<br>
    h. Click **Create**.<br>

    ![image](/images/create-group.png)

3. After creating the group, go to the application created earlier and click on **Assign users and groups** to add the created group to the application.
4. Click on the **Add user/group** button on the top. The `Add Assignment` page opens.
5. Select the created group by clicking on `None Selected` under `Users and groups`.<br>
     a. Search the newly created group.<br>
     b. Next, click on the checkbox beside the group and click `Select`.<br>
     c. Finally, click on the **Assign** button to add the group into your application.<br>

![image](/images/assign-users-and-groups.png)

### Provisioning Users and Groups

1. After creating the group and assigning it to the application, click on the **Provisioning** tab under **Manage** on the left to open the overview page for provisioning.
2. Then, click on the **Provision on demand** button on the top. The **Provision on demand** page opens.
3. Search the created group by typing the group name within the search bar and select it from the dropdown.
4. After that, click on **View Members only** to select the members of the group for provisioning.<br> 
      a. Click on the dropdown to see the full list of members of the group.<br>
      b. Next, click on the checkbox to select a particular member.<br>
      c. The members outside the group can be selected for provisioning the same way by clicking on **View all users**.<br>

![image](/images/provision-on-demand.png)

5. Finally, click **Provision** to start the provisioning. The provisioning once completed will show a completion page with all the details.

![image](/images/Provision-success.png)

6. To verify team and user sync in Nirmata Control Hub, login to Nirmata Control Hub and go to **Identity & Access**>**Users** and **Identity & Access**>**Teams** to verify user and team creation and user membership. By default, all users will be created with the DevOps role.

>NOTE: Users created as part of the AD sync will have SAML login enabled by default. The initial Role assigned in Nirmata Control Hub is `DevOps`. Only after the user logs in will the mapped Role in AD take effect.

