This page is for operators, platform engineers, and security reviewers evaluating whether KubeStellar Console is safe to install in their environment. It answers three questions:
The canonical, code-grounded version of this document lives in the source tree at docs/security/SECURITY-MODEL.md — every claim there is cited with file and line numbers. This page is the public-docs summary; read the source doc for the full detail.
The three-process architecture: your browser, a Go backend (serves UI, bootstrap-only identity), and kc-agent running on your own machine (identity is your kubeconfig). Every cluster mutation flows through kc-agent.
Legend:
127.0.0.1:8585 (loopback). kc-agent reads ~/.kube/config and stores AI keys at ~/.kc/config.yaml (mode 0600).The Go backend’s pod ServiceAccount is used only for three things:
ResourceQuota on it. Users typically do not have namespace-create RBAC; the console is the authorized policy layer for this specific flow.Deployment to roll out a new image.Every other user-initiated Kubernetes action goes through kc-agent on the user’s own machine, using the user’s own kubeconfig. Per-cluster RBAC is enforced by the target cluster’s apiserver against the user’s real identity, not against the console’s pod SA.
Consequences:
kc-agent binds 127.0.0.1:8585 by default and is not configurable to bind any other address. The bind is the primary defense against network-level access. Additional layers protect against local attackers (rogue browser tabs, other processes on the same machine):
Four layers gate every request to kc-agent:
127.0.0.1:8585. Remote LAN hosts are rejected at the OS socket layer.127.0.0.1.KC_AGENT_TOKEN for this fourth layer; recommended when you cannot assume all local processes are trusted.The console is designed to work in three progressively stricter network postures.
Posture A — fully (default): everything enabled.
Posture B — restricted egress, no AI: all cluster-management features still work.
Posture C — fully air-gapped: no public AI, no GitHub OAuth, optional local LLM.
api.anthropic.com, api.openai.com, generativelanguage.googleapis.com, api.groq.com, and openrouter.ai. All cluster-management features continue to work; AI-driven features fall back to deterministic/rule-based behavior.Three providers honor a base-URL override, so you can redirect the AI traffic to any OpenAI-compatible endpoint on your own infrastructure:
Override environment variables:
| Provider | Base URL env var | Use case |
|---|---|---|
| Groq | GROQ_BASE_URL | Ollama, vLLM, LM Studio, LocalAI, any OpenAI-compatible local runner |
| OpenRouter | OPENROUTER_BASE_URL | Corporate LLM gateway, internal OpenAI-compatible frontends |
| Open WebUI | OPEN_WEBUI_URL | Existing Open WebUI deployments |
Example — point the Groq provider slot at Ollama:
export GROQ_API_KEY=unused-but-nonempty
export GROQ_BASE_URL=http://localhost:11434/v1
export GROQ_MODEL=llama3.1:8b
./bin/kc-agent
The request payload is unchanged (OpenAI chat-completions wire format), so any OpenAI-compatible local runner works without the console knowing or caring which.
Using a local or on-prem LLM is the strongest way to keep prompts and conversation history inside your trust boundary. When the base URL points at something running on your own network, AI traffic never leaves the machine (for a loopback endpoint) or never leaves your perimeter (for an internal gateway). This is the right choice for operators in regulated, air-gapped, or high-sensitivity environments — not because the console is broken without a public provider, but because the security posture matches what those environments need.
| Data | Browser | Go backend | kc-agent | AI provider |
|---|---|---|---|---|
~/.kube/config | no | no | yes (read from local disk) | never |
| Cluster API credentials (tokens, client certs) | no | no | yes (extracted from kubeconfig) | never |
| Pod logs, events, YAML manifests | yes (when viewing) | no (except its own cluster) | yes (relayed from kubectl) | if the user pastes them into a chat |
| AI chat prompts + conversation history | yes | no | yes (forwards to provider) | yes (provider sees what you send) |
| AI API keys | no (never sent to browser) | no | yes (~/.kc/config.yaml or env) | used as Authorization header |
| GitHub OAuth client secret | no | yes (env var) | no | no |
The kubeconfig, raw secrets, and cluster credentials never cross the process boundary from kc-agent. The thing kc-agent sends outward is the chat payload to the configured AI provider — system prompt + message history + current prompt. It does not auto-upload the kubeconfig, bearer tokens, or arbitrary cluster objects.
Report security issues following the project’s security policy:
docs/security/SECURITY-MODEL.md links to the disclosure process and the upstream self-assessment at docs/security/SELF-ASSESSMENT.md.The console also has an AI-specific security document covering the threat surfaces of its LLM-backed workflows (Claude Code review, auto-qa, GA4 error monitor, kc-agent/MCP). It addresses six threat categories: external prompt injection, insider/compromised credentials, DoS/resource exhaustion, agent drift, supply chain, and agent-to-agent injection.
See docs/security/SECURITY-AI.md in the console repo for the full threat model and audit checklist.
pods/exec permission before opening an exec WebSocket stream, closing a privilege-escalation gap.docs/security/SECURITY-MODEL.md — the canonical source-grounded version of this documentdocs/security/SECURITY-AI.md — AI automation threat model (prompt injection, supply chain, agent drift)