A lightweight, secure CLI tool for managing and accessing multiple Kubernetes clusters through a central gateway — without distributing kubeconfig files, opening inbound firewall rules, or requiring VPN access.
curl -fsSL https://raw.githubusercontent.com/why-xn/kbridge/master/install.sh | shOrganizations running multiple Kubernetes clusters face a compounding set of operational and security challenges:
- Credential sprawl — Every developer needs kubeconfig files for every cluster they access. Distributing, rotating, and revoking these credentials across teams is error-prone and doesn't scale.
- No visibility — There's no centralized record of who ran what command on which cluster. When incidents happen, tracing actions back to individuals requires stitching together logs from multiple sources.
- Network complexity — Cluster API servers are typically behind firewalls or private networks. Granting access means configuring VPNs, bastion hosts, or public endpoints — each adding attack surface and operational overhead.
- Coarse access control — Kubernetes RBAC is powerful but cluster-scoped. Enforcing consistent policies across many clusters requires duplicating configuration and hoping nothing drifts.
These problems get worse with every new cluster, team, and environment.
kbridge eliminates direct cluster access by placing a central gateway between users and clusters. Users interact with a single CLI tool; clusters run a lightweight agent that connects outbound to the gateway. No inbound ports, no kubeconfig distribution, no VPN required.
- Central Service (
kbridge-central) — API gateway that authenticates users, enforces access policies, queues commands, and collects results. The single point of control for all cluster access. - Cluster Agent (
kbridge-agent) — A small daemon deployed in each cluster that initiates an outbound gRPC connection to central. It polls for pending commands, executes them via kubectl locally, and returns results. Since connections are outbound-only, no firewall changes or public endpoints are needed. - CLI (
kb) — A user-friendly command-line tool that talks to central over REST. Developers use familiar kubectl syntax (kb get pods) without needing direct cluster credentials or network access. (Installed askb, with akbridgesymlink for back-compat.)
+----------------------------------+
| Kubernetes Cluster A |
| +-----------------------------+ |
| | kbridge-agent | |
+----------------+ | | +---------+ +----------+ | |
| | | | | gRPC | | K8s API | | |
| kbridge CLI | | | | Client |--| Client | | |
| | | | +---------+ +----------+ | |
| - login | +-----------+ | +-------+---------------------+ |
| - clusters |->| |<-+----------+ |
| - use | | Central | +----------------------------------+
| - kubectl |<-| Service |
| | | | +----------------------------------+
+----------------+ | - Auth | | Kubernetes Cluster B |
| - RBAC | | +-----------------------------+ |
| - Proxy | | | kbridge-agent | |
| - Audit |<-+--| +---------+ +----------+ | |
| | | | | gRPC | | K8s API | | |
+-----+-----+ | | | Client |--| Client | | |
| | | +---------+ +----------+ | |
v | +-------+---------------------+ |
+-----------+ | | |
| Database | +----------+-----------------------+
| (SQLite) | |
| |<------------+
+-----------+
CLI (kbridge) --HTTP REST--> Central Service <--gRPC-- Agent (per cluster) --> kubectl
- CLI to Central: REST API for login, cluster listing, and kubectl execution
- Agent to Central: gRPC for registration, heartbeats, command polling, and result submission
- Agent to K8s: kubectl for local command execution
User-facing command-line tool. kubectl by default — anything that isn't a
management command (login, logout, status, clusters, admin) is run as
kubectl on the selected cluster. (kbridge remains as a back-compat alias.)
kb login # Login to central service
kb logout # Logout
kb clusters list # List available clusters
kb clusters use <cluster> # Select active cluster
kb get pods # Run kubectl on the selected cluster
kb apply -f app.yaml # Any kubectl command works
kb logs -f deploy/api # Follow/watch (-f/-w) streams live until Ctrl-C
kb exec -it deploy/api -- sh # Interactive shell (full TTY; -i for stdin-only)
kb port-forward deploy/db 5432:5432 # Forward pod port to localhost
kb kubectl get pods # 'kubectl'/'k' force kubectl explicitly
kb status # Show current context
# Admin (requires the admin role)
kb admin users list # List users
kb admin users create --email dev@corp.com --name Dev
kb admin agent-tokens create --cluster prod # Generate an agent token
kb admin audit --user dev@corp.com # View the command audit logAPI gateway and control plane. Handles user authentication, cluster registry, RBAC enforcement, command proxying, and audit logging.
Lightweight daemon running in each Kubernetes cluster. Connects outbound to central, registers cluster metadata, polls for commands, executes kubectl locally, and submits results back.
- Go 1.25+
- kubectl installed
- Access to a Kubernetes cluster
make buildThis produces three binaries in bin/:
kb- CLI tool (with akbridgesymlink for back-compat)kbridge-central- Central servicekbridge-agent- Cluster agent
1. Start the central service:
# central requires a real jwt_secret (>=32 chars). Generate one:
export KBRIDGE_JWT_SECRET="$(openssl rand -hex 32)"
./bin/kbridge-central --config configs/central.yaml2. Start an agent (in a cluster with kubectl access):
./bin/kbridge-agent --config configs/agent.yaml3. Log in and use the CLI:
# Default admin is seeded from central.yaml (admin@kbridge.local / admin123 in
# the example config — change admin_password after first login for any real deployment).
./bin/kb login
./bin/kb clusters list
./bin/kb clusters use dev-cluster
./bin/kb get pods -ASee docs/installation.md for binary, Docker, and Helm installs, and the Documentation section below for full references.
server:
http_port: 8080 # REST API port
grpc_port: 9090 # gRPC server port
database:
driver: sqlite
path: kbridge.db
auth:
jwt_secret: "change-me" # required
admin_email: admin@kbridge.local # seeded on first start
admin_password: changeme
rbac:
policy_file: configs/rbac.yaml # empty = enforcement disabled
tls:
enabled: false # see docs/configuration.md#tlsSee docs/configuration.md for the complete reference (audit, bootstrap, TLS, env vars).
central:
url: localhost:9090 # Central gRPC address
token: dev-token # Authentication token
cluster:
name: dev-cluster # Unique cluster identifiercentral_url: https://central.example.com:8080
current_cluster: production-us-east
token: ""Agent:
| Variable | Description | Default |
|---|---|---|
KBRIDGE_CONFIG |
Path to config file | configs/agent.yaml or /etc/kbridge/agent.yaml |
KBRIDGE_CENTRAL_URL |
Central gRPC address | localhost:9090 |
KBRIDGE_AGENT_TOKEN |
Authentication token | — |
KBRIDGE_CLUSTER_NAME |
Cluster name | default |
Central:
| Variable | Description | Default |
|---|---|---|
KBRIDGE_CONFIG |
Path to config file | configs/central.yaml |
apiVersion: apps/v1
kind: Deployment
metadata:
name: kbridge-agent
namespace: kbridge-system
spec:
replicas: 1
template:
spec:
serviceAccountName: kbridge-agent
containers:
- name: agent
image: kbridge-agent:latest
env:
- name: KBRIDGE_CENTRAL_URL
value: "central.example.com:9090"
- name: KBRIDGE_CLUSTER_NAME
value: "production-us-east"
- name: KBRIDGE_AGENT_TOKEN
valueFrom:
secretKeyRef:
name: kbridge-agent
key: tokenUsers authenticate via kb login, which obtains a JWT token from central and stores it locally. All subsequent API calls include this token.
Access control is defined in a declarative, hot-reloaded policy file (ArgoCD-style), enforced on every kubectl command before it reaches a cluster. Roles match by cluster, namespace, resource, and verb with wildcards; bindings map users (by JWT email) to roles:
default: viewer
roles:
- name: developer
rules:
- clusters: ["dev-*", "staging"]
namespaces: ["*"]
resources: ["pods", "services", "deployments"]
verbs: ["get", "list", "logs", "exec", "apply"]
- name: admin
rules:
- clusters: ["*"]
namespaces: ["*"]
resources: ["*"]
verbs: ["*"]
bindings:
- subject: admin@kbridge.local
roles: ["admin"]See docs/rbac.md for the full policy reference.
Agents authenticate with database-backed tokens. Each token is a high-entropy
random secret, shown once at creation and stored only as an
HMAC-SHA256 digest keyed by a server-side pepper (auth.token_pepper, falling
back to jwt_secret) — so a stolen database alone cannot be used to verify
guessed tokens. Each token is bound to one cluster, can be revoked via the admin
API, and records a last_used_at timestamp on every successful registration for
staleness detection. Tokens are managed with
POST/GET/DELETE /api/v1/admin/agent-tokens.
Server-authenticated TLS secures the HTTP API, the agent↔central gRPC channel,
and the CLI. Generate a dev certificate with make certs; see
docs/configuration.md.
Every command (allowed, denied, failed, or timed out) is recorded with user,
cluster, command, result, and duration. Query via kb admin audit or
GET /api/v1/admin/audit.
| Component | Technology |
|---|---|
| Language | Go |
| CLI | Cobra + Viper |
| HTTP Server | Gin |
| RPC | gRPC + Protocol Buffers |
| Database | SQLite (modernc.org/sqlite, pure Go) |
| Auth | JWT (HS256) + bcrypt |
| Authorization | Declarative policy file (hot-reloaded) |
| Transport security | Server-authenticated TLS (HTTP + gRPC) |
| Config | YAML + environment variables |
| Guide | Contents |
|---|---|
| Installation | Binary, Docker, and Helm installation |
| Configuration | All central / agent / CLI options, incl. TLS |
| CLI reference | Every command with examples |
| API reference | All HTTP endpoints |
| RBAC | Policy file format and examples |
| Admin guide | Users, agent tokens, and audit logs |
| Security hardening | Post-install checklist, two-layer authz, least-privilege agent RBAC |
| Operations | Backup/restore, upgrades, token rotation, troubleshooting |
Elastic License 2.0 (ELv2) — free to use and modify. Commercial distribution and offering as a hosted/managed service are not permitted.