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.

Amazon EKS

Page as Markdown

Install Solo Enterprise for agentregistry on an Amazon EKS cluster with AWS Bedrock AgentCore support.

Install Solo Enterprise for agentregistry on an Amazon EKS cluster. This guide covers the additional AWS infrastructure that an EKS install requires compared to a standard Kubernetes install, including the AWS Load Balancer Controller for the OTel collector NLB, and AWS credentials so that the registry can deploy agents to AWS Bedrock AgentCore.

Note

Solo.io provides Helm values to install third-party components as a convenience, including ClickHouse, OpenTelemetry collector, and PostgreSQL. These components are not included in the Solo Support policy. For support, contact the respective vendor or open-source project community.

Before you begin

  1. Install the following CLIs.

    • helm: Install Helm charts.
    • kubectl: Interact with your Kubernetes cluster.
    • aws: Interact with AWS.
    • eksctl: Create IAM service accounts on EKS.
  2. Set up an OIDC provider. This guide assumes you installed Keycloak and have the following environment variables set.

    echo "KEYCLOAK_ISSUER: $KEYCLOAK_ISSUER"
    echo "AR_BACKEND_SECRET: $AR_BACKEND_SECRET"
  3. Save your Solo Enterprise for agentregistry license key in an environment variable. To obtain the key, contact an account representative. For more options, such as providing the key in a secret, see Licensing.

    export AGENTREGISTRY_LICENSE_KEY=<license_key>
  4. Create or use an existing AWS VPC. You deploy your EKS cluster, AWS Bedrock AgentCore runtimes, and managed gateway into this VPC to allow secure private networking between agents and MCP servers. Make sure that your VPC has the following configuration:

    • At least one private subnet.
    • A security group that allows inbound traffic from within the VPC. The default security group in the VPC is sufficient for this guide.

    Save the networking details as environment variables.

    1. Set the VPC ID and AWS region.

      export VPC_ID=<vpc-ID>
      export AWS_REGION=<aws-region>
    2. Retrieve the private subnet IDs from the VPC. Private subnets are identified by map-public-ip-on-launch=false. The gateway that you deploy when you follow the AgentCore runtime guide uses a single subnet. Agent and MCP server runtime deployments use all available private subnets for redundancy.

      # Single private subnet for the gateway
      export SUBNET_ID=$(aws ec2 describe-subnets \
        --region "${AWS_REGION}" \
        --filters "Name=vpc-id,Values=${VPC_ID}" "Name=map-public-ip-on-launch,Values=false" \
        --query 'Subnets[0].SubnetId' \
        --output text)
      
      # All private subnets formatted as YAML for Deployment specs
      export SUBNET_IDS_YAML=$(aws ec2 describe-subnets \
        --region "${AWS_REGION}" \
        --filters "Name=vpc-id,Values=${VPC_ID}" "Name=map-public-ip-on-launch,Values=false" \
        --query 'Subnets[].SubnetId' \
        --output json | jq -r '.[] | "      - " + .')
      
      echo "Gateway subnet: ${SUBNET_ID}"
      echo "Agent and MCP server deployment subnets:"
      echo "${SUBNET_IDS_YAML}"
    3. Retrieve the default security group ID for the VPC.

      export SG_ID=$(aws ec2 describe-security-groups \
        --region "${AWS_REGION}" \
        --filters "Name=vpc-id,Values=${VPC_ID}" "Name=group-name,Values=default" \
        --query 'SecurityGroups[0].GroupId' \
        --output text)
      echo "SG_ID: ${SG_ID}"
  5. Create or use an existing Amazon EKS cluster. Make sure that the cluster is deployed into the VPC you configured in step 4. For more information about how to create a cluster, see the EKS documentation. Save the cluster details as environment variables.

    export EKS_CLUSTER_NAME=<your-eks-cluster-name>
    export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
    echo "EKS_CLUSTER_NAME: $EKS_CLUSTER_NAME"
    echo "AWS_REGION: $AWS_REGION"
    echo "AWS_ACCOUNT_ID: $AWS_ACCOUNT_ID"

Step 1: Install the AWS Load Balancer Controller

Solo Enterprise for agentregistry exposes its OpenTelemetry collector as an internal Network Load Balancer (NLB) so that agents deployed to AgentCore runtimes in your VPC can push telemetry back to the registry. The AWS Load Balancer Controller provisions and manages that NLB. If the controller is already installed in your cluster, skip to Step 2.

  1. Associate an OIDC provider with your cluster. This is required to use IAM Roles for Service Accounts (IRSA), which the controller uses to call AWS APIs.

    eksctl utils associate-iam-oidc-provider \
      --region $AWS_REGION \
      --cluster $EKS_CLUSTER_NAME \
      --approve
  2. Download the IAM policy that grants the controller the permissions it needs and create the policy in your account.

    curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.11.0/docs/install/iam_policy.json
    aws iam create-policy \
      --policy-name AWSLoadBalancerControllerIAMPolicy \
      --policy-document file://iam_policy.json
  3. Create the IAM service account and attach the policy.

    eksctl create iamserviceaccount \
      --cluster=$EKS_CLUSTER_NAME \
      --namespace=kube-system \
      --name=aws-load-balancer-controller \
      --role-name AmazonEKSLoadBalancerControllerRole \
      --attach-policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
      --approve \
      --region $AWS_REGION
  4. Install the controller.

    helm repo add eks https://aws.github.io/eks-charts
    helm repo update eks
    helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
      -n kube-system \
      --set clusterName=$EKS_CLUSTER_NAME \
      --set serviceAccount.create=false \
      --set serviceAccount.name=aws-load-balancer-controller
  5. Verify that the controller is running.

    kubectl -n kube-system rollout status deployment/aws-load-balancer-controller

Step 2: Set up AWS IAM permissions

The Solo Enterprise for agentregistry server needs IAM permissions to deploy agents and MCP servers to AWS Bedrock AgentCore on your behalf. The permissions are split across two policies: one takes a broad approach to cover all the infrastructure services the registry server uses (EC2, S3, CloudWatch, and more), and a second grants explicit, targeted access to the Bedrock AgentCore APIs and their direct dependencies. In this step, you create both managed IAM policies and then attach them to either a dedicated IAM user or an IAM role, depending on your chosen authentication method.

Choose between two AWS authentication methods:

  • IAM user credentials: Use long-lived AWS credentials with a static IAM access key and secret to authenticate with AWS. The registry server uses these credentials to later deploy agents to AWS Bedrock AgentCore runtimes. This setup is simpler, but not recommended for production.
  • EKS Pod Identity: Use EKS Pod Identity to inject short-lived, rotating credentials directly into the registry server pod that can be used to authenticate with AWS and deploy agents to AWS Bedrock AgentCore. This setup does not require secrets that are stored in your Kubernetes cluster and is therefore recommended for production.
  1. Create the general access policy document.

    This policy allows all AWS actions except IAM, Organizations, and Account management. The registry server needs broad access to several AWS APIs to manage agent infrastructure, including EC2 to create managed gateways, S3 for artifact storage, CloudWatch for logs, AppConfig for Solo Enterprise for agentgateway configuration, and more. The NotAction block ensures that IAM management actions are excluded, so the policy cannot be used to create, modify, or delete roles and policies. For more information about the required AWS components and how they relate to each other, see Runtime architectures.

    cat > general-access-policy.json << 'EOF'
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "NotAction": [
            "iam:*",
            "organizations:*",
            "account:*"
          ],
          "Resource": "*"
        },
        {
          "Effect": "Allow",
          "Action": [
            "account:GetAccountInformation",
            "account:GetGovCloudAccountInformation",
            "account:GetPrimaryEmail",
            "account:ListRegions",
            "iam:CreateServiceLinkedRole",
            "iam:DeleteServiceLinkedRole",
            "iam:ListRoles",
            "organizations:DescribeEffectivePolicy",
            "organizations:DescribeOrganization"
          ],
          "Resource": "*"
        }
      ]
    }
    EOF
  2. Create the Bedrock AgentCore access policy document.

    This policy grants the registry server explicit, targeted access to the Bedrock AgentCore APIs and the AWS services that AgentCore requires when the registry deploys and runs agents and MCP servers.

    cat > bedrock-agentcore-policy.json << 'EOF'
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "BedrockAgentCoreFullAccess",
          "Effect": "Allow",
          "Action": ["bedrock-agentcore:*"],
          "Resource": "arn:aws:bedrock-agentcore:*:*:*"
        },
        {
          "Sid": "IAMListAccess",
          "Effect": "Allow",
          "Action": [
            "iam:GetRole",
            "iam:GetRolePolicy",
            "iam:ListAttachedRolePolicies",
            "iam:ListRolePolicies",
            "iam:ListRoles"
          ],
          "Resource": "arn:aws:iam::*:role/*"
        },
        {
          "Sid": "BedrockAgentCorePassRoleAccess",
          "Effect": "Allow",
          "Action": "iam:PassRole",
          "Resource": "arn:aws:iam::*:role/*BedrockAgentCore*",
          "Condition": {
            "StringEquals": {
              "iam:PassedToService": "bedrock-agentcore.amazonaws.com"
            }
          }
        },
        {
          "Sid": "SecretsManagerAccess",
          "Effect": "Allow",
          "Action": [
            "secretsmanager:CreateSecret",
            "secretsmanager:PutSecretValue",
            "secretsmanager:GetSecretValue",
            "secretsmanager:DeleteSecret"
          ],
          "Resource": "arn:aws:secretsmanager:*:*:secret:bedrock-agentcore*"
        },
        {
          "Sid": "BedrockAgentCoreKMSReadAccess",
          "Effect": "Allow",
          "Action": ["kms:ListKeys", "kms:DescribeKey"],
          "Resource": ["arn:aws:kms:*:*:key/*"],
          "Condition": {
            "StringEquals": { "aws:ResourceAccount": "${aws:PrincipalAccount}" }
          }
        },
        {
          "Sid": "BedrockAgentCoreKMSAccess",
          "Effect": "Allow",
          "Action": ["kms:Decrypt", "kms:GenerateDataKey", "kms:ListGrants"],
          "Resource": ["arn:aws:kms:*:*:key/*"],
          "Condition": {
            "StringEquals": { "aws:ResourceAccount": "${aws:PrincipalAccount}" },
            "ForAnyValue:StringEquals": { "aws:CalledVia": ["bedrock-agentcore.amazonaws.com"] }
          }
        },
        {
          "Sid": "BedrockAgentCoreKMSGrantsAccess",
          "Effect": "Allow",
          "Action": ["kms:CreateGrant"],
          "Resource": ["arn:aws:kms:*:*:key/*"],
          "Condition": {
            "StringEquals": { "kms:GrantConstraintType": "EncryptionContextSubset" },
            "StringLike": {
              "kms:ViaService": ["bedrock-agentcore.*.amazonaws.com"],
              "kms:EncryptionContext:aws:bedrock-agentcore-gateway:arn": "arn:aws:bedrock-agentcore:*:*:gateway/*"
            },
            "ForAllValues:StringEquals": { "kms:GrantOperations": ["Decrypt", "GenerateDataKey"] }
          }
        },
        {
          "Sid": "BedrockAgentCoreS3Access",
          "Effect": "Allow",
          "Action": ["s3:GetObject"],
          "Resource": ["arn:aws:s3:::bedrock-agentcore-gateway-*"],
          "Condition": {
            "StringEquals": {
              "aws:CalledViaLast": "bedrock-agentcore.amazonaws.com",
              "s3:ResourceAccount": "${aws:PrincipalAccount}"
            }
          }
        },
        {
          "Sid": "BedrockAgentCoreGatewayLambdaAccess",
          "Effect": "Allow",
          "Action": ["lambda:ListFunctions"],
          "Resource": ["arn:aws:lambda:*:*:*"]
        },
        {
          "Sid": "BedrockAgentCoreGatewayApiGateway",
          "Effect": "Allow",
          "Action": ["apigateway:GET"],
          "Resource": ["arn:aws:apigateway:*::/restapis/*/stages/*/exports/*"]
        },
        {
          "Sid": "LoggingAccess",
          "Effect": "Allow",
          "Action": [
            "logs:Get*", "logs:List*", "logs:StartQuery", "logs:StopQuery",
            "logs:Describe*", "logs:TestMetricFilter", "logs:FilterLogEvents"
          ],
          "Resource": [
            "arn:aws:logs:*:*:log-group:/aws/bedrock-agentcore/*",
            "arn:aws:logs:*:*:log-group:/aws/application-signals/data:*",
            "arn:aws:logs:*:*:log-group:aws/spans:*"
          ]
        },
        {
          "Sid": "ObservabilityReadOnlyPermissions",
          "Effect": "Allow",
          "Action": [
            "application-autoscaling:DescribeScalingPolicies",
            "application-signals:BatchGet*", "application-signals:Get*", "application-signals:List*",
            "autoscaling:Describe*",
            "cloudwatch:BatchGet*", "cloudwatch:Describe*", "cloudwatch:GenerateQuery",
            "cloudwatch:Get*", "cloudwatch:List*",
            "oam:ListSinks",
            "rum:BatchGet*", "rum:Get*", "rum:List*",
            "synthetics:Describe*", "synthetics:Get*", "synthetics:List*",
            "xray:BatchGet*", "xray:Get*", "xray:List*",
            "xray:StartTraceRetrieval", "xray:CancelTraceRetrieval",
            "logs:DescribeLogGroups", "logs:StartLiveTail", "logs:StopLiveTail"
          ],
          "Resource": "*"
        },
        {
          "Sid": "TransactionSearchXRayPermissions",
          "Effect": "Allow",
          "Action": [
            "xray:GetTraceSegmentDestination", "xray:UpdateTraceSegmentDestination",
            "xray:GetIndexingRules", "xray:UpdateIndexingRule"
          ],
          "Resource": "*"
        },
        {
          "Sid": "TransactionSearchLogGroupPermissions",
          "Effect": "Allow",
          "Action": [
            "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutRetentionPolicy"
          ],
          "Resource": [
            "arn:aws:logs:*:*:log-group:/aws/application-signals/data:*",
            "arn:aws:logs:*:*:log-group:aws/spans:*"
          ]
        },
        {
          "Sid": "TransactionSearchLogsPermissions",
          "Effect": "Allow",
          "Action": ["logs:DescribeResourcePolicies", "logs:PutResourcePolicy"],
          "Resource": ["*"],
          "Condition": {
            "StringEquals": { "aws:ResourceAccount": "${aws:PrincipalAccount}" }
          }
        },
        {
          "Sid": "TransactionSearchApplicationSignalsPermissions",
          "Effect": "Allow",
          "Action": ["application-signals:StartDiscovery"],
          "Resource": "*"
        },
        {
          "Sid": "CloudWatchApplicationSignalsCreateServiceLinkedRolePermissions",
          "Effect": "Allow",
          "Action": "iam:CreateServiceLinkedRole",
          "Resource": "arn:aws:iam::*:role/aws-service-role/application-signals.cloudwatch.amazonaws.com/AWSServiceRoleForCloudWatchApplicationSignals",
          "Condition": {
            "StringLike": { "iam:AWSServiceName": "application-signals.cloudwatch.amazonaws.com" }
          }
        },
        {
          "Sid": "CloudWatchApplicationSignalsGetRolePermissions",
          "Effect": "Allow",
          "Action": "iam:GetRole",
          "Resource": "arn:aws:iam::*:role/aws-service-role/application-signals.cloudwatch.amazonaws.com/AWSServiceRoleForCloudWatchApplicationSignals"
        },
        {
          "Sid": "CreateBedrockAgentCoreNetworkServiceLinkedRolePermissions",
          "Effect": "Allow",
          "Action": "iam:CreateServiceLinkedRole",
          "Resource": "arn:aws:iam::*:role/aws-service-role/network.bedrock-agentcore.amazonaws.com/AWSServiceRoleForBedrockAgentCoreNetwork",
          "Condition": {
            "StringEquals": { "iam:AWSServiceName": "network.bedrock-agentcore.amazonaws.com" }
          }
        },
        {
          "Sid": "CreateBedrockAgentCoreRuntimeIdentityServiceLinkedRolePermissions",
          "Effect": "Allow",
          "Action": "iam:CreateServiceLinkedRole",
          "Resource": "arn:aws:iam::*:role/aws-service-role/runtime-identity.bedrock-agentcore.amazonaws.com/AWSServiceRoleForBedrockAgentCoreRuntimeIdentity",
          "Condition": {
            "StringEquals": { "iam:AWSServiceName": "runtime-identity.bedrock-agentcore.amazonaws.com" }
          }
        },
        {
          "Sid": "CloudWatchApplicationSignalsCloudTrailPermissions",
          "Effect": "Allow",
          "Action": ["cloudtrail:CreateServiceLinkedChannel"],
          "Resource": "arn:aws:cloudtrail:*:*:channel/aws-service-channel/application-signals/*"
        },
        {
          "Sid": "BedrockAgentCoreRuntimeS3WriteAccess",
          "Effect": "Allow",
          "Action": [
            "s3:CreateBucket", "s3:PutBucketPolicy", "s3:PutBucketVersioning", "s3:PutObject"
          ],
          "Resource": ["arn:aws:s3:::bedrock-agentcore-runtime-*"],
          "Condition": {
            "StringEquals": { "s3:ResourceAccount": "${aws:PrincipalAccount}" }
          }
        },
        {
          "Sid": "BedrockAgentCoreRuntimeS3ReadAccess",
          "Effect": "Allow",
          "Action": [
            "s3:GetObject", "s3:GetObjectVersion", "s3:ListBucket", "s3:ListBucketVersions"
          ],
          "Resource": "arn:aws:s3:::*",
          "Condition": {
            "StringEquals": { "s3:ResourceAccount": "${aws:PrincipalAccount}" }
          }
        },
        {
          "Sid": "BedrockAgentCoreRuntimeS3ListAccess",
          "Effect": "Allow",
          "Action": ["s3:ListAllMyBuckets"],
          "Resource": "*",
          "Condition": {
            "StringEquals": { "s3:ResourceAccount": "${aws:PrincipalAccount}" }
          }
        },
        {
          "Sid": "BedrockAgentCoreRuntimeECRAccess",
          "Effect": "Allow",
          "Action": ["ecr:DescribeRepositories", "ecr:DescribeImages", "ecr:ListImages"],
          "Resource": ["arn:aws:ecr:*:*:repository/*"]
        },
        {
          "Sid": "AgentCoreEvaluationCloudWatchLogCreate",
          "Effect": "Allow",
          "Action": ["logs:CreateLogGroup"],
          "Resource": ["arn:aws:logs:*:*:log-group:/aws/bedrock-agentcore/evaluations/*"]
        },
        {
          "Sid": "AgentCoreEvaluationCloudWatchLogIndexAccess",
          "Effect": "Allow",
          "Action": ["logs:PutIndexPolicy", "logs:DescribeIndexPolicies"],
          "Resource": [
            "arn:aws:logs:*:*:log-group:aws/spans",
            "arn:aws:logs:*:*:log-group:aws/spans:*"
          ]
        },
        {
          "Sid": "AgentCoreEvaluationBedrockInvokeAccess",
          "Effect": "Allow",
          "Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
          "Resource": [
            "arn:aws:bedrock:*::foundation-model/*",
            "arn:aws:bedrock:*:*:inference-profile/*"
          ]
        },
        {
          "Sid": "AgentCoreEvaluationLambdaAccess",
          "Effect": "Allow",
          "Action": ["lambda:InvokeFunction", "lambda:GetFunction"],
          "Resource": "arn:aws:lambda:*:*:function:*"
        }
      ]
    }
    EOF
  3. Create the managed policies in AWS IAM.

    aws iam create-policy \
      --policy-name AgentRegistryGeneralAccess \
      --policy-document file://general-access-policy.json
    
    aws iam create-policy \
      --policy-name AgentRegistryBedrockAgentCoreAccess \
      --policy-document file://bedrock-agentcore-policy.json
  4. Attach the policies to your IAM principal. Choose the AWS authentication method that you want to use.

    1. Create a dedicated IAM user for Solo Enterprise for agentregistry.

      aws iam create-user --user-name agentregistry-deployer
    2. Attach the general access policy to the user.

      aws iam attach-user-policy \
        --user-name agentregistry-deployer \
        --policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AgentRegistryGeneralAccess
    3. Attach the Bedrock AgentCore access policy to the user.

      aws iam attach-user-policy \
        --user-name agentregistry-deployer \
        --policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AgentRegistryBedrockAgentCoreAccess
    4. Create an access key for the user and save the credentials as environment variables.

      ACCESS_KEY_OUTPUT=$(aws iam create-access-key --user-name agentregistry-deployer)
      export AWS_ACCESS_KEY_ID=$(echo $ACCESS_KEY_OUTPUT | jq -r '.AccessKey.AccessKeyId')
      export AWS_SECRET_ACCESS_KEY=$(echo $ACCESS_KEY_OUTPUT | jq -r '.AccessKey.SecretAccessKey')
      echo "AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID"
    1. Install the EKS Pod Identity agent add-on.

      aws eks create-addon \
        --cluster-name $EKS_CLUSTER_NAME \
        --addon-name eks-pod-identity-agent \
        --region $AWS_REGION
    2. Save the trust policy document that allows EKS pods to assume the role.

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

      export AGENTREGISTRY_ROLE_NAME="agentregistry-pod-identity-role"
      aws iam create-role \
        --role-name "$AGENTREGISTRY_ROLE_NAME" \
        --assume-role-policy-document file://agentregistry-trust-policy.json
      export AGENTREGISTRY_ROLE_ARN=$(aws iam get-role \
        --role-name "$AGENTREGISTRY_ROLE_NAME" \
        --query 'Role.Arn' --output text)
      echo "AGENTREGISTRY_ROLE_ARN: $AGENTREGISTRY_ROLE_ARN"
    4. Attach the general access policy to the role.

      aws iam attach-role-policy \
        --role-name "$AGENTREGISTRY_ROLE_NAME" \
        --policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AgentRegistryGeneralAccess
    5. Attach the Bedrock AgentCore access policy to the role.

      aws iam attach-role-policy \
        --role-name "$AGENTREGISTRY_ROLE_NAME" \
        --policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AgentRegistryBedrockAgentCoreAccess
    6. Associate the role with the agentregistry-enterprise service account in the agentregistry-system namespace. The EKS Pod Identity agent uses this association to inject credentials into the registry pod when it starts.

      aws eks create-pod-identity-association \
        --cluster-name "$EKS_CLUSTER_NAME" \
        --namespace agentregistry-system \
        --service-account agentregistry-enterprise \
        --role-arn "$AGENTREGISTRY_ROLE_ARN" \
        --region "$AWS_REGION"

Step 3: Install

Install Solo Enterprise for agentregistry in your EKS cluster by using Helm. Choose the tab that matches the AWS authentication method you configured in the previous step.

helm upgrade --install agentregistry \
  oci://us-docker.pkg.dev/solo-public/agentregistry-enterprise/helm/agentregistry-enterprise \
  --version 2026.8.0 \
  --namespace agentregistry-system \
  --create-namespace \
  --set licensing.createSecret=true \
  --set licensing.licenseKey=$AGENTREGISTRY_LICENSE_KEY \
  --set oidc.issuer=$KEYCLOAK_ISSUER \
  --set oidc.clientId=ar-backend \
  --set oidc.clientSecret=$AR_BACKEND_SECRET \
  --set oidc.publicClientId=ar-ui \
  --set oidc.roleClaim=Groups \
  --set oidc.superuserRole=admins \
  --set aws.enabled=true \
  --set-string aws.accountId="${AWS_ACCOUNT_ID}" \
  --set-string aws.region="${AWS_REGION}" \
  --set-string aws.accessKeyId="${AWS_ACCESS_KEY_ID}" \
  --set-string aws.secretAccessKey="${AWS_SECRET_ACCESS_KEY}" \
  --set-string "telemetry.service.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-nlb-target-type=ip" \
  --set-string "telemetry.service.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-scheme=internal" \
  --set-string "telemetry.service.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-type=external" \
  --set telemetry.service.type=LoadBalancer
helm upgrade --install agentregistry \
  oci://us-docker.pkg.dev/solo-public/agentregistry-enterprise/helm/agentregistry-enterprise \
  --version 2026.8.0 \
  --namespace agentregistry-system \
  --create-namespace \
  --set licensing.createSecret=true \
  --set licensing.licenseKey=$AGENTREGISTRY_LICENSE_KEY \
  --set oidc.issuer=$KEYCLOAK_ISSUER \
  --set oidc.clientId=ar-backend \
  --set oidc.clientSecret=$AR_BACKEND_SECRET \
  --set oidc.publicClientId=ar-ui \
  --set oidc.roleClaim=Groups \
  --set oidc.superuserRole=admins \
  --set aws.enabled=true \
  --set aws.usePodIdentity=true \
  --set-string aws.region="${AWS_REGION}" \
  --set-string "telemetry.service.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-nlb-target-type=ip" \
  --set-string "telemetry.service.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-scheme=internal" \
  --set-string "telemetry.service.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-type=external" \
  --set telemetry.service.type=LoadBalancer
Helm valueDescription
licensing.createSecretSet to true so that the chart creates the license secret from the licensing.licenseKey value.
licensing.licenseKeyYour Solo Enterprise for agentregistry license key.
oidc.issuerThe issuer URL of your Keycloak realm. The registry uses this URL to discover the OIDC provider’s endpoints.
oidc.clientIdThe confidential backend client ID (ar-backend). Used to validate incoming user tokens.
oidc.clientSecretThe client secret for the ar-backend client.
oidc.publicClientIdThe public client ID for the browser-based UI (ar-ui). The server uses this client to log in to the UI.
oidc.roleClaimThe JWT claim that contains role or group names. Must match the Token Claim Name in the group mapper (Groups).
oidc.superuserRoleThe group name that grants full admin access (admins).
aws.enabledEnables the AWS integration in the registry server. Required for all EKS installs.
aws.accountIdYour AWS account ID. Required with the IAM user credentials option.
aws.regionThe AWS region where AgentCore resources are deployed.
aws.accessKeyId / aws.secretAccessKeyStatic IAM user credentials for the agentregistry-deployer user. Use only with the IAM user credentials option.
aws.usePodIdentityWhen true, the chart skips creating an AWS credentials Secret and relies on credentials injected by the EKS Pod Identity agent. Use only with the EKS Pod Identity option.
telemetry.service.annotationsAnnotations that configure an internal NLB with IP-based target routing so that agents deployed in your VPC can reach the OTel collector.
telemetry.service.typeExposes the OTel collector as a LoadBalancer service backed by the NLB.

Step 4: Verify

Verify that the Solo Enterprise for agentregistry pods are up and running.

kubectl get pods -n agentregistry-system

Example output:

NAME                                                            READY   STATUS    RESTARTS   AGE
agentregistry-clickhouse-shard0-0                               1/1     Running   0          51s
agentregistry-enterprise-postgresql-764898cbff-l8477            1/1     Running   0          51s
agentregistry-enterprise-server-7d56d5b698-zxj8k                1/1     Running   0          51s
agentregistry-enterprise-telemetry-collector-6ff77cbc4f-fgzwk   1/1     Running   0          51s

Step 5: Access the registry

Port-forward the Solo Enterprise for agentregistry server on port 12121. The registry service is not exposed externally by default, so port-forwarding is required to reach it from your local machine. The arctl CLI and the UI both default to http://localhost:12121 as the registry endpoint.

kubectl -n agentregistry-system port-forward svc/agentregistry-enterprise-server 12121:12121

Open the Solo Enterprise for agentregistry UI and log in with the admin-user username and password password. Verify that you see the dashboard.

Step 6: Install the arctl CLI

The arctl CLI is the primary tool for managing AI artifacts in Solo Enterprise for agentregistry. You use it to create, publish, and deploy AI artifacts. Before you can run any arctl commands, you must authenticate the CLI with Keycloak to obtain a valid access token.

  1. Download and install the arctl CLI.

    curl -sSL https://storage.googleapis.com/agentregistry-enterprise/install.sh | ARCTL_VERSION=v2026.8.0 sh
    export PATH=$HOME/.arctl/bin:$PATH
  2. 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)

  3. Verify that you can run arctl commands.

    arctl user whoami

    Example output:

    FIELD       VALUE
    Subject     8d7ffd9c-1f75-459a-b900-bfa4f5e3b492
    Email       admin-user@example.com
    Issuer      http://172.18.0.10:8080/realms/agentregistry
    Superuser   true (overrides role-based permission checks)
    
    ROLE     STATUS
    admins   no explicit permissions configured
    

    Note

    If you see 401 errors in the CLI, you might have previously stored a token in the ARCTL_API_TOKEN environment variable. This environment variable takes precedence over the token that you obtain via the CLI login flow. Try running unset ARCTL_API_TOKEN. Then, repeat the CLI login flow.

Next steps