Skip to content
Latest (currently 2026.8.0) has the newest features, bug fixes, and CVE patches of Solo Enterprise for agentregistry.

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Solo Enterprise for kagent

Page as Markdown

Connect Solo Enterprise for agentregistry to a Solo Enterprise for kagent runtime so that you can deploy agents from the registry to your Kubernetes cluster.

Solo Enterprise for kagent is a Kubernetes-native AI runtime that Solo Enterprise for agentregistry uses to deploy and manage agents and MCP servers as pods in your cluster. When you connect a kagent runtime, the registry server calls the kagent controller’s management API by using its own OIDC service identity to create, update, and delete workloads on your behalf. One registry can connect to multiple kagent clusters at once. For a detailed breakdown of how the components fit together, see Runtime architectures.

Before you begin

  1. Set up an OIDC provider. This guide assumes that you installed Keycloak. Make sure to follow the Solo Enterprise for kagent tab to install Keycloak with the required realm settings, clients, and secrets.

  2. Verify that you have the following environment variables set before continuing.

    echo "KEYCLOAK_ISSUER: $KEYCLOAK_ISSUER"
    echo "AR_BACKEND_SECRET: $AR_BACKEND_SECRET"
    echo "KAGENT_BACKEND_SECRET: $KAGENT_BACKEND_SECRET"
    echo "AGENTREGISTRY_OUTBOUND_SECRET: $AGENTREGISTRY_OUTBOUND_SECRET"
  3. Install Solo Enterprise for agentregistry.

  4. Log in to the registry. Choose between the interactive device authorization and the static username and password credential flow.

    Use this flow for interactive logins from a terminal. The CLI uses the ar-cli-interactive public client and starts a device authorization grant flow that prints a URL and a one-time code for you to approve in a browser.

    1. Configure the CLI to use the Keycloak issuer and ar-cli-interactive client. Then, log in to Solo Enterprise for agentregistry.

      export OIDC_ISSUER=$KEYCLOAK_ISSUER
      export OIDC_CLIENT_ID=ar-cli-interactive
      arctl user login

      Example output:

      To complete the login process, please:
       1. Open: http://172.18.0.13:8080/realms/agentregistry/device
       2. Enter the code: SYSQ-SNSP
       - or go to: http://172.18.0.13:8080/realms/agentregistry/device?user_code=SYSQ-SNSP
      
    2. Open the URL in a web browser and log into Keycloak with the admin-user username and password password. Confirming the code in the browser tells Keycloak to issue an access token for the CLI session. After authorization is complete, the CLI stores the token in your system keychain so you do not have to log in again until it expires.

    Use this flow for scripted logins where a specific user identity is required in CI/CD pipelines. The CLI uses the ar-cli-password public client and exchanges a username and password directly for an access token.

    1. Log in to Solo Enterprise for agentregistry with the admin-user/password credentials.

      export OIDC_ISSUER=$KEYCLOAK_ISSUER
      arctl user login \
        --oidc-flow=password-credentials \
        --oidc-client-id=ar-cli-password \
        --oidc-username=admin-user \
        --oidc-password=password
    2. Save the access token in the ARCTL_API_TOKEN environment variable.

      export ARCTL_API_TOKEN=$(arctl user info --show-tokens | jq -r .access_token)

Step 1: Install Solo Enterprise for kagent

  1. Save your Solo Enterprise for kagent license key in an environment variable. To obtain the key, contact an account representative. If you prefer to specify the license key in a secret instead, see Licensing.

    export KAGENT_LICENSE_KEY="<key>"
  2. Save the API key for the LLM that you want to use as an environment variable. This example uses Gemini. For a list of supported LLMs, see Supported LLMs in the Solo Enterprise for kagent documentation.

    export GOOGLE_API_KEY="<key>"
  3. Set the Solo Enterprise for kagent patch version. This example uses the latest version. You can find other versions in the reference documentation.

    export KAGENT_ENT_VERSION=0.5.6
  4. Install the kagent-mgmt chart for Solo Enterprise for kagent.

    helm upgrade -i kagent-mgmt \
      oci://us-docker.pkg.dev/solo-public/solo-enterprise-helm/charts/management \
      -n kagent --create-namespace \
      --version "$KAGENT_ENT_VERSION" \
      --set cluster=mgmt-cluster \
      --set products.kagent.enabled=true \
      --set products.agentregistry.enabled=true \
      --set-string licensing.licenseKey="$KAGENT_LICENSE_KEY" \
      --set-string oidc.issuer="$KEYCLOAK_ISSUER" \
      --set-string ui.backend.oidc.clientId=kagent-backend \
      --set-string ui.backend.oidc.secret="$KAGENT_BACKEND_SECRET" \
      --set-string ui.frontend.oidc.clientId=kagent-ui
  5. Verify that the management component pods have a status of Running.

    kubectl get po -n kagent
    • The clickhouse pod runs a ClickHouse exporter for local data storage.
    • The ui pod runs the UI that you can use to monitor and manage agents.
    • The telemetry-collector pod runs the OTel collector that collects telemetry data from your cluster.
    NAME                                    READY   STATUS              RESTARTS   AGE
    kagent-mgmt-clickhouse-shard0-0         1/1     Running             0          4s
    solo-enterprise-telemetry-collector-0   1/1     Running             0          4s
    solo-enterprise-ui-76c85c7d6b-xftcj     5/5     Running             0          4s
    
  6. Install the kagent-enterprise CRDs chart.

    helm upgrade --install kagent-crds \
      oci://us-docker.pkg.dev/solo-public/kagent-enterprise-helm/charts/kagent-enterprise-crds \
      -n kagent \
      --version "$KAGENT_ENT_VERSION"
  7. Create an OBO token for the Solo Enterprise for kagent controller and store it in a Kubernetes secret. The controller watches for a secret named jwt in its own namespace and uses the token to provide authentication so that agents can execute actions on behalf of the user. If the secret is missing, the OBO token handler stays in a not ready state and A2A chat requests to agents fail with an upstream auth failed: obo token handler not ready error.

    openssl genrsa -out /tmp/key.pem 2048
    kubectl create secret generic jwt \
    -n kagent --from-file=jwt=/tmp/key.pem \
    --dry-run=client -o yaml | kubectl apply -f -    
  8. Create a values file for the RBAC configuration in Solo Enterprise for kagent.

    roleMappings is a lookup table that maps a Keycloak group name to a Solo Enterprise for kagent role. In this guide, any token that carries agentregistry in its Groups claim is granted the global.Writer role in Solo Enterprise for kagent. Tokens with other Groups claim values or tokens that do not have a Groups claim at all, are denied with a 401 Unauthorized response.

    cat > /tmp/kagent-rbac.yaml << 'EOF'
    rbac:
      roleMapping:
        roleMapper: 'has(claims.Groups) ? claims.Groups.transformList(i, v, v in rolesMap, rolesMap[v]) : []'
        roleMappings:
          agentregistry: global.Writer
    EOF
  9. Install the kagent-enterprise chart to deploy the Solo Enterprise for kagent controller and UI.

    helm upgrade -i kagent \
      oci://us-docker.pkg.dev/solo-public/kagent-enterprise-helm/charts/kagent-enterprise \
      -n kagent \
      --version "$KAGENT_ENT_VERSION" \
      --set-string licensing.licenseKey="$KAGENT_LICENSE_KEY" \
      --set agents.k8s-agent.enabled=true \
      --set kagent-tools.enabled=true \
      --set kmcp.licensing.createSecret=false \
      --set-string oidc.issuer="$KEYCLOAK_ISSUER" \
      --set oidc.clientId=kagent-backend \
      --set-string oidc.secret="$KAGENT_BACKEND_SECRET" \
      --set providers.openAI.apiKey=$GOOGLE_API_KEY \
      -f /tmp/kagent-rbac.yaml
  10. Verify that the controller and UI deployments are ready.

    kubectl get po -n kagent

    Example output:

    kagent-controller-dfc4c966c-zzds5                    1/1     Running                      0          3m
    kagent-mgmt-clickhouse-shard0-0                      1/1     Running                      0          5m48s
    kagent-postgresql-57c4f5597f-x4mjg                   1/1     Running                      0          3m
    kagent-tools-69bdb559df-cb9bw                        1/1     Running                      0          3m
    kmcp-enterprise-controller-manager-dbd59bcbf-j5hjt   1/1     Running                      0          3m
    solo-enterprise-telemetry-collector-0                1/1     Running                      0          5m48s
    solo-enterprise-ui-66cbb6687c-6czzk                  4/4     Running                      0          5m48s
    

Step 2: Connect to Solo Enterprise for kagent

Create a Runtime resource that points Solo Enterprise for agentregistry at the Solo Enterprise for kagent controller you deployed in Step 1. Choose between the following setup paths:

  • General setup: Choose this tab if you run Solo Enterprise for kagent in a standard Kubernetes cluster.
  • Inject AWS credentials at agent runtime: Choose this tab if you installed Solo Enterprise for kagent in an AWS EKS cluster and your deployed agents need AWS credentials injected at runtime to access other AWS services, such as an S3 bucket.

Use these instructions for a standard Kubernetes setup where deployed agents do not need AWS credentials. If your agents need to call AWS services such as Bedrock AgentCore, use the Inject AWS credentials at agent runtime tab instead.

  1. Create a Solo Enterprise for agentregistry Secret that stores the client secret for the agentregistry Keycloak client. The runtime references this secret when it mints outbound tokens to call the Solo Enterprise for kagent controller.

    arctl apply -f- <<EOF
    apiVersion: ar.dev/v1alpha1
    kind: Secret
    metadata:
      name: kagent-oidc
    spec:
      type: Opaque
      stringData:
        clientSecret: "$AGENTREGISTRY_OUTBOUND_SECRET"
    EOF

    Example output:

    ✓ Secret/kagent-oidc applied
    
  2. Create the Solo Enterprise for kagent runtime in Solo Enterprise for agentregistry. The runtime points to the Solo Enterprise for kagent controller that you deployed to the kagent namespace. The auth.oidc block tells the registry server which credentials to use when it calls the kagent controller on your behalf.

    arctl apply -f- <<EOF
    apiVersion: ar.dev/v1alpha1
    kind: Runtime
    metadata:
      name: kagent
    spec:
      type: Kagent
      telemetryEndpoint: http://agentregistry-enterprise-telemetry-collector.agentregistry-system.svc.cluster.local:4318
      config:
        kagentUrl: http://kagent-controller.kagent:8083
        namespace: kagent
        auth:
          oidc:
            issuer: $KEYCLOAK_ISSUER
            clientId: agentregistry
            clientSecretRef:
              name: kagent-oidc
              key: clientSecret
    EOF

    Example output:

    ✓ Runtime/kagent applied
    

    Note

    If your kagent controller uses Microsoft Entra ID as the OIDC provider, add a scope field to the auth.oidc block as shown in the following snippet. Entra requires a scope parameter on client_credentials requests that Keycloak does not include by default. Set scope to the application ID URI of your kagent app registration followed by /.default.

    auth:
      oidc:
        issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
        clientId: <entra-client-id>
        scope: api://<kagent-app-id>/.default
        clientSecretRef:
          name: kagent-oidc
          key: clientSecret
  3. List the runtimes that are connected to Solo Enterprise for agentregistry and verify that the kagent runtime is listed. You also see a default kubernetes-default and local runtime.

    arctl get runtimes

    Example output:

    NAME                 TYPE
    kagent               Kagent
    kubernetes-default   Kubernetes
    local                Local 
    virtual-default      Virtual
    

Use these instructions if Solo Enterprise for kagent runs on an Amazon EKS cluster and your deployed agents need AWS credentials, such as to call AWS Bedrock AgentCore agents or access an S3 bucket. Solo Enterprise for agentregistry automatically creates an EKS Pod Identity Association (PIA) before each agent deployment. This way, the agent pod gets the AWS credentials injected on first start with no manual setup and no restart required. The association is deleted when you delete the agent deployment.

Important

Solo Enterprise for agentregistry must be installed with EKS Pod Identity enabled (aws.usePodIdentity=true). If you followed the AWS Bedrock AgentCore quickstart, this is already in place and the role name is agentregistry-pod-identity-role. Cross-account is not supported. The EKS cluster and the pod execution role must be in the same AWS account as Solo Enterprise for agentregistry.

  1. If not already installed, enable the EKS Pod Identity Agent add-on on your EKS cluster.

    aws eks create-addon --cluster-name $EKS_CLUSTER_NAME --addon-name eks-pod-identity-agent --region $AWS_REGION
  2. Create the IAM role that agent pods assume and save the role ARN as an environment variable.

    1. Create the trust policy file.

      cat > pod-execution-trust-policy.json << 'EOF'
      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {"Service": "pods.eks.amazonaws.com"},
            "Action": ["sts:AssumeRole", "sts:TagSession"]
          }
        ]
      }
      EOF
    2. Create the IAM role and save its ARN.

      export POD_EXECUTION_ROLE_NAME="kagent-agent-pod-execution-role"
      aws iam create-role \
        --role-name "$POD_EXECUTION_ROLE_NAME" \
        --assume-role-policy-document file://pod-execution-trust-policy.json
      export POD_EXECUTION_ROLE_ARN=$(aws iam get-role \
        --role-name "$POD_EXECUTION_ROLE_NAME" \
        --query 'Role.Arn' --output text)
      echo "POD_EXECUTION_ROLE_ARN: $POD_EXECUTION_ROLE_ARN"
  3. Set the name of your EKS cluster and Solo Enterprise for agentregistry’s IAM role, then derive the cluster ARN.

    export EKS_CLUSTER_NAME=<eks-cluster-name>
    export AGENTREGISTRY_ROLE_NAME=<agentregistry-iam-role-name>
    export EKS_CLUSTER_ARN=$(aws eks describe-cluster \
      --name "$EKS_CLUSTER_NAME" \
      --query 'cluster.arn' \
      --output text)
    echo "EKS_CLUSTER_ARN: $EKS_CLUSTER_ARN"

    If you are not sure what the Solo Enterprise for agentregistry IAM role name is, look it up from the existing Pod Identity Association.

    aws eks list-pod-identity-associations \
      --cluster-name "$EKS_CLUSTER_NAME" \
      --namespace agentregistry-system \
      --query 'associations[].{SA:serviceAccount,Role:roleArn}' \
      --output table
  4. Grant Solo Enterprise for agentregistry’s IAM role permission to manage Pod Identity Associations on your cluster and to pass the pod execution role you created in the previous step to agent pods.

    aws iam put-role-policy \
      --role-name "$AGENTREGISTRY_ROLE_NAME" \
      --policy-name "AgentRegistryPodIdentity" \
      --policy-document "{
        \"Version\": \"2012-10-17\",
        \"Statement\": [
          {
            \"Effect\": \"Allow\",
            \"Action\": [
              \"eks:CreatePodIdentityAssociation\",
              \"eks:DeletePodIdentityAssociation\",
              \"eks:ListPodIdentityAssociations\"
            ],
            \"Resource\": \"$EKS_CLUSTER_ARN\"
          },
          {
            \"Effect\": \"Allow\",
            \"Action\": \"iam:PassRole\",
            \"Resource\": \"$POD_EXECUTION_ROLE_ARN\"
          }
        ]
      }"
  5. Create a Solo Enterprise for agentregistry Secret that stores the client secret for the agentregistry Keycloak client.

    arctl apply -f- <<EOF
    apiVersion: ar.dev/v1alpha1
    kind: Secret
    metadata:
      name: kagent-oidc
    spec:
      type: Opaque
      stringData:
        clientSecret: "$AGENTREGISTRY_OUTBOUND_SECRET"
    EOF

    Example output:

    ✓ Secret/kagent-oidc applied
    
  6. Create the Solo Enterprise for kagent runtime. The auth.connection block tells Solo Enterprise for agentregistry to create a Pod Identity Association for each agent it deploys to this runtime.

    arctl apply -f- <<EOF
    apiVersion: ar.dev/v1alpha1
    kind: Runtime
    metadata:
      name: kagent
    spec:
      type: Kagent
      telemetryEndpoint: http://agentregistry-enterprise-telemetry-collector.agentregistry-system.svc.cluster.local:4318
      config:
        kagentUrl: http://kagent-controller.kagent:8083
        namespace: kagent
        auth:
          oidc:
            issuer: $KEYCLOAK_ISSUER
            clientId: agentregistry
            clientSecretRef:
              name: kagent-oidc
              key: clientSecret
          connection:
            type: aws
            aws:
              podExecutionRoleArn: $POD_EXECUTION_ROLE_ARN
              clusterArn: $EKS_CLUSTER_ARN
    EOF
    FieldDescription
    auth.connection.typeSet to aws to enable EKS Pod Identity.
    auth.connection.aws.podExecutionRoleArnThe ARN of the IAM role to attach to agent pods.
    auth.connection.aws.clusterArnThe ARN of the EKS cluster. Required when using pod identity.

    Example output:

    ✓ Runtime/kagent applied
    

    Note

    If your kagent controller uses Microsoft Entra ID as the OIDC provider, add a scope field to the auth.oidc block as shown in the following snippet. Entra requires a scope parameter on client_credentials requests that Keycloak does not include by default. Set scope to the application ID URI of your kagent app registration followed by /.default.

    auth:
      oidc:
        issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
        clientId: <entra-client-id>
        scope: api://<kagent-app-id>/.default
        clientSecretRef:
          name: kagent-oidc
          key: clientSecret
  7. List the runtimes that are connected to Solo Enterprise for agentregistry and verify that the kagent runtime is listed.

    arctl get runtimes

    Example output:

    NAME                 TYPE
    kagent               Kagent
    kubernetes-default   Kubernetes
    local                Local 
    virtual-default      Virtual
    

Step 3: Optional: Install Solo Enterprise for Istio

Runtime authorization with AccessPolicies requires Solo Enterprise for Istio (ambient mesh) and Solo Enterprise for agentgateway. Together, they provide the ztunnel and waypoint proxy infrastructure that enforces AccessPolicies at the network level before any request reaches its target.

Note

This step is optional for basic agent deployment. You only need it if you want to restrict which MCP server tools an agent can invoke at runtime.

Install ambient mesh

  1. Save your Solo Enterprise for Istio license key in an environment variable. The license key is included with your Solo Enterprise for kagent license. To obtain the key, contact an account representative.

    export SOLO_ISTIO_LICENSE_KEY=<key>
  2. Save the Solo distribution of Istio version and image repository details.

    export ISTIO_VERSION=1.29.6
    export ISTIO_IMAGE=${ISTIO_VERSION}-solo
    export REPO=us-docker.pkg.dev/soloio-img/istio
    export HELM_REPO=us-docker.pkg.dev/soloio-img/istio-helm
  3. Apply the Kubernetes Gateway API CRDs, which are required for waypoint proxies and other components.

    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.0/standard-install.yaml
  4. Install the istio-base chart, which contains the CRDs and cluster roles required to set up Istio.

    helm upgrade --install istio-base oci://${HELM_REPO}/base \
      --namespace istio-system \
      --create-namespace \
      --version ${ISTIO_IMAGE} \
      -f - <<EOF
    defaultRevision: ""
    profile: ambient
    EOF
  5. Create the istiod control plane.

    helm upgrade --install istiod oci://${HELM_REPO}/istiod \
      --namespace istio-system \
      --version ${ISTIO_IMAGE} \
      -f - <<EOF
    global:
      hub: ${REPO}
      proxy:
        clusterDomain: cluster.local
      tag: ${ISTIO_IMAGE}
    meshConfig:
      accessLogFile: /dev/stdout
      defaultConfig:
        proxyMetadata:
          ISTIO_META_DNS_AUTO_ALLOCATE: "true"
          ISTIO_META_DNS_CAPTURE: "true"
    env:
      PILOT_ENABLE_IP_AUTOALLOCATE: "true"
      PILOT_SKIP_VALIDATE_TRUST_DOMAIN: "true"
    pilot:
      cni:
        namespace: istio-system
        enabled: true
    profile: ambient
    license:
      value: ${SOLO_ISTIO_LICENSE_KEY}
    EOF
  6. Install the Istio CNI node agent daemonset.

    helm upgrade --install istio-cni oci://${HELM_REPO}/cni \
      --namespace istio-system \
      --version ${ISTIO_IMAGE} \
      -f - <<EOF
    ambient:
      dnsCapture: true
    excludeNamespaces:
      - istio-system
      - kube-system
    global:
      hub: ${REPO}
      tag: ${ISTIO_IMAGE}
    profile: ambient
    EOF
  7. Install the ztunnel daemonset.

    helm upgrade --install ztunnel oci://${HELM_REPO}/ztunnel \
      --namespace istio-system \
      --version ${ISTIO_IMAGE} \
      -f - <<EOF
    configValidation: true
    enabled: true
    env:
      L7_ENABLED: "true"
    hub: ${REPO}
    istioNamespace: istio-system
    namespace: istio-system
    profile: ambient
    proxy:
      clusterDomain: cluster.local
    tag: ${ISTIO_IMAGE}
    terminationGracePeriodSeconds: 29
    variant: distroless
    EOF
  8. Verify that the ambient mesh components are running.

    kubectl get pods -n istio-system

    Example output:

    NAME                      READY   STATUS    RESTARTS   AGE
    istio-cni-node-ps9vs      1/1     Running   0          80s
    istiod-58f745c977-q94jj   1/1     Running   0          94s
    ztunnel-7df9l             1/1     Running   0          62s
    
  9. Enroll the kagent namespace in the ambient mesh. This label tells ztunnel to intercept traffic for all pods in the namespace so that traffic flows through the waypoint proxies where AccessPolicies are enforced. Without this label, agent-to-MCP traffic bypasses the waypoints and policies are never applied.

    kubectl label namespace kagent istio.io/dataplane-mode=ambient

    Verify that the label was applied.

    kubectl get namespace kagent --show-labels

    Example output:

    NAME     STATUS   AGE   LABELS
    kagent   Active   10m   istio.io/dataplane-mode=ambient,kubernetes.io/metadata.name=kagent
    

Install Solo Enterprise for agentgateway

Solo Enterprise for agentgateway deploys waypoint proxies that enforce AccessPolicies. You must install it after the ambient mesh.

  1. Save your Solo Enterprise for agentgateway license key in an environment variable. The license key is included with your Solo Enterprise for kagent license.

    export AGENTGATEWAY_LICENSE_KEY=<key>
  2. Deploy the Solo Enterprise for agentgateway CRDs and control plane.

    helm upgrade -i enterprise-agentgateway-crds \
      oci://us-docker.pkg.dev/solo-public/enterprise-agentgateway/charts/enterprise-agentgateway-crds \
      --create-namespace \
      --namespace agentgateway-system \
      --version v2026.7.0
    
    helm upgrade -i enterprise-agentgateway \
      oci://us-docker.pkg.dev/solo-public/enterprise-agentgateway/charts/enterprise-agentgateway \
      --namespace agentgateway-system \
      --version v2026.7.0 \
      --set licensing.licenseKey=${AGENTGATEWAY_LICENSE_KEY}
  3. Verify that agentgateway is running.

    kubectl get pods -n agentgateway-system

    Example output:

    NAME                                       READY   STATUS    RESTARTS   AGE
    enterprise-agentgateway-5495d98459-46dpk   1/1     Running   0          19s
    

Next steps