Skip to content
Draft
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 internal/cmd/root/verbs/install/skills_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestInstallBundledSkillsWritesVersionedSkillsAndManifest(t *testing.T) {

assert.Equal(t, canonicalDir, result.CanonicalDir)
assert.Equal(t, "v9.9.9", result.CLIVersion)
expectedSkills := []string{"kongctl-declarative", "kongctl-extension-builder"}
expectedSkills := []string{"kongctl-ai-gateway", "kongctl-declarative", "kongctl-extension-builder"}
assert.ElementsMatch(t, expectedSkills, result.SkillNames)

for _, skillName := range result.SkillNames {
Expand Down
6 changes: 6 additions & 0 deletions skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ with `kongctl`.

## Included Skills

- [kongctl-ai-gateway](kongctl-ai-gateway/SKILL.md)
- Deploy native AI Gateway models, caller access and auditable CI/CD.
- `kongctl-declarative`
- Generate declarative config and manage plan/apply/sync/delete/adopt flows.
- `kongctl-extension-builder`
Expand All @@ -28,8 +30,10 @@ kongctl install skills --dry-run
By default, the installer writes skill files to `.kongctl/skills/` and creates
symlinks for supported agent tooling:

- `.agents/skills/kongctl-ai-gateway`
- `.agents/skills/kongctl-declarative`
- `.agents/skills/kongctl-extension-builder`
- `.claude/skills/kongctl-ai-gateway`
- `.claude/skills/kongctl-declarative`
- `.claude/skills/kongctl-extension-builder`

Expand All @@ -50,12 +54,14 @@ tool's skills directory.

- Target path: `.claude/skills/`
- Example:
- `ln -s ../../skills/kongctl-ai-gateway .claude/skills/kongctl-ai-gateway`
- `ln -s ../../skills/kongctl-declarative .claude/skills/kongctl-declarative`
- `ln -s ../../skills/kongctl-extension-builder .claude/skills/kongctl-extension-builder`

### Codex, Cursor, opencode

- Target path: `.agents/skills/` (some setups use `.agents/skills/`)
- Example:
- `ln -s ../../skills/kongctl-ai-gateway .agents/skills/kongctl-ai-gateway`
- `ln -s ../../skills/kongctl-declarative .agents/skills/kongctl-declarative`
- `ln -s ../../skills/kongctl-extension-builder .agents/skills/kongctl-extension-builder`
2 changes: 1 addition & 1 deletion skills/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import "embed"

// BundledFS contains the built-in kongctl skills distributed with the CLI.
//
//go:embed kongctl-declarative kongctl-extension-builder
//go:embed kongctl-ai-gateway kongctl-declarative kongctl-extension-builder
var BundledFS embed.FS
148 changes: 148 additions & 0 deletions skills/kongctl-ai-gateway/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
name: kongctl-ai-gateway
description: >-
Build and evolve native Konnect AI Gateway deployments with kongctl
declarative configuration, from local provider-backed inference to model
access controls and auditable CI/CD. Use for AI Gateway setup, extending
an existing deployment, or diagnosing its configuration and traffic.
license: Apache-2.0
metadata:
product: kongctl
category: ai-gateway
---

# kongctl AI Gateway

Help the user reach a working AI Gateway through declarative files they can
review and operate again. This skill is self-contained; a kongctl source
checkout or another skill is unnecessary.

## Choose the next outcome

- For a new local OpenAI deployment, read
[local OpenAI setup](references/local-openai.md). Adapt the bundled
[manifest](assets/openai/ai-gateway.yaml) and
[data plane helper](assets/openai/data-plane.sh) into the user's project.
- For more models or caller authorization, read
[model access](references/model-access.md). Extend the existing gateway
and preserve its namespace, refs, names, public certificate and model
aliases unless the requested change requires otherwise.
- For a deployment pipeline, read [CI/CD](references/cicd.md). Combine it
with model access only when that expansion is requested. Start with the
bundled single-workflow example and one existing gateway; for a
speed-focused task, get the first CI deployment working before expanding
models or callers. Keep the user's required approval boundary, but do not
add enterprise controls or custom audit machinery by default.
- For a failure, use the diagnostic table in the local setup reference;
inspect the relevant installed schema before changing configuration.

Use the user's chosen provider, CI system and hosting model. The local
OpenAI example is a starting point, not a prerequisite for other use cases.
If account details or credentials are unavailable, still prepare concrete
files, local checks and the commands needed to finish. Ask only for choices
that block the next action; reuse existing authorization. A files-only task
does not authorize Konnect mutations, Docker startup or paid inference.

## Discover the installed contract

Start with `kongctl version --full` and targeted schema discovery:

```sh
kongctl explain ai_gateways -o text
```

Then inspect only the children and fields needed for the requested setup,
using `-o text` for summaries. Request JSON or extended output only for a
specific field that needs detail; a full gateway schema includes all nested
resources and can overwhelm the useful context. For example, use
`kongctl explain ai_gateways.models.access -o text` for access controls.
Use `kongctl scaffold --help` when a different resource shape needs a
starter. Read the schema's required
fields, union branches and relationship annotations; do not infer required
names from `ref`. If the installed CLI lacks these subjects, report that
capability gap and arrange a compatible CLI before attempting deployment.

Native AI Gateway uses `ai_gateways`, nested `model_providers`, `models`,
`data_plane_certificates`, `auth_strategies` and `consumers`. A Gateway
control plane with services, routes and AI plugins is a different workflow.
Use that architecture when the user explicitly requests it or is already
operating it. Native AI Gateway configuration does not require decK.

The bundled example follows kongctl 1.15.1 native declarative support and
the AI Gateway 2.0 quickstarts. Verify the installed schema when adapting it;
an example version is not a claim of compatibility with every environment.
For other providers or policies, use targeted discovery and the current
[AI Gateway documentation](https://developer.konghq.com/ai-gateway/).

## Keep the deployment contract explicit

- Set `_defaults.kongctl.namespace` to the project's ownership scope. Use
explicit `ref`, `name` and required API fields. Preserve identity during
expansion so the plan updates the existing deployment.
- Keep file inputs within the project. `!file` resolves relative to its
containing YAML file, constrained by `--base-dir`. Ordinary `!env` values
resolve during loading; deferred `!secret` values resolve during apply.
- Use `!secret` for write-only provider and caller credentials. Public
`Bearer ` decoration belongs in `parts`; secret bytes do not. Do not print
environment values or put private keys, credentials or response dumps in
committed configuration.
- Separate the public model alias used in request routing from the upstream
model ID. Give aliases unique values within the gateway. Select upstream
models available to the user's provider account before planning.
- Prefer an explicit `--mode apply` plan for additive setup and expansion.
`plan` defaults to sync mode, which can propose deletions. A saved plan's
execution verb must match its mode. Use sync/delete only for the intended
ownership scope and show their proposed removals.
- Plan and diff require remote state and Konnect authentication. Schema
inspection and local file checks can run without them. Do not invent an
offline validation flag, substitute a fake API endpoint, or claim generic
YAML lint proves native schema, references or deployment success.

Once the target and execution are authorized, produce and inspect a saved
plan, then execute that same file:

```sh
mkdir -p .plans .artifacts
kongctl plan --mode apply -f ai-gateway.yaml \
--require-namespace ai-demo --output-file .plans/apply.json
kongctl diff --plan .plans/apply.json
kongctl apply --plan .plans/apply.json -o json --auto-approve \
--execution-report-file .artifacts/apply-report.json
```

Adapt the namespace and use the same explicit profile and region/base URL
for planning and execution. Record the target organization ID using
`kongctl get organization -o json --jq '.id' --jq-raw-output` with that
same context; a profile or organization name alone is not its identity.
Changes to inputs or target require a new plan and review. Secrets
referenced in that plan must be supplied to execution.
Use `--auto-approve` only after the saved plan's execution is authorized;
it avoids a second interactive CLI prompt in an agent's noninteractive
shell. Explicit JSON output also works around versions that skip writing
`--execution-report-file` with text output. Verify that the report exists
and inspect its summary; a missing report does not mean apply failed and
is not a reason to repeat mutations.

## Finish with evidence and a usable handoff

Deliver the project files and concise instructions to configure required
inputs, plan/apply, run the data plane, verify traffic and clean up the
project's resources. Keep local data plane operations separate from remote
Konnect operations so the user can run each on its intended host.

Report what was actually checked:

- **Authored:** files and execution instructions exist.
- **Locally checked:** name the schema, file or script checks performed.
- **Provisioned/connected:** resources exist and the data plane connects.
- **Functional:** a matching request returns a real model completion;
access changes also pass the intended allowed and denied cases.

A plan, container startup, node listing or HTTP status alone does not prove
inference. Record remaining steps when live execution is unavailable. For a
repeatable demo, inspect an unchanged follow-up plan and rehearse scoped
cleanup. Keep the execution report, follow-up plan and sanitized node and
inference check results as local evidence; do not rely only on a transcript
summary. Inspect artifacts for secrets before sharing them.
Determinism here concerns deployment inputs and approved actions;
model replies and remote state can vary.
5 changes: 5 additions & 0 deletions skills/kongctl-ai-gateway/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
interface:
display_name: "Kongctl AI Gateway"
short_description: "Deploy AI Gateway with models, access and CI/CD"
default_prompt: "Use $kongctl-ai-gateway to build a declarative AI Gateway
deployment with working model traffic and a reviewable deployment workflow."
84 changes: 84 additions & 0 deletions skills/kongctl-ai-gateway/assets/github-actions/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Deploy reviewed AI Gateway plan

on:
workflow_dispatch:
inputs:
plan_sha256:
description: SHA-256 of the committed ci/plan.json you reviewed
required: true
type: string

permissions:
contents: read

concurrency:
group: ai-gateway-ai-demo
cancel-in-progress: false

env:
KONGCTL_VERSION: "1.16.0"
KONGCTL_NO_TELEMETRY: "true"
KONNECT_BASE_URL: https://us.api.konghq.com
KONNECT_ORG_ID: REPLACE_WITH_ORGANIZATION_ID
KONNECT_NAMESPACE: ai-demo

jobs:
deploy:
runs-on: ubuntu-24.04
timeout-minutes: 5
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
persist-credentials: false
- name: Check the reviewed plan
env:
EXPECTED_PLAN_SHA256: ${{ inputs.plan_sha256 }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
set -euo pipefail
test "$GITHUB_REF" = "refs/heads/$DEFAULT_BRANCH"
[[ "$EXPECTED_PLAN_SHA256" =~ ^[0-9a-f]{64}$ ]]
printf '%s ci/plan.json\n' "$EXPECTED_PLAN_SHA256" | sha256sum --check -
jq -e --arg ns "$KONNECT_NAMESPACE" --arg cli "kongctl/$KONGCTL_VERSION" '
.metadata.mode == "apply" and .metadata.generator == $cli and
all(.changes[]; .namespace == $ns and
(.action == "CREATE" or .action == "UPDATE"))
' ci/plan.json >/dev/null
- uses: Kong/setup-kongctl@659d5c2b0f4db2e25d63797035358a22907421db # v1
with:
kongctl-version: ${{ env.KONGCTL_VERSION }}
- name: Apply the approved plan
env:
KONGCTL_DEFAULT_KONNECT_PAT: ${{ secrets.KONNECT_PAT }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
set -euo pipefail
test -n "$KONGCTL_DEFAULT_KONNECT_PAT"
test "$(kongctl version --full | cut -d ' ' -f 1)" = "$KONGCTL_VERSION"
actual_org="$(kongctl get organization --profile default \
--base-url "$KONNECT_BASE_URL" -o json --jq '.id' --jq-raw-output)"
test "$actual_org" = "$KONNECT_ORG_ID"
mkdir -p evidence
{
printf 'Source: %s\nActor: %s\n' "$GITHUB_SHA" "$GITHUB_ACTOR"
printf 'Organization: %s\nNamespace: %s\n' "$actual_org" "$KONNECT_NAMESPACE"
sha256sum ci/plan.json
kongctl diff --plan ci/plan.json
} > evidence/review.txt
cat evidence/review.txt
cat evidence/review.txt >> "$GITHUB_STEP_SUMMARY"
kongctl apply --plan ci/plan.json --profile default \
--base-url "$KONNECT_BASE_URL" --auto-approve -o json \
--execution-report-file evidence/apply.json
jq -e '.summary.status == "success"' evidence/apply.json
- name: Save execution evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ai-gateway-${{ github.run_id }}-${{ github.run_attempt }}
path: evidence/
if-no-files-found: warn
retention-days: 7
58 changes: 58 additions & 0 deletions skills/kongctl-ai-gateway/assets/openai/ai-gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
_defaults:
kongctl:
namespace: ai-demo

ai_gateways:
- ref: ai-demo
name: ai-demo
display_name: AI Demo
description: Local OpenAI-backed AI Gateway
deployment_type: hybrid
proxy_urls:
- host: localhost
port: 8000
protocol: http
data_plane_certificates:
- ref: ai-demo-data-plane
title: ai-demo-data-plane
description: Local Docker data plane
cert: !file ./certs/data-plane.crt
model_providers:
- ref: openai
name: openai
display_name: OpenAI
type: openai
config:
auth:
type: basic
headers:
- name: Authorization
value: !secret
parts:
- "Bearer "
- !env OPENAI_API_KEY
models:
- ref: demo-chat
name: demo-chat
display_name: Demo Chat
type: model
enabled: true
formats:
- type: openai
config:
route:
paths:
- /v1
model:
body_param: model
values:
- demo-chat
targets:
- name: !env OPENAI_MODEL
provider: openai
allow_auth_override: false
config:
type: openai
policies: []
capabilities:
- generate
Loading
Loading