Security Overview
The table below summarizes all active protections across every layer of the stack.Authentication and Authorization
JWT Authentication (Recommended)
The gRPC and REST servers support JWT-based authentication with configurable issuer, audience, and secret. JWTs carry role claims that map to RBAC policies.- HS256 (Symmetric)
- Via Helm
RBAC Roles
Three built-in roles control access to API endpoints and operations:/Health endpoint is always accessible without authentication to support load balancer and orchestrator health checks.Legacy Bearer Token
For simpler deployments, the server supports static bearer token authentication with constant-time comparison (crypto/subtle.ConstantTimeCompare), preventing timing attacks.
- Via flag
- Via environment variable
OAuth 2.0 + PKCE
ChatCLI supports OAuth 2.0 with PKCE for the following providers:Encryption and Data Protection
AES-256-GCM Credential Encryption
All OAuth credentials are encrypted at rest using AES-256-GCM in~/.chatcli/auth-profiles.json. The encryption key is automatically generated and stored with strict permissions.
Session Encryption
Session data can be encrypted at rest when a custom encryption key is provided:TLS 1.3 Transport Security
- Server TLS
- Mutual TLS (mTLS)
- Development (no TLS)
kubectl logs even if the structured logger cannot flush before the crash.Environment Variable Redaction
Sensitive environment variables are automatically redacted in logs and error messages. You can control the redaction behavior:OS Keychain Integration
ChatCLI can store encryption keys in the OS keychain instead of the filesystem:Agent Mode Security
Command Allowlist (Strict Mode)
In strict mode, only commands from the allowlist can be executed. The default allowlist includes 150+ safe commands organized by category:File Operations (30+ commands)
File Operations (30+ commands)
Development Tools (40+ commands)
Development Tools (40+ commands)
System Utilities (30+ commands)
System Utilities (30+ commands)
Network and Cloud (30+ commands)
Network and Cloud (30+ commands)
Text Processing (20+ commands)
Text Processing (20+ commands)
Custom Allowlist
Extend the allowlist with your own commands:Denylist Patterns (Permissive Mode)
In permissive mode, 50+ regex patterns detect and block dangerous commands:Read Path Blocking
In strict workspace mode, the agent can only read files within the current workspace directory:Shell Configuration Sourcing
By default, shell configuration files (~/.bashrc, ~/.zshrc) are not sourced during agent command execution to prevent malicious aliases and functions:
Input guard — typeahead protection in security prompts
When a security box appears (coder/agent mode), three layers defend against accidental typing being consumed as a y/n response:- Flush kernel TTY —
TCIFLUSH(Linux) /TIOCFLUSH(BSD/Darwin) /FlushConsoleInputBuffer(Windows) discards bytes in the kernel queue before the box renders. - Drain channel — empties the centralized non-blocking stdin channel (the 10-line buffer the reader goroutine uses).
- Intent debounce — discards any input that arrives in the first 250ms after the box is drawn (minimum human reaction window).
stty sane on the controlling /dev/tty to recover from a prior go-prompt teardown that may have left the terminal in raw mode (echo off). Without this reset, you type and don’t see characters on screen — even though the kernel is capturing them.
Output Sanitizer
Agent command output is sanitized before being sent to the LLM:- ANSI escape sequences are stripped
- Output is truncated to prevent context overflow
EDITOR Validation
When the user edits commands in agent mode, theEDITOR variable is validated against an allowlist of known editors:
Kubeconfig Access Control
Control whether agent commands can access kubeconfig:Shell Injection Protection
All code paths where dynamic values are interpolated into shell commands use theutils.ShellQuote() function, which applies POSIX quoting with single quotes:
- Quote injection:
'; rm -rf /; echo ' - Command substitution:
$(malicious)or`malicious` - Variable expansion:
$HOME,${PATH} - Pipe/redirection:
| cat /etc/passwd,> /etc/crontab
Binary Resolution via LookPath
Thestty binary (used to restore the terminal) is resolved once at startup via exec.LookPath("stty"), returning the absolute path. This prevents an attacker from placing a malicious stty in the PATH.
Plugin Security
Ed25519 Signature Verification
ChatCLI plugins are verified using Ed25519 digital signatures. Each plugin binary must be signed with the developer’s private key, and the corresponding public key must be registered.Generate a signing key pair
Sign your plugin
Distribute with signature
Verify on install
Quarantine for Unsigned Plugins
Unsigned plugins enter a quarantine period before they can execute:Plugin Permission Manifest
Each plugin declares its required permissions in a manifest:gRPC Server Security
SSRF Prevention
The server blocks outbound requests to private IP ranges, preventing Server-Side Request Forgery attacks:10.0.0.0/8,172.16.0.0/12,192.168.0.0/16(RFC 1918)127.0.0.0/8(loopback)169.254.0.0/16(link-local, including cloud metadata endpoints)::1/128,fc00::/7(IPv6 private)
Rate Limiting
Token-bucket rate limiting protects against abuse and DoS:Message Size Limits
Prevent memory exhaustion from oversized messages:Input Validation
All RPC fields are validated before processing:- String length limits on all text fields
- Enum value validation for severity, status, etc.
- Namespace and resource name format validation (Kubernetes naming rules)
- Timestamp range validation
Audit Logging
All sensitive operations are recorded in structured JSON audit logs:Bind Address
Control which network interface the server listens on:Interceptor Chain
All requests pass through a chain of gRPC interceptors:Recovery
Rate Limiting
Logging
Auth
RBAC
gRPC Reflection (Disabled by Default)
gRPC reflection exposes the full service schema, allowing tools likegrpcurl and grpcui to discover and call all RPCs. In production, this can facilitate reconnaissance by attackers.
Kubernetes Operator Security
Fail-Closed Authentication
The operator webhook uses fail-closed authentication: if the authentication service is unavailable, all requests are denied. This prevents unauthorized access during outages. API keys are hot-reloaded every 30 seconds with the following priority order:- Secret
chatcli-operator-secrets(priority) —api-keysfield containing a YAML list of{key, role, description}entries - ConfigMap
chatcli-operator-config(fallback) — sameapi-keysfield - Reject the request (or accept in dev-mode if
CHATCLI_OPERATOR_DEV_MODE=true)
Resource Type Allowlist
The operator can only manage resources from a configurable allowlist:Log Scrubbing
Secrets, tokens, and sensitive data are automatically scrubbed from operator logs:CORS Policy
The REST API enforces a configurable CORS policy:RBAC and NetworkPolicy
- Namespace-Scoped RBAC (Default)
- Cluster-Wide RBAC
Pod SecurityContext
The Helm chart defines a restrictive SecurityContext by default:securityContext.readOnlyRootFilesystem is true, the chart automatically mounts an emptyDir volume at /tmp (limited to 100Mi) so the application can write temporary files.Operator Dev Mode
For local development, the operator can run in dev mode with relaxed security:Operator TLS
Container Security (Docker)
Thedocker-compose.yml includes the following hardening measures:
CI/CD Security
ChatCLI’s CI/CD pipeline includes multiple security checks:govulncheck
gosec
Dependabot
.github/dependabot.yml.Cosign Image Signing
Coder Mode Governance (Policy Manager)
Word Boundary Matching
The policy system uses word boundary matching to prevent permission escalation by prefix. Example:/, =, etc.) and not a word continuation (letter, digit, -, _). This ensures that read does not match readlink.
Default Rules
Read commands are allowed by default:Security Environment Variables Reference
Complete reference of all security-related environment variables:Server Security
Agent Security
Plugin and Auth Security
Operator Security
Version Check
ChatCLI automatically checks for newer versions on GitHub. To disable (e.g., air-gapped environments or CI/CD):Production Best Practices
Use JWT authentication with RBAC
Enable TLS in production
Use strict agent security mode
Require plugin signatures
CHATCLI_ALLOW_UNSIGNED_PLUGINS as false (default). Only install plugins with valid Ed25519 signatures.Configure rate limiting
Enable audit logging
Keep gRPC reflection disabled
CHATCLI_GRPC_REFLECTION=true in production. Use only for local debugging.Use namespace-scoped RBAC
rbac.clusterWide: false (default) unless you need to monitor multiple namespaces.Set resource limits
Enable environment variable redaction
Use OS keychain for key storage
Keep ChatCLI updated
CHATCLI_DISABLE_VERSION_CHECK, check periodically: