> ## Documentation Index
> Fetch the complete documentation index at: https://agentstack.beeai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Stack Deployment Guide

> Deploying Agent Stack

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:

| Category            | Requirement                                      |
| ------------------- | ------------------------------------------------ |
| **Kubernetes**      | Version 1.24+ with admin access                  |
| **Tooling**         | Helm 3.8+ and kubectl configured                 |
| **Storage**         | 20GB+ available for PostgreSQL                   |
| **Providers**       | API access for LLMs (OpenAI, Anthropic, etc.)    |
| **Agent Stack CLI** | Agent Stack CLI installed for post-deploy config |

<Tip>
  **OpenShift Users**: Use the [OpenShift
  CLI](https://docs.redhat.com/en/documentation/openshift_container_platform/4.20/html/cli_tools/openshift-cli-oc) for login and administration.
</Tip>

## 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.

```shell theme={null}
# 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](#configuration-options) section.

```yaml theme={null}
# 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.

```shell theme={null}
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:

```shell theme={null}
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):

```shell theme={null}
# 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:

```shell theme={null}
agentstack list
agentstack run chat hi
```

## Configuration Options

### Authentication & Security Settings

| Option               | Description                                                |
| -------------------- | ---------------------------------------------------------- |
| **Disabled**         | No security. Simplest for isolated testing.                |
| **Basic Auth**       | Simple username/password (adminPassword).                  |
| **Bundled Keycloak** | OIDC using an internal instance of Keycloak.               |
| **External OIDC**    | Integration with existing Auth0, Okta, or Enterprise IDPs. |

<Warning>
  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.
</Warning>

#### Disable Authentication

For local testing environments without authentication.

```yaml theme={null}
# CAUTION: INSECURE, for testing only
auth:
  enabled: false
```

#### Basic Authentication

A straightforward method requiring an admin password for certain endpoints.

```yaml theme={null}
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`.

```yaml theme={null}
trustProxyHeaders: true # This is important if validate_audience is enabled

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
  # Internal URL used by the server for token validation (default shown)
  internalIssuerUrl: "http://keycloak:8336/realms/agentstack"
  # Public URL used by the browser
  publicIssuerUrl: "https://keycloak.example.com/realms/agentstack"
```

#### External OIDC Provider

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

```yaml theme={null}
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
```

<Warning>
  **Critical: Endpoint Exposure**

  If using OIDC (Bundled or External), you must expose the following endpoints publicly via [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/), [Gateway API](https://kubernetes.io/docs/concepts/services-networking/gateway/), [OpenShift Routes](https://docs.redhat.com/en/documentation/openshift_container_platform/4.20/html/ingress_and_load_balancing/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.
</Warning>

### Accessing & Configuring Keycloak

* **Local Access**: kubectl port-forward `svc/agentstack-keycloak 8336:8336` -> Access at `http://localhost:8336`
* **Production Access:** Create an [Ingress](https://kubernetes.io/docs/concepts/services-networking/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.).

<Warning>
  **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.
</Warning>

<Accordion title="Keycloak Architecture & Roles">
  The Agent Stack Keycloak integration is automatically provisioned with the following architecture:

  **Realm:** `agentstack`

  **Clients:**

  * `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.
</Accordion>

## Exposing the Platform

To move beyond local port-forwarding, you must expose the following services using [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) or [OpenShift Routes](https://docs.redhat.com/en/documentation/openshift_container_platform/4.20/html/ingress_and_load_balancing/configuring-routes).

| Service                         | Internal Target         | Purpose                                                   |
| ------------------------------- | ----------------------- | --------------------------------------------------------- |
| <b>UI Endpoint</b>              | `agentstack-ui-svc`     | Access to the web interface (includes API proxy).         |
| <b>API Endpoint (optional)</b>  | `agentstack-server-svc` | Direct server API access; Required for CLI usage.         |
| <b>Auth Endpoint (optional)</b> | `agentstack-keycloak`   | Required 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:

```yaml theme={null}
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.

```yaml theme={null}
initContainers.createVectorDbExtension=false
```

Then make sure the following SQL statements were executed in your database:

```sql theme={null}
-- 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:

```yaml theme={null}
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:**

```yaml theme={null}
redis:
  enabled: true
```

**External Redis:**

To use an external Redis instance, ensure the built-in subchart is disabled (default) and provide connection details:

```yaml theme={null}
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.

```yaml theme={null}
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
```

<Warning>
  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.
</Warning>

### 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.

```yaml theme={null}
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.

```yaml theme={null}
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)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) and [GitHub Apps](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps). This configuration enables the build engine to clone your source code.

```yaml theme={null}
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.

```yaml theme={null}
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.

```yaml theme={null}
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](#private-image-registries)
* GitHub credentials to access private or enterprise GitHub repositories (optional)
* External cluster for better security (optional)

```yaml theme={null}
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
    #   ...
```

<Warning>
  **OpenShift Users**: In-cluster builds require a service account with the appropriate [Security Context Constraints (SCC)](https://www.redhat.com/en/blog/managing-sccs-in-openshift) to allow the elevated permissions necessary for container image construction.
</Warning>

## 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](https://github.com/i-am-bee/agentstack/blob/v0.4.3/helm/values.yaml) 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.

| Task               | Command                                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| Upgrade Platform   | `helm upgrade --install agentstack -f config.yaml oci://ghcr.io/i-am-bee/agentstack/chart/agentstack:<version>` |
| View Active Config | `helm get values agentstack`                                                                                    |
| Deployment Status  | `helm status agentstack`                                                                                        |
| Resource Health    | `kubectl get pods` , `kubectl logs deployment/agentstack-server`                                                |
| Uninstall          | `helm 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:**

```bash theme={null}
# 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.
