Overview - Administrator Guide - Cortex CLOUD

KSPM-Documentation

Product
Cortex Cloud Application Security > Cortex CLOUD
Creation date
2025-05-11
Last date published
2026-06-11
Category
Administrator Guide

kcli is designed for environments requiring image mirroring before deployment, including air-gapped clusters and GitOps-driven installations. The tool integrates into the Cortex Cloud portal's Kubernetes Connect wizard, slotting between the configuration download step and the final installation step.

Functional responsibilities

The image mirroring workflow distributes tasks across two roles:

  • Platform Engineer (Infrastructure): Installs kcli, mirrors images to the private registry, and commits the rewritten values file to version control.

  • Cluster Administrator (Deployment): Executes the portal's installation commands against the rewritten values file to deploy the konnector to the cluster.

Prerequisites

Verify the following tools are installed on the workstation where you will run kcli:

Tool

Minimum version

Purpose

bash

4.0+

Script runtime

docker

20.10+ with buildx

Pull and push multi-architecture images

yq

v4 (mikefarah/yq)

YAML processing

jq

1.6+

JSON processing

curl

Any recent version

Chart download and version check

helm

3.8+

Pull chart from source OCI registry

tar, base64

POSIX standard

Bundled with all supported operating systems

Note

  • macOS: The system bash is version 3.2. Install a newer version with brew install bash. kcli will automatically use the Homebrew bash if it is first in your PATH.

  • yq: Must be the Go-based mikefarah/yq, not the Python variant. Verify with yq --version.

  • Network access: The workstation running kcli must have access to both the Cortex source registry and your private registry. The cluster only needs access to your private registry.

  • Bundle version: kcli requires konnector bundle v2 or higher. Older bundles are rejected at startup.

  • Air-gapped environments: Set KCLI_SKIP_VERSION_CHECK=1 to skip the upstream version check.

Install the image mirroring CLI

kcli is a single self-contained bash script. Pin to a specific version tag for reproducible installations.

curl -fsSL "https://raw.githubusercontent.com/PaloAltoNetworks/cortex-cloud/main/tools/kcli/kcli" -o /tmp/kcli
sudo install -m 0755 /tmp/kcli /usr/local/bin/kcli
kcli version

Alternatively, clone the repository and create a symlink to the kcli script in your PATH:

git clone https://github.com/PaloAltoNetworks/cortex-cloud.git
ln -s $(pwd)/cortex-cloud/tools/kcli/kcli /usr/local/bin/kcli
Mirror images to your private registry

Step 1: Download configuration files from the portal

  1. From Cortex, navigate to SettingsData Sources & Integrations.

  2. Select Kubernetes, and then right-click and select Edit.

  3. Click Edit Profile and configure the following:

    • Set Profile Name to Standalone-Installer.

    • Disable Auto Upgrade.

    • Click Apply.

  4. Click Generate.

  5. From the Kubernetes Connect screen, download both values.yaml and auth.json to your computer.

  6. Do not continue with the steps in the wizard. This should be done later when deploying the konnector.

Step 2: Create a pull secret for your private registry

If you are using --docker-pull-secret-file, create a kubelet-compatible pull secret with inline credentials. kubelet cannot use Docker credential helpers (credsStore, credHelpers, osxkeychain, acr, gcloud, ecr-login).

Build the pull secret:

REG="myregistry.azurecr.io"
USER="<username>"
PASS="<password-or-token>"
AUTH=$(printf '%s:%s' "$USER" "$PASS" | base64 | tr -d '\n')
cat > pull-secret.dockerconfigjson <<EOF
{"auths":{"$REG":{"auth":"$AUTH"}}}
EOF

Credential recipes by registry:

  • Azure Container Registry (ACR): Use an ACR token with pull rights: <token-name>:<token-password>

  • Google Artifact Registry (GAR) / Google Container Registry (GCR): Use a service account with roles/artifactregistry.reader: _json_key:$(cat key.json)

  • Amazon Elastic Container Registry (ECR): Prefer IRSA or EKS Pod Identity with --no-pull-secret (ECR tokens expire after 12 hours).

  • Harbor, Quay, Artifactory: Use a robot account: username:password

  • Docker Hub: Use a Personal Access Token: <username>:<PAT>

Step 3: Mirror images and rewrite values.yaml

  1. Sign in to your private registry:

    docker login myregistry.azurecr.io 
  2. Run kcli mirror to pull images from the Cortex source registry and push them to your private registry:

    kcli mirror \ 
      --chart-version 2.0.0 \ 
      --values ./values.yaml \ 
      --private-registry myregistry.azurecr.io/cortex \ 
      --docker-pull-secret-file ./pull-secret.dockerconfigjson 

    Note

    If you have already downloaded the Helm chart archive (for example, on an air-gapped relay host), pass the local chart file instead:

    kcli mirror \ 
      --chart ./konnector-2.0.0.tgz \ 
      --values ./values.yaml \ 
      --private-registry myregistry.azurecr.io/cortex \ 
      --docker-pull-secret-file ./pull-secret.dockerconfigjson 

    What kcli modifies:

    kcli writes a timestamped backup to <values>.bak.YYYYMMDDTHHMMSSZ and updates three fields inyour values file:

    global: 
      imageRegistry: myregistry.azurecr.io/cortex 
      dockerPullSecret: <your-private-registry-creds-b64>
    bundle: 
      <component>: 
        image: 
            repository: <component> 
  3. Delete the temporary pull secret file:

    rm pull-secret.dockerconfigjson 

    The credentials are now embedded in the rewritten values file under global.dockerPullSecret.

  4. Commit the rewritten values file to version control if you are using GitOps (Argo CD, Flux):

    git add values.yaml
    git commit -m "Mirror konnector images to private registry"
    git push 

Step 4: Deploy the Konnector

From the Kubernetes Connect screen, continue at step 2 where you run deployment script and install the Helm chart. This block contains two commands:

  • helm registry login: Authenticates to the Cortex source OCI registry using the auth. json credentials.

  • helm upgrade --install: Deploys the konnector using the rewritten values file, so Pods pull images from your private registry.

Run both commands together as shown on the screen:

cat K8s-security-profile-panw-31-May-26-5PM.auth.json | helm registry login 
us-central1-docker.pkg.dev --username _json_key --password-stdin

helm upgrade --install konnector oci://us-central1-docker.pkg.dev/qa2-test-
99924894351125/agent-docker/helm/konnector-launcher \ 
  --wait-for-jobs \ 
  --create-namespace \ 
  --namespace panw \ 
  --values K8s-security-profile-panw-31-May-26-5PM.values.yaml \ 
  --set-file konnector-upgrader.rawValuesContent=K8s-security-profile-panw-
31-May-26-5PM.values.yaml 
kcli command reference

kcli mirror

Mirror images and rewrite the Helm values file.

kcli mirror (--chart <chart.tgz> | --chart-version <version>) \ 
  --values <values-file> \ 
  --private-registry <registry> \ 
  (--docker-pull-secret <b64> | --docker-pull-secret-file <file> | --no-pull-secret) \ 
  [--dry-run] 

Flag

Required

Description

--chart<chart.tgz>

One of these

Local konnector Helm chart archive (bundle v2+).

--chart-version<version>

One of these

Pull the chart from oci://<global.imageRegistry>/helm/konnector-bundle:<version> (for example, 2.0.0). The <global.imageRegistry> value is read from the values file. Requires helm.

--values<file>

Yes

Tenant values YAML file. Rewritten in place with a .bak backup.

--private-registry<url>

Yes

Target registry URL (for example, myregistry.azurecr.io/proj/repo).

--docker-pull-secret<b64>

One of these

Base64-encoded dockerconfigjson.

--docker-pull-secret-file <file>

One of these

Path to dockerconfigjson file (automatically base64-encoded).

--no-pull-secret

One of these

Strip global.dockerPullSecret from values. Use for managed identities (IRSA, AKS, GKE) or out-of-band imagePullSecret resources.

--dry-run

No

Preview changes without pulling, pushing, or rewriting files.

-h, --help

No

Display command help.

Other commands

  • kcli version (also --version, -v): Display the installed kcli version.

  • kcli help (also --help, -h): Display general help.

  • kcli mirror --help: Display help for the mirror command.

Environment variables

  • NO_COLOR: Set to any value to disable ANSI color output.

  • DOCKER_CONFIG: Docker configuration directory (default: ~/.docker).

  • TMPDIR: Temporary directory for chart extraction and logs (default: /tmp).

  • KCLI_SKIP_VERSION_CHECK: Set to 1 to skip the upstream version check (air-gapped environments).

Exit codes

  • 0 - Success

  • 1 - Runtime failure

  • 64 - Usage error

  • 65 - Stale version (kcli is outdated)

  • 130 - Interupted by user

Update kcli

Every kcli run (except version and help) compares your local version to the canonical script on the main branch. If your version is older, kcli fails with exit code 65 and an actionable message.

The version check is best-effort and is skipped (with a warning) if curl is unavailable, the fetch times out (5 seconds), or KCLI_SKIP_VERSION_CHECK=1 is set.

To update:

  • Installed via curl: Re-run the install command and update the KCLI_VERSION variable.

  • Installed via git clone: Run git pull in the cloned repository.

Troubleshooting image mirroring

Issue

Solution

"Unsupported bundle version"

kcli requires bundle v2 or higher. Verify with tar -xzOf <chart.tgz> konnector-bundle/Chart.yaml | yq '.version'. Download a v2+ chart from the Cortex Cloud portal.

"Could not extract global.imageRegistry/global.dockerPullSecret"

Your values file is missing required fields. The portal-issued file includes both. Verify you are not using a hand-crafted values file.

Docker login failures

Source registry credentials come from global.dockerPullSecret (must be valid base64). For the target registry, run docker login <your-registry> first. In CI/CD, use non-interactive login.

ImagePullBackOff after installation

Most common causes: (1) You used --docker-pull-secret-file with ~/.docker/config.json that delegates to a credential helper. Build a proper inline secret per the pull secret section. (2) You used --no-pull-secret but did not create the imagePullSecret resource, or your managed-identity binding is incorrect.

Multi-architecture push failures

kcli uses docker buildx imagetools create and falls back to single-architecture docker tag and docker push. Ensure docker buildx is installed and a builder exists: docker buildx create --use.

"Wrong yq" error

Run yq --version. Must show mikefarah/yq v4. Install with brew install yq (macOS) or follow the mikefarah/yq installation guide.

"A newer kcli version is available" (exit 65)

Update kcli per the Update kcli section, or set KCLI_SKIP_VERSION_CHECK=1 in air-gapped environments.

Debugging

Each run writes a log to $TMPDIR/kcli-log-XXXXXX.log (preserved on success and failure). Attach this log to support tickets. For deep debugging, run bash -x /usr/local/bin/kcli mirror ...