Configuration¶
Custom Skills¶
Skills are bash snippets the agent can invoke as tools. Define them in a ConfigMap with a skills.md key:
apiVersion: v1
kind: ConfigMap
metadata:
name: copilot-skills
namespace: kube-copilot-agent
data:
skills.md: |
## Skill: List unhealthy pods
Lists all pods that are not Running or Completed.
```bash
kubectl get pods -A | grep -vE "Running|Completed"
```
Note
See config/samples/skills-configmap.yaml in the source repo for a full example with Kubernetes operations skills.
Custom Instructions (AGENT.md)¶
Shape agent behaviour with persistent instructions:
apiVersion: v1
kind: ConfigMap
metadata:
name: copilot-agent-md
namespace: kube-copilot-agent
data:
AGENT.md: |
# Agent Instructions
- Always confirm the current cluster context before acting.
- Never modify resources in production namespaces (prefixed with `prod-`).
- Prefer read-only operations unless explicitly asked to make changes.
Dynamic Configuration (Runtime Settings)¶
The web UI includes a Settings dialog that lets you configure agent behaviour at runtime — no pod restart or Helm upgrade needed.
graph LR
subgraph settings["⚙️ Settings Dialog"]
A["🧠 Model<br/><sub>Select LLM model</sub>"]
B["📝 Instructions<br/><sub>Edit copilot-instructions.md</sub>"]
C["🛠️ Skills<br/><sub>Add/edit/delete SKILL.md</sub>"]
D["🤖 Custom Agents<br/><sub>Define agent personas</sub>"]
E["🔑 BYOK<br/><sub>External provider config</sub>"]
end
subgraph storage["Storage"]
PVC[("PVC<br/><sub>instructions · skills<br/>custom-agents.json</sub>")]
Secret[("K8s Secret<br/><sub>API key</sub>")]
end
A --> |"per-request"| SDK["Agent Server"]
B --> |"PUT /config/instructions"| PVC
C --> |"PUT /config/skills/{name}"| PVC
D --> |"PUT /config/agents"| PVC
E --> |"upsert Secret"| Secret
style settings fill:#1a1a2e,stroke:#00bcd4,color:#e0e0e0
style storage fill:#16213e,stroke:#ffc107,color:#e0e0e0
Model Selection¶
Switch between available Copilot models at runtime. The UI queries /models (backed by client.list_models() from the SDK) and sends the chosen model with each request via the session_config.model field.
Runtime Instructions¶
Edit the agent's copilot-instructions.md file directly from the UI. Changes are written to the PVC and take effect on the next session — no restart needed.
Runtime Skills¶
Create, edit, or delete skills through the UI. Each skill is stored as a SKILL.md file under $COPILOT_HOME/skills/<name>/ on the PVC.
Custom Agents¶
Define inline agent personas with specific prompts and tool restrictions. Stored as custom-agents.json on the PVC and loaded into each SDK session.
BYOK (Bring Your Own Key)¶
Configure an external OpenAI-compatible or Azure OpenAI provider:
- Provider type and base URL are stored in the
KubeCopilotSendCR'ssessionConfig.providerfield - API keys are stored securely in a Kubernetes Secret and read by the controller at reconciliation time — never persisted in CRDs
# Example: KubeCopilotSend with session config
apiVersion: kubecopilot.io/v1
kind: KubeCopilotSend
metadata:
name: my-question
namespace: kube-copilot-agent
spec:
agentRef: github-copilot-agent
message: "What is the cluster health?"
sessionConfig:
model: "gpt-4o"
provider:
type: openai
baseURL: "https://api.openai.com/v1"
secretRef: my-provider-secret # K8s Secret with 'api-key' key
ServiceAccount-Based Permissions¶
By default, agents interact with the cluster through a manually-created kubeconfigSecretRef. The RBAC configuration option lets the operator manage all of this automatically — creating a dedicated ServiceAccount, RBAC Role/ClusterRole, bindings, and a kubeconfig Secret so each agent runs with least-privilege access.
How it works¶
When you set spec.rbac in a KubeCopilotAgent, the operator:
- Creates a ServiceAccount (name defaults to
<agent-name>-saor usesrbac.serviceAccountName) - Creates a Role (namespace-scoped) with the rules you specify in
rbac.rules - Creates a RoleBinding to bind the ServiceAccount to that Role
- Creates a ClusterRole (cluster-scoped) with the rules in
rbac.clusterRules(optional) - Creates a ClusterRoleBinding to bind the ServiceAccount to that ClusterRole
- Generates a kubeconfig Secret that uses the ServiceAccount token for authentication
- Mounts the kubeconfig into the agent pod at
/copilot/.kube/config
Namespace-scoped resources (ServiceAccount, Role, RoleBinding, kubeconfig Secret) are owned by the KubeCopilotAgent and garbage-collected on deletion. Cluster-scoped resources (ClusterRole, ClusterRoleBinding) are cleaned up via a finalizer (kubecopilot.io/rbac-cleanup) since namespaced owners cannot GC cluster-scoped resources directly.
Note
spec.rbac is mutually exclusive with spec.kubeconfigSecretRef. Use one or the other.
AgentRBAC Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
serviceAccountName |
string |
No | Name of the ServiceAccount to create; defaults to <agent-name>-sa |
rules |
[]rbacv1.PolicyRule |
No | Namespace-scoped permissions (Role + RoleBinding) |
clusterRules |
[]rbacv1.PolicyRule |
No | Cluster-scoped permissions (ClusterRole + ClusterRoleBinding) |
CR Example¶
apiVersion: kubecopilot.io/v1
kind: KubeCopilotAgent
metadata:
name: my-agent
namespace: kube-copilot-agent
spec:
githubTokenSecretRef:
name: github-token
rbac:
serviceAccountName: my-agent-sa # optional, defaults to "<name>-sa"
rules: # namespace-scoped
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
clusterRules: # cluster-scoped (optional)
- apiGroups: [""]
resources: ["namespaces", "nodes"]
verbs: ["get", "list"]
Helm Example¶
# my-agent-rbac-values.yaml
githubToken:
existingSecret: github-token
rbac:
serviceAccountName: my-agent-sa
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
clusterRules:
- apiGroups: [""]
resources: ["namespaces", "nodes"]
verbs: ["get", "list"]
helm upgrade --install my-agent ./helm/github-copilot-agent \
--namespace kube-copilot-agent \
-f my-agent-rbac-values.yaml
Verifying Permissions¶
# Check what the ServiceAccount can do in the agent namespace
kubectl auth can-i --list \
--as=system:serviceaccount:kube-copilot-agent:my-agent-sa \
-n kube-copilot-agent
# Check cluster-scoped permissions
kubectl auth can-i list namespaces \
--as=system:serviceaccount:kube-copilot-agent:my-agent-sa
# Inspect the generated RBAC resources
kubectl get sa,role,rolebinding -n kube-copilot-agent | grep my-agent
kubectl get clusterrole,clusterrolebinding | grep my-agent
Chunk Types (Real-time Streaming)¶
KubeCopilotChunk resources are created as the agent works:
chunkType |
Description |
|---|---|
thinking |
Agent's internal reasoning |
tool_call |
Agent invoking a skill or tool |
tool_result |
Result returned from the tool |
response |
Final answer text |
info |
Processing status (e.g. "Processing: ...") |
error |
Error during processing or cancellation |