Skip to content
Ankole

Quick start

How Ankole is deployed

A private Ankole deployment instance has one control plane and one or more Agent Computer Workers. The control plane is the management platform. A Worker runs Agent tasks and acts as the Agent’s work computer.

One Worker can serve several Agents. In finance or another environment that needs strict isolation, give each Agent a dedicated Worker. A work computer can be shared by several interns or assigned to one colleague.

Each instance also needs PostgreSQL and persistent disk storage. A single-host deployment can use a local or virtual disk. A Kubernetes deployment needs NFS or another shared volume that supports ReadWriteMany.

Terms used in this guide

This page defines the terms used in Ankole user documentation and interfaces. The names in parentheses match third-party platforms, configuration fields, and APIs. Later sections use the short form.

Canonical term Meaning Short form
Private deployment instance One complete Ankole system that an enterprise deploys and manages Instance
Principal A person, Agent, or system service that can have an identity and permissions in Ankole Principal
Identity Provider (IdP) An external identity source that provides Console SSO and synchronizes employees, contacts, and organization structure IdP
Chat platform An external conversation platform such as Slack, Teams, Lark/Feishu, or DingTalk Platform
Channel Provider One chat application or bot configuration that receives messages and sends Agent replies Channel Provider
Signal Routing Rule (Signal Binding) The rule that sends messages or events from a signal source to an Agent Routing rule
LLM Provider A configuration that stores a model service endpoint, credentials, and available models LLM Provider
Background Agent Jobs profile (internal key: coding) Selects the AIGateway provider and model for Background Agent Jobs; normal conversations do not select it by code volume Background Agent Jobs

Let an Agent complete the setup

You can send this prompt to Codex, Claude Code, or another Agent that can operate a terminal:

Use https://ankole.agentbull.com/en-US/docs/quickstart/ to help me deploy and configure a private Ankole deployment instance. First, inspect my environment and recommend Docker Compose, Kubernetes, or installing from source. Then help me set up the Identity Provider (IdP), LLM Provider, Agent, Channel Provider, and Signal Routing Rule (Signal Binding). If I did not specify an IdP and IM platform, ask which identity source and chat platform I want to use. Do not choose them for me. Do not expose secrets in chat or command output. You are finished only when I receive a real Agent reply in my selected IM.

1. Deploy Ankole

Use Docker Compose for one host or Kubernetes for an enterprise deployment. Install from source for development and debugging.

The best starting point for most teams. One Linux, macOS, or Windows host with Docker runs PostgreSQL, the control plane, one Agent Computer Worker, and Caddy HTTPS.

Before you start

  • A Linux, macOS, or Windows host that can run Linux amd64 or arm64 containers
  • Docker Engine with the Compose plugin, or Docker Desktop
  • Persistent disk, a DNS name, and ports 80 and 443

Basic setup

Install with Docker Compose

Keep provider API keys out of this deployment file. You will add them in the Console after sign-in.

  1. 01

    Get the deployment package

    bash
    git clone https://github.com/AgentBull/ankole.git
    cd ankole/tools/deploy/docker-compose
    cp .env.example .env
    chmod 600 .env
  2. 02

    Generate three independent secrets

    Copy and run this command. Then paste its complete output into .env.

    bash
    printf '%s\n' \
      '# PostgreSQL database password' \
      "POSTGRES_PASSWORD=$(openssl rand -hex 32)" \
      '' \
      '# ANKOLE master encryption key' \
      "ANKOLE_SECRET_BASE=$(openssl rand -hex 32)" \
      '' \
      '# Authentication key shared by the ANKOLE control plane and Agent Workers' \
      "ANKOLE_RUNTIME_FABRIC_WORKER_AUTH_KEY=$(openssl rand -hex 32)"
  3. 03

    Set the public host

    Set ANKOLE_HOST to the DNS name that points to this host. Set ACME_EMAIL to an address that can receive certificate notices.

    ANKOLE_HOST
    ankole.example.com
    The HTTPS host that people and provider callbacks will use.
    ACME_EMAIL
    ops@example.com
    Contact address for Caddy certificate management.
  4. 04

    Start and verify the stack

    Compose waits for PostgreSQL, runs migrations, stores the Worker key, and then starts the control plane, Worker, and Caddy.

    bash
    docker compose pull
    docker compose up -d
    docker compose ps
  5. 05

    Open the first setup

    Open https://<ANKOLE_HOST>/setup and enter the activation code.

    bash
    docker compose logs control-plane | grep "SETUP ACTIVATION CODE"

2. Set up the identity provider first

Ankole is designed for private deployment inside an enterprise. Each enterprise operates one instance. Inside that instance, Agents, employees, and system services are represented as Principals, and the authorization module manages their permissions.

Like Hermes Agent and OpenClaw, Ankole connects to chat channels. It also connects to the enterprise identity source so it can synchronize employees, directory contacts, and the organization structure. Configure an Identity Provider (IdP) before you configure the chat channel.

Setting What it controls Configure it where
Identity Provider (IdP) Console SSO and the employees, contacts, organization structure, and permission groups synchronized from the enterprise directory /setup first, then Console → Identity Providers
Channel Provider The IM app or bot that receives messages and sends Agent replies Console → Signal Routing

The identity source and chat channel can use different platforms. Employees can sign in through Google Workspace and talk to the Agent in Slack. Entra ID can supply identity while Lark, Slack, DingTalk, or Teams carries the conversation.

Complete the setup for your IdP

Select the identity source that your enterprise uses. Each tab starts in the provider console and ends with the first sign-in and directory sync.

If you enable the adapter for the first time, restart the control plane after the first sign-in. This restart starts the plugin background work, such as directory connections and Graph subscriptions.

Use one Slack app for Console sign-in and for workspace member and user-group sync. The default setup needs an OAuth client, a Bot Token, and an App Token.

Before you start

  • A workspace administrator who can create and install a Slack app
  • A public HTTPS address for Ankole
  • A workspace member account for the first sign-in

Basic setup

Set up the Slack IdP

  1. 01

    Copy the callback URL from Ankole

    Open https://<ANKOLE_HOST>/setup and enter the activation code. Select Slack Adapter on the plugin page, save the selection, and then select Slack.

    Keep the provider ID as slack-main. Copy the login callback URL shown on the page. Do not type or change this URL by hand.

  2. 02

    Create the Slack app

    Open Slack API Your Apps and select Create New App → From scratch. Enter an app name and select the workspace that holds your employees.

    Open Basic Information → App Credentials. Copy the Client ID and Client Secret.

  3. 03

    Register the login callback

    Open OAuth & Permissions → Redirect URLs. Select Add New Redirect URL, paste the complete URL from Ankole, and save it.

    Ankole requests the openid, profile, and email sign-in scopes by default. Do not replace them with chat bot scopes.

  4. 04

    Grant directory access and get the Bot Token

    On OAuth & Permissions, add the four scopes below under Bot Token Scopes. Then select Install to Workspace and approve the installation.

    • users:read

      Read member profiles

    • users:read.email

      Read member email addresses

    • usergroups:read

      Read user groups and their members

    • team:read

      Read basic workspace information

    Copy the Bot User OAuth Token after installation. It must start with xoxb-. Reinstall the app after each scope change.

  5. 05

    Get the App Token and enable Socket Mode

    Open Basic Information → App-Level Tokens. Select Generate Token and Scopes, add the scope below, and copy the generated xapp- token. Then open Socket Mode and turn on Enable Socket Mode.

    • connections:write

      Let the App Token open a Socket Mode connection

  6. 06

    Subscribe to directory events

    Open Event Subscriptions and enable events. Under Subscribe to bot events, add each of the five events below.

    • team_join

      A member joins the workspace

    • user_change

      A member profile changes

    • subteam_created

      A user group is created

    • subteam_updated

      A user group changes

    • subteam_members_changed

      A user-group membership changes

  7. 07

    Enter the Slack values in Ankole

    Keep Enable OIDC, Sync directory, and Realtime directory sync on. Select Save and sign in with OIDC, and then complete the Slack authorization.

    • Client ID: the Client ID from Basic Information
    • Client Secret: the Client Secret on the same page
    • Workspace ID: the T… part after /client/ in the Slack web URL; it limits sign-in and directory sync to this workspace
    • Bot Token: the xoxb- token
    • App Token: the xapp- token
  8. 08

    Verify sign-in and the first sync

    After Slack returns to Ankole, this user becomes the first root administrator. Open Console → Identity Providers, select slack-main, and select Run full sync.

    When the sync finishes, check Console → Principals and Principal groups for the workspace members and Slack user groups.

3. Add an LLM Provider and create an Agent

An Agent model profile stores a model reference, so add the LLM Provider first. Sign in to the Console. Open Providers → New provider, choose the provider kind, give it a stable Provider ID, enter the endpoint and credential fields, and save.

Provider credentials stay encrypted in the control plane. Do not put them in deployment environment files or Agent files.

Open Agents → New Agent. Give the Agent a stable UID, a clear display name, and a mission that says what it owns and what counts as an acceptable result.

Then configure its model profiles:

Profile First-run use
primary Main reasoning model
light Short and frequent work
heavy Hard synthesis

All three are required before the Agent can run. For the first conversation, you can bind the same known-good provider and model to all three. Split them only after the end-to-end path works.

4. Connect a chat channel and create its signal routing rule

Enable the chat platform’s Control Plane Plugin in the Console, and then create the bot or application on that platform. Use separate apps for the IdP and chat roles, even when both use the same platform. This separation keeps sign-in and directory permissions away from bot permissions. It also separates credential rotation and app releases.

One chat app usually represents one bot identity. If several Agents need different bot names, avatars, or permissions, create several apps on that platform. After you prepare an app, create its routing rule in the Console and connect it to the intended Agent.

Slack uses Socket Mode. Ankole opens an outbound WebSocket, so the chat path does not need a public Slack webhook.

Before you start

  • Permission to create and install a Slack app
  • A test channel or direct message

Basic setup

Prepare a Slack app

  1. 01

    Create the app and enable Socket Mode

    Create a Slack app from scratch. Under Basic Information, create an App-Level Token, add the scope below, and then enable Socket Mode.

    • connections:write

      Let the App Token open a Socket Mode connection

  2. 02

    Subscribe to the first message events

    Open Event Subscriptions → Subscribe to bot events. Add each event below.

    • app_mention

      Receive channel @-mentions

    • message.im

      Receive direct messages

  3. 03

    Grant scopes and install the app

    Under OAuth & Permissions → Bot Token Scopes, add each scope that matches the conversations you will use. The first two are required.

    • app_mentions:read

      Read channel messages that mention the bot

    • chat:write

      Send bot replies

    • channels:history

      Read public channel messages

    • groups:history

      Add when the bot must read private channels

    • im:history

      Add when the bot must read direct messages

    Install the app to the workspace after each scope change.

  4. 04

    Collect the Console fields

    botToken
    xoxb-…
    Bot User OAuth Token. The xoxb- prefix is required.
    appToken
    xapp-…
    App-Level Token for Socket Mode. The xapp- prefix is required.

Complete the connection in the Console

The current release uses a direct connection. One routing rule connects one Channel Provider to one Agent. It records the adapter, app credentials, target Agent, group-message behavior, and memory behavior. Create a separate rule for each bot.

In the Console, open Signal Routing → New routing rule and set:

Field What to choose
Target Agent The Agent you created in step 3
Adapter Slack, Teams, Lark/Feishu, or DingTalk
Rule name A stable name such as slack-main or lark-main
Group message mode Start with addressed_only
Confidential memory Leave off for the first test
Channel settings Paste the credentials and values from the channel tab

Save the rule. The list must show it as enabled. If the form rejects a credential, fix that error before testing the IM; the adapter has not opened its connection yet.

5. Talk to the Agent in the IM

Add the bot to a test conversation. For Slack, Teams, Lark/Feishu, or DingTalk group chat, start with an explicit @-mention:

@Ankole What can you do, and which team are you serving?

After the first real model reply, tune the Agent mission, models, and group-chat policy for the team.

If the Agent does not reply

Check one boundary at a time, in this order:

  1. The latest provider app version is published and available to the test user.
  2. The bot is installed in the channel, team, or conversation.
  3. The required message event and scopes are active.
  4. The routing rule is enabled and points to the intended Agent.
  5. The Agent has primary, light, and heavy model profiles.
  6. The LLM Provider credential and model selector are valid.
  7. At least one Worker is ready.

For Compose, inspect docker compose logs -f control-plane worker. For Kubernetes, inspect the control-plane and Worker pod logs. Read only the relevant error; do not print environment variables or secrets.

Once the reply arrives, continue with Agents, Signal routing rules, or Background Agent Jobs.