Skip to main content
This guide walks you through running Agent Stack in your own self-hosted environment so you can evaluate, develop, and integrate agents as backend services. Agent Stack provides a consistent runtime for agents—handling model access, storage, authentication, and service wiring—so teams can move from agent code to a running service with minimal setup. Agent Stack deploys with Kubernetes via our provided Helm chart, ensuring a standardized setup within your infrastructure. Agent Stack is designed for trusted environments and early-stage integration work. It’s well suited for local development, shared team environments, and internal evaluation. It is not intended to be directly exposed to untrusted public traffic or used as a hardened, multi-tenant production platform today. If you’re evaluating Agent Stack for broader organizational use, deploy it behind your existing network and security boundaries. If you’re an application or agent developer, this guide helps you get agents running in your deployment environment and callable from your application. If you’re part of a platform or IT team, this guide provides a concrete runtime to assess how agent services run inside your infrastructure using our Helm-based deployment, how they integrate with your security and observability tooling, and how they fit your deployment standards. Proceed to the installation guide below to configure your environment and deploy the Agent Stack cluster.

Requirements

Before deployment, ensure your environment meets these specifications:
CategoryRequirement
KubernetesVersion 1.24+ with admin access
ToolingHelm 3.8+ and kubectl configured
Storage20GB+ available for PostgreSQL
ProvidersAPI access for LLMs (OpenAI, Anthropic, etc.)
Agent Stack CLIAgent Stack CLI installed for post-deploy config
OpenShift Users: Use the OpenShift CLI for login and administration.

Deployment Steps

1. Generate Encryption Key

Agent Stack requires an encryption key for secure data handling. Generate this using Python before creating your configuration file.
# Option A: Using UV
uv run --with cryptography python3 -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())'

# Option B: Using python3 directly
python3 -m pip install cryptography
python3 -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())'

# Option C: use your preferred way to install the cryptography package

2. Create Configuration File

Create a config.yaml file to define your registry, agents, and security keys. This is a minimal example, more advanced options are explained in the Configuration Options section.
# External registries for default catalogs (change release/tag accordingly):
externalRegistries:
  public_github: "https://github.com/i-am-bee/agentstack@v0.4.3#path=agent-registry.yaml"

# Custom agents as docker images
providers:
  - location: <docker-image-id>
  # e.g. location: ghcr.io/i-am-bee/agentstack-starter/my-agent:latest

# Use the key generated in Step 1
encryptionKey: "encryption-key-from-command"

# Basic authentication settings requires passing an admin password to certain endpoints, you can disable auth for insecure deployments
auth:
  enabled: true
  basic:
    enabled: true
    adminPassword: "my-secret-password"

3. Install the Chart

Deploy the stack to your cluster using Helm.
helm upgrade --install agentstack -f config.yaml oci://ghcr.io/i-am-bee/agentstack/chart/agentstack:0.4.3
It may take a few minutes for the pods to start.

4. Port-Forwarding

By default, ingress is not configured. You can port-forward the service to access the platform. In a separate terminal, run:
kubectl port-forward svc/agentstack-svc 8333:8333 &

5. Setup the LLM

After the platform becomes ready, set up your model provider (and login if auth is enabled):
# agentstack server login (if auth is enabled)
agentstack model setup

6. Test the Deployment

Verify the installation by listing available agents and running a test command:
agentstack list
agentstack run chat hi

Configuration Options

Authentication & Security Settings

OptionDescription
DisabledNo security. Simplest for isolated testing.
Basic AuthSimple username/password (adminPassword).
Bundled KeycloakOIDC using an internal instance of Keycloak.
External OIDCIntegration with existing Auth0, Okta, or Enterprise IDPs.
The current authentication model is basic and intended for development use. For any deployment beyond local testing, carefully consider your security requirements and network access controls.

Disable Authentication

For local testing environments without authentication.
# CAUTION: INSECURE, for testing only
auth:
  enabled: false

Basic Authentication

A straightforward method requiring an admin password for certain endpoints.
trustProxyHeaders: true # This is important if validate_audience is enabled

auth:
  enabled: true
  basic:
    enabled: true
    adminPassword: "my-secret-password"

Bundled Keycloak (Default OIDC)

Use an internal Keycloak instance to handle OIDC and bridge to GitHub, Google, or SAML. Keycloak is deployed automatically when auth.enabled is true.
auth:
  enabled: true

  # Next.js settings
  nextauthUrl: "https://example.com" # Public URL of the UI
  apiUrl: "https://api.example.com" # Public URL of the API
  
keycloak:
  enabled: true
  publicIssuerUrl: "https://keycloak.example.com/realms/agentstack" # Public URL of keycloak

External OIDC Provider

Connect your own OIDC provider (e.g., Auth0, Okta, or your own Keycloak) by disabling the bundled Keycloak.
auth:
  enabled: true

  # Next.js settings
  nextauthUrl: "https://example.com" # Public URL of the UI
  apiUrl: "https://api.example.com" # Public URL of the API

keycloak:
  enabled: false

externalOidcProvider:
  issuerUrl: "https://your-oidc-provider.com"
  name: "My IDP" # Optional display name used in the UI
  id: "my-idp" # Optional ID used internally
  rolesPath: "realm_access.roles" # JSON path to roles in JWT claims (can be an array or a semicolon separated string)
  
  uiClientId: "agentstack-ui"
  serverClientId: "agentstack-server"
  
  # Secrets can be provided directly or via existing secrets
  uiClientSecret: "..." 
  serverClientSecret: "..."
  # existingSecret: "my-oidc-secret"
  # uiClientSecretKey: "ui-secret-key"         # Key in my-oidc-secret
  # serverClientSecretKey: "server-secret-key" # Key in my-oidc-secret
Critical: Endpoint ExposureIf using OIDC (Bundled or External), you must expose the following endpoints publicly via Ingress, Gateway API, OpenShift Routes, or other tools:
  • UI: https://example.com
  • API: https://api.example.com used by the CLI to authenticate
  • Keycloak: https://keycloak.example.com used by the UI and CLI to authenticate
⚠️ Failure to configure these endpoints with proper https may leave your application vulnerable.

Accessing & Configuring Keycloak

  • Local Access: kubectl port-forward svc/agentstack-keycloak 8336:8336 -> Access at http://localhost:8336
  • Production Access: Create an Ingress for the agentstack-keycloak service.
  • Setup: Log in (default credentials: admin / retrieve from secret). -> navigate to Identity Providers -> add your provider (GitHub, Google, etc.).
Email Verification Required:Agent Stack requires the email_verified claim to be true in JWT tokens. Ensure:
  • Users verify emails before authenticating
  • The email_verified claim is mapped to the token (included by default in the email scope)
  • External providers pass the email verification status correctly
Without verified emails, authentication will fail with “Verified email not found” error.
The Agent Stack Keycloak integration is automatically provisioned with the following architecture:Realm: agentstackClients:
  • agentstack-server: Backend service client (Confidential, Service Accounts enabled).
  • agentstack-ui: Frontend UI client (Confidential, Standard Flow).
  • agentstack-cli: Command Line Interface client (Public, Standard Flow).
Roles:
  • agentstack-admin: Full system access.
  • agentstack-developer: Access to agent management.
Audiences:
  • Audience mappers are dynamically configured to ensure tokens are valid for the UI and API URLs defined in your config.

Exposing the Platform

To move beyond local port-forwarding, you must expose the following services using Ingress or OpenShift Routes.
ServiceInternal TargetPurpose
UI Endpointagentstack-ui-svcAccess to the web interface (includes API proxy).
API Endpoint (optional)agentstack-server-svcDirect server API access; Required for CLI usage.
Auth Endpoint (optional)agentstack-keycloakRequired for UI and CLI authentication if using Keycloak.

Configuring External Services & Storage

By default, Agent Stack includes PostgreSQL and SeaweedFS (S3-compatible storage). For production environments, it is highly recommended to use external, managed services.

External PostgreSQL

To use an external PostgreSQL instance, disable the built-in subchart and provide connection details. This is required if you prefer a managed database like AWS RDS or Google Cloud SQL. Example configuration:
postgresql:
  enabled: false # disable builtin subchart
externalDatabase:
  host: "<your-postgres-host>"
  port: 5432
  user: "<your-postgres-user>"
  database: "<your-postgres-database>"
  password: "<your-postgres-password>"
  # Required when initContainers.createVectorDbExtension is enabled
  adminUser: "<postgres-admin-user>"
  adminPassword: "<postgres-admin-password>"
  ssl: true
  sslRootCert: ""
  # SSL certificate for the external database to ensure ssl connection, for example:
  # sslRootCert: |
  #   -----BEGIN CERTIFICATE-----
  #   ...
  #   -----END CERTIFICATE-----
If the migration fails while installing the vector extension, you can disable automated creation and run the SQL manually.
initContainers.createVectorDbExtension=false
Then make sure the following SQL statements were executed in your database:
-- Manual SQL setup for External DB
CREATE EXTENSION IF NOT EXISTS vector;
SET maintenance_work_mem = '512MB';
SET hnsw.ef_search = 1000;
SET hnsw.iterative_scan = strict_order;
SET hnsw.max_scan_tuples = 1000000;

External S3 support

You may want to have Agent Stack connect to an external object storage rather than installing seaweedfs inside your cluster. This chart allows you to specify credentials for an external storage streaming with the externalS3. You should also disable the seaweedfs installation with the seaweedfs.enabled option. Example configuration:
seaweedfs:
    enabled: false
externalS3:
    host: <your-s3-host>
    accessKeyID: <your-s3-access-key>
    accessKeySecret: <your-s3-access-key-secret>

Redis

Redis is used for rate limiting and caching. While disabled by default, it is required if replicaCount > 1 to ensure counters are synchronized across replicas. Enable Built-in Redis:
redis:
  enabled: true
External Redis: To use an external Redis instance, ensure the built-in subchart is disabled (default) and provide connection details:
redis:
  enabled: false
externalRedis:
  host: "<your-redis-host>"
  port: 6379
  password: "<your-redis-password>"
  # Optional: use existing secret for password
  # existingSecret: "my-redis-secret"
  # existingSecretPasswordKey: "redis-password"

Security and Traffic Control

Rate Limiting

Rate limiting is recommended for production environments as a protection against overloading the platform.
rateLimit:
  enabled: true
  globalLimits:
    - "20/second"
    - "100/minute"
  roleBasedLimits:
    user:
      openai_chat_completion_tokens: []
      openai_chat_completion_requests: []
      openai_embedding_inputs: []
    developer:
      openai_chat_completion_tokens: []
      openai_chat_completion_requests: []
      openai_embedding_inputs: []
    admin:
      openai_chat_completion_tokens: []
      openai_chat_completion_requests: []
      openai_embedding_inputs: []
  strategy: "sliding-window-counter" # Options: fixed-window, moving-window, sliding-window-counter
If you are running multiple replicas (replicaCount > 1), Redis is required for rate limiting to work correctly across all instances. Without Redis, each replica maintains its own rate limit counters, allowing users to exceed limits by distributing requests across replicas.

Cross-Origin Resource Sharing Configuration

Agent Stack supports Cross-Origin Resource Sharing (CORS) to allow web applications hosted on different domains to interact with the Agent Stack API.
cors:
  enabled: true
  allowOrigins:
    - http://localhost:3000
    - https://my-ui.example.com
  allowMethods:
    - GET
    - POST
    - PUT
    - DELETE
    - OPTIONS
  allowHeaders:
    - Content-Type
    - Authorization
  allowCredentials: true
  • cors.enabled: Set to true to enable CORS. Default is false.
  • cors.allowOrigins: A list of origins (e.g., http://localhost:3000) that are allowed to make cross-site requests to the Agent Stack API.
  • cors.allowMethods: A list of HTTP methods (e.g., GET, POST) that are allowed for cross-origin requests. Default is ["*"].
  • cors.allowHeaders: A list of HTTP request headers (e.g., Content-Type, Authorization) that can be used when making the actual cross-origin request. Default is ["*"].
  • cors.allowCredentials: Set to true to indicate that the client can send cookies and HTTP authentication credentials with the cross-origin request. Note that allowOrigins cannot be ["*"] when allowCredentials is true. Default is false.

Agent Management

To manage agents within Agent Stack, you must configure how the platform accesses existing images, how it registers them for use, and how it builds new agents from source code.

Configuring Private Access

If your agent images or source code are hosted in private environments, you must provide authentication credentials to allow the cluster to retrieve them.

Private Image Registries

When using agents stored in private Docker registries, you must specify the name of a Kubernetes custom-registry-secret. This allows the cluster to pull the images during deployment.
imagePullSecrets:
  - name: custom-registry-secret

Private GitHub Repositories

For building agents from private or Enterprise GitHub repositories, Agent Stack supports both Personal Access Token (PAT) and GitHub Apps. This configuration enables the build engine to clone your source code.
github:
  auths:
    github.com:
      type: "pat"
      token: "ghp_xxxxxxxxxxxxxxxxxxxx"
    github.enterprise.com:
      type: "app"
      app_id: 123456
      installation_id: 789012
      private_key: |
        -----BEGIN RSA PRIVATE KEY-----
        MIIEpAIBAAKCAQEA...
        -----END RSA PRIVATE KEY-----

Agent Registration

Once access is configured, you must define which agents are available to the platform. You can do this by listing specific images or by syncing with a remote catalog.

Static Agent Registration

Use this method to manually define specific agent images and their unique environment variables.
providers:
  # Official agents
  - location: ghcr.io/i-am-bee/agentstack/agents/chat:0.4.3
  - location: ghcr.io/i-am-bee/agentstack/agents/rag:0.4.3
  - location: ghcr.io/i-am-bee/agentstack/agents/form:0.4.3

  # Your custom agents
  - location: your-registry.com/your-team/custom-agent:v1.0.0
    auto_stop_timeout_sec: 0 # disable agent downscaling
    # Variables should be strings (or they will be converted)
    variables:
      MY_API_KEY: "sk-..."
      MY_CONFIG_VAR: "42"
To upgrade an agent, change its version tag and redeploy using helm upgrade.

External Agent Registry

Instead of manual listing, you can point to a remote registry file. This is ideal for teams managing a large, dynamic catalog of agents.
externalRegistries:
  public_github: "https://github.com/i-am-bee/agentstack@v0.4.3#path=agent-registry.yaml"
To upgrade an agent, change its version in the registry and wait for automatic synchronization (up to 10 minutes).

Agent Builds

Agents can be built from a GitHub repository directly in the cluster. To enable this feature, you will need to setup a few things:
  • Docker image registry credentials with write permissions, see Private image registries
  • GitHub credentials to access private or enterprise GitHub repositories (optional)
  • External cluster for better security (optional)
providerBuilds:
  enabled: true
  buildBackend: "kaniko" # valid options: [kaniko, buildkit]
  buildRegistry:
    registryPrefix: "ghcr.io/github-org-name"
    imageFormat: "{registry_prefix}/{org}/{repo}/{path}:{commit_hash}"
    # Registry credentials with write access (see section about Private image registries below)
    secretName: "custom-registry-secret"
    insecure: false
  kaniko:
    useSecurityContextCapabilities: true
  externalClusterExecutor:
    serviceAccountName: ""
    namespace: "" # Kubernetes namespace for provider builds (defaults to current namespace if empty)
    kubeconfig: "" # Kubeconfig YAML content for external cluster (optional)
    # Example:
    # kubeconfig: |
    #   apiVersion: v1
    #   kind: Config
    #   clusters:
    #   - cluster:
    #       server: https://kubernetes.example.com
    #   ...
OpenShift Users: In-cluster builds require a service account with the appropriate Security Context Constraints (SCC) to allow the elevated permissions necessary for container image construction.

Advanced Configuration

The guide above covers the primary configuration paths for production environments. For a comprehensive list of every available parameter, including low-level resource limits, node selectors, and detailed sub-chart settings, refer to the source configuration file. All configuration options, including their default values and technical descriptions, are documented in the values.yaml file within the official repository. If your infrastructure has specific requirements (such as custom sidecars, unique volume mounts, or specific network policies) that are not currently exposed via the Helm chart, please open a GitHub issue to request a new configuration toggle.

Operations & Maintenance

Management Commands

Upgrading

Once Agent Stack is running, use these Helm and kubectl commands to manage the lifecycle of your deployment.
TaskCommand
Upgrade Platformhelm upgrade --install agentstack -f config.yaml oci://ghcr.io/i-am-bee/agentstack/chart/agentstack:<version>
View Active Confighelm get values agentstack
Deployment Statushelm status agentstack
Resource Healthkubectl get pods , kubectl logs deployment/agentstack-server
Uninstallhelm uninstall agentstack

Troubleshooting

If you encounter issues during or after deployment, use the following commands and checklists to diagnose the problem.

Common Issues

Platform not starting:
# Check pod status
kubectl get pod

# Check server logs
kubectl logs deployment/agentstack-server
# If server is not starting, check specific init container logs (e.g. migrations)
kubectl logs deployment/agentstack-server -c run-migrations

# Check events
kubectl get events --sort-by=.lastTimestamp
Authentication issues:
  • Redirect URIs: Your Identity Provider must whitelist https://<your-url>/api/auth/callback. For CLI usage, you must also whitelist http://localhost:9001/callback.
  • CLI Application: Consider creating a separate public OIDC application for the CLI
  • Audience Claim: The audience claim in your JWT must match the public URL of your application exactly, with no trailing slash (e.g., https://example.com).
  • Proxy Headers: If you are behind a load balancer or ingress, trustProxyHeaders: true must be enabled in your config to correctly forward request URLs.