This directory contains example Agent, Provider, Gateway, and Credential definitions for the Agent Control Plane. The examples are organized into two tiers:
- Starter Examples (
base/+overlays/) — individual agents scoped to simple tenant projects. Start here. - vTeam Lab (
vteam-catalog/) — multi-agent virtual teams that demonstrate building agentic teams with coordination, specialization, and shared work.
Get a working OpenShell gateway with sandboxed agents in under 5 minutes.
make kind-upThis creates a Kind cluster and deploys the full ACP stack: API server, control plane, UI, Keycloak SSO, and OpenShell gateways for all tenants. By default OPENSHELL_USE_GATEWAY=true and five tenants are provisioned: tenant-a, tenant-b, tenant-c, vteam-product-swarm, codebase-maintainers.
Vertex AI credentials are auto-detected from gcloud auth application-default login if available.
make kind-loginSets your kubectl context, starts port-forwards, and logs acpctl in via Keycloak SSO (default: developer/developer).
make kind-statusShows all access URLs, port assignments, and gateway endpoints.
scripts/setup-gateway-cli.sh tenant-aExtracts mTLS certificates from the cluster and registers the tenant-a gateway with the openshell CLI. After this, you can use openshell commands directly against the gateway.
Option A — Create a session via acpctl:
acpctl project tenant-a
acpctl create session --name my-test --agent-id hello-world --prompt "Say hello"Option B — Create a sandbox via the openshell CLI:
openshell sandbox create -g tenant-a --image quay.io/ambient_code/acp_runner_openshell:latest -- bashOption C — Use the web UI:
Open http://localhost:14080, sign in as developer/developer, select the tenant-a project, and start a session with the hello-world agent.
| Tenant | Database | Auth | Purpose |
|---|---|---|---|
| tenant-a | PostgreSQL | mTLS | Development. Full-featured: postgres-backed gateway, all providers, permissive sandbox policy. |
| tenant-b | SQLite (default) | mTLS | Staging. Lighter footprint, fewer credentials. Good for comparing behavior. |
| tenant-c | SQLite (default) | OIDC + Keycloak | OIDC demo. Browser-based login, role-based access control. |
If you want to re-apply or modify tenant configurations:
acpctl apply -k examples/overlays/tenant-a/ --project tenant-a
acpctl apply -k examples/overlays/tenant-b/ --project tenant-b
acpctl apply -k examples/overlays/tenant-c/ --project tenant-cEach overlay applies the full declarative stack: Project, Gateway, Agents, Providers, Policies, and Credentials.
If you are using a hosted ACP environment, your administrators provide Vertex AI access; you only need to supply your own integration credentials, such as GitHub and Jira, for examples that use those providers.
The following covers credential setup for the local Kind cluster. Each agent example declares which providers it needs; you only need to set up credentials for the providers used by the agents you want to run.
If you have local Vertex authentication configured (e.g.
gcloud auth application-default login), make kind-up automatically detects
it and installs the credential into each tenant namespace. Agents that use
Claude — such as hello-world — will work out of the box.
To use a different Vertex service account key:
kubectl create secret generic vertex-sa-key \
--namespace=tenant-a \
--from-literal=token="$(cat vertex.json)"Agents that integrate with Jira (e.g. jira-simple-whoami,
jira-issue-categorizer) require a Jira API token in the tenant namespace:
kubectl create secret generic jira \
--from-literal=JIRA_USERNAME="you@example.com" \
--from-literal=JIRA_API_TOKEN="$(cat ~/jira-token.txt)" \
-n tenant-aAgents that integrate with GitHub (e.g. pr-reviewer) require a GitHub
personal access token in the tenant namespace:
kubectl create secret generic github-creds \
--from-literal=token="$(cat ~/github-pat.txt)" \
-n tenant-aSimple, single-agent examples organized into two tenants. Use these to learn how Agents, Providers, Gateways, and Credentials fit together.
examples/
├── base/
│ ├── agents/ # Agent definitions (provider-agnostic)
│ │ ├── hello-world.yaml
│ │ ├── security-reviewer.yaml
│ │ ├── jira-simple-whoami.yaml
│ │ ├── jira-simple-whoami-with-skill-payload.yaml
│ │ ├── pr-reviewer.yaml
│ │ └── jira-issue-categorizer.yaml
│ ├── gateways/ # Base gateway template (reference only)
│ │ └── openshell-gateway.yaml
│ ├── policies/ # Sandbox policies (applied alongside agents)
│ │ ├── permissive.yaml
│ │ ├── locked-down.yaml
│ │ └── mock-llm-permissive.yaml
│ └── providers/ # Boilerplate provider integrations (shared by all tenants)
│ ├── vertex.yaml
│ ├── github.yaml
│ ├── jira.yaml
│ └── mock-llm.yaml
└── overlays/
├── tenant-a/ # Development tenant (PostgreSQL gateway)
│ ├── project.yaml
│ ├── gateway.yaml # Gateway with database: {type: postgres}
│ ├── credential-vertex.yaml
│ ├── credential-jira.yaml
│ ├── credential-github.yaml
│ └── credential-mock-llm.yaml
├── tenant-b/ # Staging tenant (SQLite gateway)
│ ├── project.yaml
│ ├── gateway.yaml
│ ├── credential-vertex.yaml
│ └── credential-github.yaml
└── tenant-c/ # OIDC-authenticated tenant
├── project.yaml
└── gateway.yaml # Gateway with OIDC + route config
base/ contains resources shared across all tenants: agent definitions, sandbox policies, and boilerplate provider integrations (vertex, github, jira). overlays/ contains the tenant-specific Project, Gateway, and Credentials.
# Apply to development tenant
acpctl apply -k examples/overlays/tenant-a/ --project tenant-a
# Apply to staging tenant
acpctl apply -k examples/overlays/tenant-b/ --project tenant-b# tenant-a
acpctl apply -f examples/base/agents --project tenant-a
acpctl apply -f examples/overlays/tenant-a --project tenant-a
# tenant-b
acpctl apply -f examples/base/agents --project tenant-b
acpctl apply -f examples/overlays/tenant-b --project tenant-bThe --project flag (or acpctl project <name> beforehand) tells the CLI which project to scope Agents, Providers, and Gateways to.
Each overlay applies the full declarative stack via a single acpctl apply -k:
| Kind | Source | Purpose |
|---|---|---|
| Project | overlays/*/project.yaml |
Creates the tenant project with description, prompt, and labels |
| Agent | base/agents/*.yaml |
Shared agent definitions (hello-world, pr-reviewer, etc.) |
| Policy | base/policies/*.yaml |
Sandbox policies referenced by agents (sandbox_policy: permissive) |
| Provider | base/providers/*.yaml |
Boilerplate integrations (vertex, github, jira, mock-llm) — shared by all tenants |
| Gateway | overlays/*/gateway.yaml |
Project-scoped OpenShell gateway with tenant-specific DNS names and optional database config |
| Credential | overlays/*/credential-*.yaml |
Tenant-specific credentials with env-var token references |
Full-featured development tenant with a PostgreSQL-backed gateway. The control plane provisions a Postgres Deployment, PVC, Secret, Service, and NetworkPolicy alongside the gateway. Use this tenant for testing new prompts, provider integrations, and agent configurations.
Database: PostgreSQL (auto-provisioned)
Providers configured: vertex, jira, github, mock-llm
Credentials: Vertex AI, Jira, GitHub, Mock LLM
Gateway: OpenShell gateway at openshell-gateway.tenant-a.svc.cluster.local
Lighter-weight staging tenant using the default SQLite database (embedded in the gateway StatefulSet). Use this tenant to validate agent behavior and provider configs before promoting to production.
Database: SQLite (default, no external database)
Providers configured: vertex, github, jira (from base)
Credentials: Vertex AI, GitHub (no Jira credential — agents requiring Jira will not run)
Gateway: OpenShell gateway at openshell-gateway.tenant-b.svc.cluster.local
Demonstrates OIDC-authenticated gateway access via Keycloak. Requires browser-based login. Role-based access control enforced by the gateway: openshell-admin and openshell-user roles.
Database: SQLite (default)
Auth: OIDC via Keycloak (ambient-code realm)
Providers configured: vertex, github, jira (from base)
Gateway: OpenShell gateway at openshell-gateway.tenant-c.svc.cluster.local
A wide-open sandbox policy that allows network access to most common services. Defines filesystem access (read-only system paths, read-write /sandbox and /tmp), Landlock LSM settings, process identity, and network policies for:
- Claude Code + Vertex AI — Vertex AI inference, Google auth, Anthropic API
- gcloud — OAuth and IAM token refresh
- GitHub — Git Smart HTTP (read-only clone/fetch) and REST API (read-only)
- PyPI — Python package installation
- VS Code / Cursor — IDE remote server downloads
- OpenCode — npm registry and inference
- Atlassian — Jira and Confluence REST APIs
Note: ACP internal traffic (runner-to-control-plane and runner-to-API-server) is automatically injected by the control plane at sandbox creation time and does not need to be declared in user-facing policies.
Agents reference the policy by name via sandbox_policy: permissive. Agents that omit sandbox_policy get the gateway's built-in locked-down default (no external network access beyond ACP internal traffic).
To apply the policy independently:
acpctl apply -f examples/base/policies/permissive.yamlThe simplest possible agent. Sends a greeting and demonstrates payload injection and environment variables.
Providers: vertex
What it does: Says hello world, and — thanks to an injected payload — also tells you how to say hello in a different language.
Session prompt example:
Say hello
A code security auditor. Analyzes code snippets or repositories for common vulnerabilities.
Providers: vertex
What it does: Reviews code for injection attacks, authentication issues, insecure data handling, and other vulnerabilities. Reports findings with severity, location, and remediation guidance.
Session prompt example:
Review this Python function for security issues:
def login(username, password):
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
return db.execute(query)
Demonstrates Jira Model Context Protocol integration. Connects to Jira and looks up the authenticated user's profile.
Providers: vertex, jira
Prerequisites: Jira credentials for the project.
What it does: Uses the Jira Model Context Protocol tools to call the Jira API. Returns the current user's username and profile information.
Session prompt example:
Who am I in Jira?
Same as jira-simple-whoami but demonstrates the payload injection pattern: a skill file is injected into the sandbox at /sandbox/SKILL.md and the agent follows its instructions.
Providers: vertex, jira
Prerequisites: Jira credentials for the project.
What it does: Looks up the Jira user profile and responds in olde English, as instructed by the injected skill payload.
Session prompt example:
Who am I in Jira?
A GitHub Pull Request reviewer. Fetches PR metadata, diffs, and comments via the GitHub Model Context Protocol integration. Produces a structured review report.
Providers: vertex, github
Prerequisites: GitHub credentials for the project.
What it does:
- Fetches PR metadata (title, description, author, branches)
- Retrieves changed files and full diffs
- Reads existing review comments for context
- Analyzes the changes against an injected checklist covering security, code quality, tests, architecture conventions, breaking changes, and documentation
- Produces a report grouped by severity:
CRITICAL/WARNING/INFO - Ends with an overall recommendation:
APPROVE/REQUEST_CHANGES/COMMENT
Session prompt example:
Review PR #42 in my-org/my-repo
Automatically categorizes Jira issues into Sankey Activity Types using AI. Inspired by the jira-ai-categorizer project, reimplemented as an agent — eliminating the need for a separate Python script and external LLM endpoint.
Providers: vertex, jira
Prerequisites: Jira credentials for the project. The Jira URL is
pre-configured to https://redhat.atlassian.net in the agent definition.
What it does:
- Searches for issues in the specified project(s) using JQL
- Reads each issue's summary and description
- Classifies it into one of six Sankey Activity Types using an injected classification guide:
Associate Wellness & DevelopmentIncidents & SupportSecurity & ComplianceQuality / Stability / ReliabilityFuture SustainabilityProduct / Portfolio Work
- In dry-run mode (default), reports what would be set without making changes
- Optionally supports hierarchical propagation: propagates the Activity Type from parent issues down to all descendants
Session prompt examples:
Categorize issues in project RHCLOUD. Dry-run mode ON.
Categorize issues in project RHCLOUD for components Clowder and Bonfire. Dry-run mode ON.
Categorize issues in project HPSTRAT using hierarchical mode. Apply changes.
Note: By default the agent runs in dry-run mode and will not write any changes to Jira unless explicitly instructed otherwise in the session prompt.
The vteam-catalog/ directory contains more in-depth examples of building agentic virtual teams. Where the starter examples above show individual agents, the vTeam lab demonstrates multi-agent collaboration: teams of specialized agents with distinct roles, coordination patterns, and shared work.
vteam-catalog/
├── product-swarm/ # Cross-functional product delivery team
└── codebase-maintainers/ # Internal codebase maintenance team
The vteam-product-swarm and codebase-maintainers namespaces are provisioned automatically during make kind-up (included in the default OPENSHELL_TENANTS). See the vTeam Catalog README for architecture details and the QUICKSTART for a step-by-step walkthrough.
# Product swarm — six-agent product delivery team
acpctl apply -k examples/vteam-catalog/product-swarm --project vteam-product-swarm
# Codebase maintainers — four-agent maintenance team
acpctl apply -k examples/vteam-catalog/codebase-maintainers --project codebase-maintainersEach overlay declares a project-scoped OpenShell gateway in gateway.yaml. The gateway is reconciled by the GatewayReconciler into Kubernetes resources (StatefulSet or Deployment, Service, RBAC, certgen Job).
Key fields:
image— gateway container image (defaults toOPENSHELL_GATEWAY_IMAGEif omitted)server_dns_names— DNS names for TLS certificate generation, scoped to the tenant namespaceconfig— optional TOML configuration for the gatewaydatabase— optional database backend configuration:type: sqlite(default) — embedded database, gateway runs as a StatefulSettype: postgres— auto-provisions a PostgreSQL Deployment, PVC, Secret, Service, and NetworkPolicy; gateway runs as a Deployment with await-for-dbinit containerstorage_size— PVC size for PostgreSQL data (default5Gi)image— PostgreSQL container image (defaultpostgres:16)
oidc— optional OIDC authentication (issuer, audience, roles)route— optional GRPCRoute exposure via Kubernetes Gateway API
The base gateways/openshell-gateway.yaml serves as a reference template. Each overlay declares its own gateway with the correct namespace in server_dns_names.