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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"plugins": [
{
"name": "kbagent",
"version": "0.28.0",
"version": "0.29.0",
"source": "./plugins/kbagent",
"description": "AI-friendly interface to Keboola Connection projects — explore configs, jobs, lineage, call MCP tools, manage dev branches, and debug SQL in workspaces",
"category": "development"
Expand Down
16 changes: 14 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ All three inherit from `BaseHttpClient` (`http_base.py`) which provides shared r

11. **Error accumulation**: multi-project operations collect per-project errors without stopping. One project failing doesn't block others (see `lineage_service.py`, `org_service.py`).

12. **Manage token security**: never persisted, never passed as CLI argument, never logged. Only via `KBC_MANAGE_API_TOKEN` env var or interactive hidden prompt.
12. **Manage token security**: never persisted, never passed as CLI argument, never logged. Default-deny since 0.28.0: only via interactive hidden prompt; the `KBC_MANAGE_API_TOKEN` env var is **ignored** unless the top-level `--allow-env-manage-token` flag is passed. Default-deny closes the AI-exfiltration risk where any subprocess (including the AI agent itself) inherits the manage token via env. CI/CD callers must opt in explicitly.

13. **Idempotency**: `org setup` skips already-registered projects by matching `project_id`. Safe to re-run.

Expand Down Expand Up @@ -251,7 +251,7 @@ plugins/kbagent/
> "Plugin synchronization map" for the full list.

```
# Global options: --json, --verbose, --no-color, --config-dir, --hint client|service, --deny-writes, --deny-destructive
# Global options: --json, --verbose, --no-color, --config-dir, --hint client|service, --deny-writes, --deny-destructive, --allow-env-manage-token

kbagent project add --project NAME --url URL --token TOKEN
kbagent project list
Expand All @@ -264,6 +264,13 @@ kbagent project description-get --project NAME
kbagent project description-set --project NAME [--text STR | --file PATH | --stdin]
kbagent project use ALIAS
kbagent project current
kbagent project invite --project ALIAS --email EMAIL --role admin|guest|readOnly|share [--reason TEXT] [--dry-run]
kbagent project invite --from-csv FILE [--default-role ROLE] [--workers N] [--dry-run]
kbagent project member-list --project ALIAS [--include-pending]
kbagent project invitation-list --project ALIAS
kbagent project invitation-cancel --project ALIAS --email EMAIL [--invitation-id ID] [--yes]
kbagent project member-remove --project ALIAS --email EMAIL [--yes]
kbagent project member-set-role --project ALIAS --email EMAIL --role admin|guest|readOnly|share

kbagent config list [--project NAME] [--component-type TYPE] [--component-id ID] [--branch ID] [--include-rows]
kbagent config detail --project NAME [--project NAME ...] --component-id ID [--config-id ID] [--branch ID] [--with-state]
Expand Down Expand Up @@ -358,6 +365,11 @@ kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
kbagent data-app delete --project NAME --app-id ID [--yes]
kbagent data-app password --project NAME --app-id ID
kbagent data-app secrets-set --project ALIAS --app-id ID --secret '#KEY=VALUE' [--secret ...] [--secrets-file PATH] [--branch ID] [--allow-plaintext-on-encrypt-failure] [--dry-run] [--no-hint-next]
kbagent data-app secrets-list --project ALIAS --app-id ID [--branch ID] [--show-fingerprint]
kbagent data-app secrets-get --project ALIAS --app-id ID --key '#KEY' [--branch ID]
kbagent data-app secrets-remove --project ALIAS --app-id ID --key '#KEY' [--key ...] [--branch ID] [--yes] [--dry-run]
kbagent data-app validate-repo --git-repo URL [--git-branch BRANCH] [--git-public/--no-git-public] [--git-pat-env VAR | --git-pat-file PATH] [--type python-js] [--strict]

kbagent component list [--project NAME] [--type TYPE] [--query QUERY]
kbagent component detail --component-id ID [--project NAME]
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DEFAULT_GOAL := help

.PHONY: help install install-mcp sync test test-unit test-integration test-e2e test-file lint lint-fix format format-check skill-check skill-gen version-sync version-check changelog changelog-check check-error-codes check clean hooks
.PHONY: help install install-mcp sync test test-unit test-integration test-e2e test-e2e-invite test-file lint lint-fix format format-check skill-check skill-gen version-sync version-check changelog changelog-check check-error-codes check clean hooks

help: ## Show this help message
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
Expand All @@ -26,6 +26,9 @@ test-integration: ## Run integration tests only
test-e2e: ## Run E2E tests (E2E_API_TOKEN and E2E_URL required)
uv run pytest tests/test_e2e.py -v -s --tb=long

test-e2e-invite: ## Run project invite E2E (E2E_MANAGE_TOKEN + E2E_INVITE_PROJECT_ID required)
uv run pytest tests/test_e2e.py -v -s --tb=long -m e2e_invite

test-file: ## Run a specific test file (FILE=tests/test_cli.py)
uv run pytest $(FILE) -v

Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,22 @@ kbagent project add --project prod --url https://connection.keboola.com --token

**Many projects by ID** — you have a Manage API or Personal Access Token + the project IDs:
```bash
# Interactive: kbagent will prompt for the Manage API token (default since v0.28.0).
kbagent org setup --project-ids 901,9621,10539 --url https://connection.keboola.com --yes

# CI / non-interactive: opt in to env-var resolution with --allow-env-manage-token.
KBC_MANAGE_API_TOKEN=your-manage-or-personal-token \
kbagent org setup --project-ids 901,9621,10539 --url https://connection.keboola.com --yes
kbagent --allow-env-manage-token org setup --project-ids 901,9621,10539 --url https://connection.keboola.com --yes
```

**Whole organization** — you are org admin:
```bash
# Interactive (default since v0.28.0): kbagent prompts for the Manage API token.
kbagent org setup --org-id 123 --url https://connection.keboola.com --yes

# CI / non-interactive:
KBC_MANAGE_API_TOKEN=your-org-admin-manage-token \
kbagent org setup --org-id 123 --url https://connection.keboola.com --yes
kbagent --allow-env-manage-token org setup --org-id 123 --url https://connection.keboola.com --yes
```

Run `kbagent doctor` to verify setup (token validity, CLI version, MCP server, Claude Code plugin install).
Expand Down
39 changes: 29 additions & 10 deletions docs/TUTORIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,19 @@ use `org setup --project-ids`. kbagent creates a Storage API token in
each listed project and registers them all locally, in parallel.

```bash
export KBC_MANAGE_API_TOKEN=YOUR_MANAGE_OR_PAT_TOKEN

# Interactive (default since v0.29.0): kbagent prompts for the Manage API
# token on stdin. No env var, no shell history.
kbagent org setup \
--project-ids 901,9621,10539 \
--url https://connection.keboola.com \
--dry-run # always dry-run first

# CI / non-interactive: opt in to env-var resolution.
export KBC_MANAGE_API_TOKEN=YOUR_MANAGE_OR_PAT_TOKEN
kbagent --allow-env-manage-token org setup \
--project-ids 901,9621,10539 \
--url https://connection.keboola.com \
--dry-run
```

The dry-run prints what would happen (create token + register alias
Expand All @@ -132,10 +139,14 @@ Flags worth knowing:
The command is **idempotent**: running it again skips projects that
are already registered. Safe to re-run after adding new project IDs.

**Security note**: `KBC_MANAGE_API_TOKEN` is read only from env or
from an interactive hidden prompt. kbagent never accepts it as a CLI
argument (`--token xxx`) -- that would leak into shell history and
process listings.
**Security note (since v0.29.0)**: `KBC_MANAGE_API_TOKEN` is **ignored
by default** -- the env var is read only when the top-level
`--allow-env-manage-token` flag is passed. Without the flag, kbagent
prompts on stdin (hidden input). kbagent never accepts the token as a
CLI argument (`--token xxx`) -- that would leak into shell history and
process listings. The default-deny closes an AI-exfiltration risk where
any subprocess running as the same user (including the AI agent itself)
inherits env vars.

---

Expand All @@ -145,12 +156,18 @@ If you are an org admin with a Manage API token, register **every**
project in an organization in one shot:

```bash
export KBC_MANAGE_API_TOKEN=YOUR_ORG_ADMIN_MANAGE_TOKEN

# Interactive (default since v0.29.0):
kbagent org setup \
--org-id 123 \
--url https://connection.keboola.com \
--dry-run

# CI / non-interactive:
export KBC_MANAGE_API_TOKEN=YOUR_ORG_ADMIN_MANAGE_TOKEN
kbagent --allow-env-manage-token org setup \
--org-id 123 \
--url https://connection.keboola.com \
--dry-run
```

The dry-run reports how many projects will be registered and the
Expand Down Expand Up @@ -859,7 +876,8 @@ kbagent --json data-app create \
deploy. To retrieve it:

```bash
# Requires KBC_MANAGE_API_TOKEN in env (org-scoped Manage API token).
# Manage API token: interactive prompt by default (since v0.29.0). For CI,
# add `--allow-env-manage-token` and set KBC_MANAGE_API_TOKEN in env.
kbagent --json data-app password \
--project prod --app-id 12345678 \
| jq -r '.data.password'
Expand Down Expand Up @@ -949,7 +967,8 @@ shapes, and the `--hint client|service` code-generation contract, see
| `kbagent: command not found` after `uv tool install` | Ensure `~/.local/bin` (or uv's tool dir) is on your PATH. `uv tool update-shell` can help. |
| `kbagent doctor` reports `warn` for plugin | Run the two `/plugin` commands shown in the warning, from inside Claude Code. |
| Plugin version != CLI version | In Claude Code: `/plugin update kbagent`. |
| `org setup` fails with `401 Unauthorized` | Your `KBC_MANAGE_API_TOKEN` is wrong for this stack or role. Manage tokens are stack-specific and require the right scope. |
| `org setup` exits 2 with `Warning: KBC_MANAGE_API_TOKEN found in environment but ignored` | Default-deny since v0.29.0 -- pass `--allow-env-manage-token` (top-level flag) to opt in to env resolution, or run interactively to use the prompt. |
| `org setup` fails with `401 Unauthorized` | Your manage token is wrong for this stack or role. Manage tokens are stack-specific and require the right scope. |
| `org setup --org-id` fails with `403` | You are not an org admin. Use `--project-ids` with a Personal Access Token instead (works for any project member). |
| Changes from `kbagent config update` do not show in UI | You are on a dev branch. Run `kbagent branch list` and `kbagent project current` to verify the active branch; changes in a dev branch merge to production only via the UI merge step (`kbagent branch merge` returns the merge URL). |
| The specialist subagent does not spawn when I type `/keboola X` | Plugin is not installed or is outdated. Run `kbagent doctor` and follow the reported commands. |
Expand Down
4 changes: 2 additions & 2 deletions docs/e2e-scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ Skipped if `keboola-mcp-server` is not installed.

| Command | Reason |
|---------|--------|
| `project refresh` | Requires Manage API token (`KBC_MANAGE_API_TOKEN`) |
| `org setup` | Requires Manage API token + destructive (registers projects in org) |
| `project refresh` | Requires Manage API token (interactive prompt by default since v0.29.0; `--allow-env-manage-token` + `KBC_MANAGE_API_TOKEN` for non-interactive runners) |
| `org setup` | Requires Manage API token (same prompt-or-flag as above) + destructive (registers projects in org) |
| `sharing share/unshare` | Requires org-level permissions or second project |
| `sharing link/unlink` | Requires shared bucket from another project |
| `permissions set/reset` | Interactive random-code confirmation blocks automated testing |
Expand Down
2 changes: 1 addition & 1 deletion plugins/kbagent/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kbagent",
"version": "0.28.0",
"version": "0.29.0",
"description": "AI-friendly interface to Keboola Connection projects — explore configs, jobs, lineage, call MCP tools, manage dev branches, and debug SQL in workspaces",
"author": {
"name": "Keboola",
Expand Down
Loading
Loading