Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ jobs:
cache: true

- name: golangci-lint
uses: golangci/golangci-lint-action@v4
uses: golangci/golangci-lint-action@v9
with:
version: latest
# @note pinned: v1 releases are built with Go 1.24 and refuse this
# module's Go 1.25 target, and `latest` has broken the job before
version: v2.13.2

validate-examples:
name: Validate Examples
Expand Down Expand Up @@ -105,5 +107,5 @@ jobs:

- name: Run acceptance tests
env:
CHATBOTKIT_API_KEY: ${{ secrets.CHATBOTKIT_API_KEY }}
CHATBOTKIT_API_TOKEN: ${{ secrets.CHATBOTKIT_API_KEY }}
run: go test -v ./internal/provider/ -run "^TestAcc"
30 changes: 21 additions & 9 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# golangci-lint configuration
# https://golangci-lint.run/usage/configuration/
# https://golangci-lint.run/docs/configuration/

version: "2"

run:
timeout: 5m
Expand All @@ -8,19 +10,29 @@ run:
linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused

linters-settings:
errcheck:
# Check for ignored error returns in tests too
check-blank: false
gosimple:
# S1039: unnecessary use of fmt.Sprintf
checks: ["all"]
settings:
errcheck:
# Check for ignored error returns in tests too
check-blank: false
staticcheck:
# @note v2 folds gosimple (S1*) and stylecheck (ST1*) into staticcheck.
# Keep what v1 ran here: staticcheck and every gosimple check, without
# the style checks that were never enabled.
checks: ["SA*", "S1*"]

# @note v1 applied these exclusions by default, which is why idioms such as
# `defer resp.Body.Close()` passed. v2 makes them opt-in presets.
exclusions:
presets:
- comments
- common-false-positives
- legacy
- std-error-handling

issues:
# Don't limit the number of issues
Expand Down
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,43 @@ All notable changes to the ChatBotKit Terraform Provider are documented in this
file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.10.0] - 2026-09-18

### Added

- `api_token` is the new name for the provider credential. `api_key` is
deprecated and still read when `api_token` is not set. The token is read
from `CHATBOTKIT_API_TOKEN` (or `CBK_API_TOKEN`); the older
`CHATBOTKIT_API_SECRET` and `CHATBOTKIT_API_KEY` names, and their `CBK_`
forms, still work. `CBK_API_URL` is accepted as a shorthand for
`CHATBOTKIT_API_URL`. The run-as user is also read from
`CHATBOTKIT_API_RUNAS_USERID` (or `CBK_API_RUNAS_USERID`), the names the CLI
uses; `CHATBOTKIT_RUN_AS` still works and gains a `CBK_RUN_AS` shorthand.
- The provider reads the platform origin from the `CHATBOTKIT_API_URL`
environment variable when `base_url` is not set, and derives the GraphQL
endpoint from it (`http://localhost:3000` becomes
`http://localhost:3000/api/v1/graphql`). This is the same variable the SDKs'
CLI reads, so one setting points every tool at a self-hosted platform. Plain
`http` works for local use, and `base_url` still wins when configured.

### Changed

- **BREAKING (behaviour):** `chatbotkit_instagram_integration`, `chatbotkit_messenger_integration` and `chatbotkit_whatsapp_integration` gain an `app_secret` attribute (sensitive; reads are masked so the configured value is kept), and on update a missing `access_token` / `app_secret` is now sent as an explicit `null`, which clears the credential on the platform. Previously an omitted credential was silently kept - configurations that relied on that must set the value explicitly. Requires the platform release that passes credential nulls through the GraphQL update mutations.
- `chatbotkit_skillset_ability` import now takes `<skillset_id>/<ability_id>`; a bare ability id is rejected with a clear message. Reads paginate the skillset's abilities instead of stopping at the first 100.
- **BREAKING (API wire format):** the `chatbotkit_skillset_ability` resource
now sends and reads the renamed platform link fields `linkedSecretId` /
`linkedFileId` / `linkedBotId` / `linkedSpaceId` (previously `secretId` /
`fileId` / `botId` / `spaceId`) on create/update/read, and the GraphQL
`Ability` relations `linkedSecret` / `linkedFile` / `linkedBot` /
`linkedSpace` (previously `secret` / `file` / `bot` / `space`). The HCL
attribute names `secret_id`, `bot_id`, `file_id` and `space_id` are
unchanged, so existing configurations need no edits. There are no
compatibility aliases on the platform side; upgrade the provider together
with the platform deploy. A link removed outside Terraform is now cleared to
`null` in state on read.

## [1.9.0] - 2026-06-30

### Added
Expand Down
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[![ChatBotKit](https://img.shields.io/badge/credits-ChatBotKit-blue.svg)](https://chatbotkit.com)
[![CBK.AI](https://img.shields.io/badge/credits-CBK.AI-blue.svg)](https://cbk.ai)
[![Email](https://img.shields.io/badge/Email-Support-blue?logo=mail.ru)](mailto:support@chatbotkit.com)
[![Email](https://img.shields.io/badge/Email-Support-blue?logo=mail.ru)](mailto:support@cbk.ai)
[![Discord](https://img.shields.io/badge/Discord-Support-blue?logo=discord)](https://go.cbk.ai/discord)
[![Terraform Registry](https://img.shields.io/badge/Terraform-Registry-purple.svg)](https://registry.terraform.io/providers/chatbotkit/chatbotkit/latest)
[![Follow on Twitter](https://img.shields.io/twitter/follow/chatbotkit.svg?logo=twitter)](https://twitter.com/chatbotkit)
Expand Down Expand Up @@ -73,10 +72,10 @@ provider_installation {
}
```

### 2. Set API Key
### 2. Set API Token

```bash
export CHATBOTKIT_API_KEY="your-api-key"
export CHATBOTKIT_API_TOKEN="your-api-token"
```

### 3. Test with Example Configuration
Expand All @@ -94,8 +93,8 @@ terraform apply
# Run unit tests
go test -v ./internal/provider/ -run "^Test[^Acc]"

# Run acceptance tests (requires CHATBOTKIT_API_KEY)
CHATBOTKIT_API_KEY=your-api-key go test -v ./internal/provider/ -run "^TestAcc"
# Run acceptance tests (requires CHATBOTKIT_API_TOKEN)
CHATBOTKIT_API_TOKEN=your-api-token go test -v ./internal/provider/ -run "^TestAcc"
```

## Directory Structure
Expand Down Expand Up @@ -185,7 +184,7 @@ terraform {
}

provider "chatbotkit" {
# api_key = "..." # Or set CHATBOTKIT_API_KEY env var
# api_token = "..." # Or set CHATBOTKIT_API_TOKEN env var
}

# Create a new bot
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.9.0
1.10.0
1 change: 0 additions & 1 deletion docs/data-sources/dataset.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ The following attributes are exported:
- `search_min_score` - Minimum similarity score for search results.
- `reranker` - The reranking model used.
- `separators` - Custom separators for text chunking.
- `store` - The storage backend used.
- `visibility` - The visibility setting of the dataset.
- `meta` - A map of metadata key-value pairs.
- `created_at` - The timestamp when the dataset was created.
Expand Down
21 changes: 11 additions & 10 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ terraform {
}

provider "chatbotkit" {
api_key = var.chatbotkit_api_key
api_token = var.chatbotkit_api_token
}

# Create a knowledge base dataset
Expand Down Expand Up @@ -50,7 +50,7 @@ resource "chatbotkit_bot" "assistant" {

## Authentication

The ChatBotKit provider requires an API key for authentication. You can obtain an API key from the [ChatBotKit Dashboard](https://chatbotkit.com).
The ChatBotKit provider requires a API token for authentication. You can obtain a API token from the [ChatBotKit Dashboard](https://chatbotkit.com).

### Configuration Options

Expand All @@ -59,13 +59,13 @@ You can configure authentication in two ways:
1. **Provider Configuration** (recommended for variables):
```terraform
provider "chatbotkit" {
api_key = var.chatbotkit_api_key
api_token = var.chatbotkit_api_token
}
```

2. **Environment Variable**:
```bash
export CHATBOTKIT_API_KEY="your-api-key"
export CHATBOTKIT_API_TOKEN="your-api-token"
```

When both are set, the provider configuration takes precedence.
Expand All @@ -74,18 +74,19 @@ When both are set, the provider configuration takes precedence.

### Optional

- `api_key` (String, Sensitive) - The API key for authenticating with the ChatBotKit API. Can also be set via the `CHATBOTKIT_API_KEY` environment variable.
- `base_url` (String) - Custom API endpoint URL. Defaults to `https://api.chatbotkit.com/graphql`. This is typically only needed for testing or enterprise deployments.
- `run_as` (String) - The ID of a sub-account (partner user) to operate on behalf of. When set, requests include the `X-RunAs-UserId` header, so a single `api_key` (a partner/master token) can manage many sub-accounts — configure one provider alias per sub-account. Can also be set via the `CHATBOTKIT_RUN_AS` environment variable.
- `api_token` (String, Sensitive) - The API token for authenticating with the ChatBotKit API. Can also be set via the `CHATBOTKIT_API_TOKEN` environment variable, or `CBK_API_TOKEN` for short.
- `api_key` (String, Sensitive, Deprecated) - The former name of `api_token`. It is used when `api_token` is not set.
- `base_url` (String) - The GraphQL endpoint URL. Defaults to `https://api.chatbotkit.com/graphql`. For a self-hosted platform use its GraphQL endpoint, e.g. `http://localhost:3000/api/v1/graphql`, or set the platform origin in the `CHATBOTKIT_API_URL` environment variable. Plain `http` works for local use.
- `run_as` (String) - The ID of a child User to operate on behalf of. When set, requests include the `X-RunAs-UserId` header, so one `api_token` belonging to the parent User can manage many child Users. Configure one provider alias per child User. Can also be set via the `CHATBOTKIT_API_RUNAS_USERID` environment variable (or `CBK_API_RUNAS_USERID` for short); `CHATBOTKIT_RUN_AS` and `CBK_RUN_AS` are still read.

### Operating on sub-accounts (multi-tenancy)
### Operating on child Users (multi-tenancy)

A partner/master token combined with `run_as` lets one configuration manage many isolated sub-accounts — the standard Terraform multi-account pattern (provider aliases, like the AWS provider's `assume_role`):
A API token belonging to a parent User, combined with `run_as`, lets one configuration manage many isolated child Users. This follows the standard Terraform multi-account pattern of provider aliases, similar to the AWS provider's `assume_role`:

```hcl
provider "chatbotkit" {
alias = "acme"
run_as = var.acme_account_id # api_key from CHATBOTKIT_API_KEY
run_as = var.acme_account_id # api_token from CHATBOTKIT_API_TOKEN
}

provider "chatbotkit" {
Expand Down
8 changes: 4 additions & 4 deletions docs/resources/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: |-

# chatbotkit_context (Resource)

Manages a ChatBotKit Context. A context binds the current account (or, under `run_as`, a partner sub-account) to a set of platform resources — a blueprint, bot, dataset, or skillset — along with a free-form payload. It is commonly used to scope a sub-account to a pre-defined configuration, or to attach per-account data (such as a repository or project id) that an agent reads at runtime.
Manages a ChatBotKit Context. A context binds the current User, or the child User selected by `run_as`, to a set of platform resources such as a blueprint, bot, dataset, or skillset, along with a free-form payload. It is commonly used to scope a User to a predefined configuration or attach per-User data, such as a repository or project ID, that an agent reads at runtime.

## Example Usage

Expand Down Expand Up @@ -47,11 +47,11 @@ resource "chatbotkit_context" "onboarding" {
}
```

### Per-sub-account context (with run_as)
### Per-User context (with run_as)

```terraform
# A provider alias whose run_as targets a partner sub-account; the context is
# created inside that sub-account.
# A provider alias whose run_as targets a child User. The context is
# created for that User.
provider "chatbotkit" {
alias = "customer"
run_as = var.customer_account_id
Expand Down
1 change: 0 additions & 1 deletion docs/resources/dataset.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ The following arguments are supported:
- `search_min_score` - (Optional) Minimum similarity score (0-1) for search results to be included.
- `reranker` - (Optional) The reranking model to use for improving search relevance.
- `separators` - (Optional) Custom separators for text chunking.
- `store` - (Optional) The storage backend to use.
- `visibility` - (Optional) The visibility level of the dataset. Can be "private" or "public".
- `meta` - (Optional) A map of metadata key-value pairs.

Expand Down
4 changes: 3 additions & 1 deletion docs/resources/instagram_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ resource "chatbotkit_instagram_integration" "advanced" {
bot_id = chatbotkit_bot.assistant.id

access_token = var.instagram_access_token
app_secret = var.instagram_app_secret

session_duration = 3600000 # 1 hour in milliseconds
contact_collection = true
Expand All @@ -51,7 +52,8 @@ The following arguments are supported:
- `name` - (Optional) The name of the integration. This is displayed in the ChatBotKit dashboard.
- `description` - (Optional) A description of the integration's purpose.
- `bot_id` - (Optional) The ID of the ChatBotKit bot to connect.
- `access_token` - (Optional, Sensitive) The Instagram access token used to send and receive messages.
- `access_token` - (Optional, Sensitive) The Instagram access token used to send and receive messages. Removing `access_token` from your configuration sends an explicit null on update, which clears the access token on the platform.
- `app_secret` - (Optional, Sensitive) The Instagram app secret used to verify webhook signatures. The API never returns the configured value (it is masked on read), so the value from your configuration is kept in state. Removing `app_secret` from your configuration sends an explicit null on update, which clears the app secret on the platform.
- `attachments` - (Optional) Whether to enable file attachments.
- `session_duration` - (Optional) The duration of a conversation session in milliseconds.
- `contact_collection` - (Optional) Whether to collect contact information from users.
Expand Down
4 changes: 3 additions & 1 deletion docs/resources/messenger_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ resource "chatbotkit_messenger_integration" "advanced" {
bot_id = chatbotkit_bot.assistant.id

access_token = var.messenger_access_token
app_secret = var.messenger_app_secret
session_duration = 3600000 # 1 hour in milliseconds
attachments = true
}
Expand Down Expand Up @@ -66,7 +67,8 @@ The following arguments are supported:
- `name` - (Optional) The name of the integration. This is displayed in the ChatBotKit dashboard.
- `description` - (Optional) A description of the integration's purpose.
- `bot_id` - (Optional) The ID of the ChatBotKit bot to connect.
- `access_token` - (Optional, Sensitive) The Facebook Messenger page access token.
- `access_token` - (Optional, Sensitive) The Facebook Messenger page access token. Removing `access_token` from your configuration sends an explicit null on update, which clears the page access token on the platform.
- `app_secret` - (Optional, Sensitive) The Facebook Messenger app secret used to verify webhook signatures. The API never returns the configured value (it is masked on read), so the value from your configuration is kept in state. Removing `app_secret` from your configuration sends an explicit null on update, which clears the app secret on the platform.
- `session_duration` - (Optional) The duration of a conversation session in milliseconds.
- `attachments` - (Optional) Whether to enable file attachments in conversations.
- `blueprint_id` - (Optional) The ID of a blueprint to associate with this integration.
Expand Down
6 changes: 4 additions & 2 deletions docs/resources/skillset_ability.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,10 @@ In addition to all arguments above, the following attributes are exported:

## Import

Skillset abilities can be imported using their ID:
Skillset abilities can only be looked up through their skillset, so the import ID must combine both IDs as `<skillset_id>/<ability_id>`:

```bash
terraform import chatbotkit_skillset_ability.example ability_abc123def456
terraform import chatbotkit_skillset_ability.example skillset_abc123def456/ability_abc123def456
```

Importing with a bare ability ID is rejected with an error explaining the expected format.
4 changes: 3 additions & 1 deletion docs/resources/whatsapp_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ resource "chatbotkit_whatsapp_integration" "advanced" {
bot_id = chatbotkit_bot.assistant.id

access_token = var.whatsapp_access_token
app_secret = var.whatsapp_app_secret
phone_number_id = var.whatsapp_phone_number_id
session_duration = 3600000 # 1 hour in milliseconds
contact_collection = true
Expand Down Expand Up @@ -70,7 +71,8 @@ The following arguments are supported:
- `name` - (Optional) The name of the integration. This is displayed in the ChatBotKit dashboard.
- `description` - (Optional) A description of the integration's purpose.
- `bot_id` - (Optional) The ID of the ChatBotKit bot to connect.
- `access_token` - (Optional, Sensitive) The WhatsApp Business API access token.
- `access_token` - (Optional, Sensitive) The WhatsApp Business API access token. Removing `access_token` from your configuration sends an explicit null on update, which clears the access token on the platform.
- `app_secret` - (Optional, Sensitive) The WhatsApp Business app secret used to verify webhook signatures. The API never returns the configured value (it is masked on read), so the value from your configuration is kept in state. Removing `app_secret` from your configuration sends an explicit null on update, which clears the app secret on the platform.
- `phone_number_id` - (Optional) The WhatsApp Business phone number ID.
- `session_duration` - (Optional) The duration of a conversation session in milliseconds.
- `contact_collection` - (Optional) Whether to collect contact information from users.
Expand Down
Loading
Loading