Protection Summary
| Layer | Protection | Status |
|---|---|---|
| Authentication | Constant-time token comparison (crypto/subtle) | Active |
| Shell | POSIX quoting to prevent shell argument injection | Active |
| Editors | EDITOR validation against allowlist of known editors | Active |
| Commands | 50+ regex patterns for dangerous command detection | Active |
| Policies | Word-boundary matching to prevent permission escalation | Active |
| gRPC | Reflection disabled by default (hides service schema) | Active |
| Binaries | stty resolution via exec.LookPath (prevents PATH injection) | Active |
| Containers | read-only filesystem, no-new-privileges, drop ALL capabilities | Active |
| Kubernetes | Namespace-scoped RBAC by default, restrictive SecurityContext | Active |
| Network | Optional TLS with warning when disabled | Active |
gRPC Server Authentication
Bearer Token with Constant-Time Comparison
The gRPC server uses Bearer token authentication in theauthorization header of each request. Token comparison uses crypto/subtle.ConstantTimeCompare, which prevents timing attacks — an attacker cannot infer correct characters by measuring response time.
- Via flag
- Via environment variable
The
/Health endpoint is always accessible without authentication to allow health checks from load balancers and orchestrators.TLS (Optional)
TLS is fully optional. In a local development environment, you can run without TLS without issues. For production, we strongly recommend enabling TLS:- Production (with TLS)
- Development (without TLS)
Shell Injection Protection
ShellQuote — Secure POSIX Quoting
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
Protected Points
| File | Context |
|---|---|
cli/agent_mode.go | Dry-run echo of commands (simulation) |
cli/cli.go | Sourcing shell configuration file (~/.bashrc, etc.) |
cli/agent/command_executor.go | Sourcing shell configuration file (interactive execution) |
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.
EDITOR Validation
When the user edits commands in agent mode, theEDITOR variable is validated against an allowlist of known editors:
Command Validation
50+ Detection Patterns
TheCommandValidator analyzes each command suggested by the AI before execution, checking against more than 50 regex patterns that cover:
| Category | Examples |
|---|---|
| Data destruction | rm -rf /, dd if=, mkfs, drop database |
| Remote execution | curl | bash, wget | sh, base64 | bash |
| Code injection | python -c, perl -e, ruby -e, node -e, php -r, eval |
| Command substitution | $(curl ...), `wget ...` |
| Process substitution | <(cmd), >(cmd) |
| Privilege escalation | sudo, chmod 777 /, chown -R / |
| Network manipulation | nc -l, iptables -F, /dev/tcp/ |
| Kernel | insmod, modprobe, rmmod, sysctl -w |
| Evasion | ${IFS;cmd}, VAR=x; bash, export PATH= |
Custom Denylist
Add your own patterns via environment variable:sudo Control
Coder Mode Governance (Policy Manager)
Word Boundary Matching
The policy system uses word boundary matching to prevent permission escalation by prefix. Example:| Rule | Command | Result |
|---|---|---|
@coder read = allow | @coder read file.txt | Allowed |
@coder read = allow | @coder readlink /tmp | Blocked (ask) |
@coder read --file /etc = deny | @coder read --file /etc/passwd | Blocked (deny) |
/, =, etc.) and not a word continuation (letter, digit, -, _). This ensures that read does not match readlink.
Default Rules
Read commands are allowed by default:gRPC Server Security
gRPC Reflection (Disabled by Default)
gRPC reflection exposes the complete service schema, allowing tools likegrpcurl and grpcui to discover and call all RPCs. In production, this can facilitate reconnaissance by attackers.
| Variable | Description | Default |
|---|---|---|
CHATCLI_GRPC_REFLECTION | Enables gRPC reflection (true/false) | false |
Security Interceptors
All requests pass through a chain of interceptors:Version Check
ChatCLI automatically checks whether a newer version is available on GitHub. To disable (e.g., air-gapped environments or CI/CD):| Variable | Description | Default |
|---|---|---|
CHATCLI_DISABLE_VERSION_CHECK | Disables automatic version check (true/false) | false |
Container Security (Docker)
The project’sdocker-compose.yml includes the following hardening measures:
What Each Measure Does
| Measure | Protection |
|---|---|
read_only: true | Prevents malware from writing files to the container filesystem |
tmpfs | Provides an in-memory /tmp directory with limited size |
no-new-privileges | Prevents child processes from gaining more privileges than the parent |
| Resource limits | Prevents excessive CPU/memory consumption (DoS) |
Kubernetes Security (Helm)
Pod SecurityContext
The Helm chart defines a restrictive SecurityContext by default:Namespace-Scoped RBAC (Default)
By default, the chart creates Role and RoleBinding (namespace-scoped) instead of ClusterRole. This ensures ChatCLI only has access to the namespace where it is deployed.clusterWide:
Automatic tmpfs
When
securityContext.readOnlyRootFilesystem is true, the chart automatically mounts an emptyDir volume at /tmp (limited to 100Mi) so the application can write temporary files.Security Environment Variables
Summary of all security-related variables:| Variable | Description | Default |
|---|---|---|
CHATCLI_SERVER_TOKEN | gRPC server authentication token | "" (no auth) |
CHATCLI_SERVER_TLS_CERT | Server TLS certificate | "" |
CHATCLI_SERVER_TLS_KEY | Server TLS key | "" |
CHATCLI_GRPC_REFLECTION | Enables gRPC reflection | false |
CHATCLI_DISABLE_VERSION_CHECK | Disables version check | false |
CHATCLI_AGENT_ALLOW_SUDO | Allows sudo in agent mode | false |
CHATCLI_AGENT_DENYLIST | Additional regex patterns to block (; separated) | "" |
CHATCLI_AGENT_CMD_TIMEOUT | Execution timeout per command | 10m |
Credential Encryption
OAuth credentials are stored with AES-256-GCM encryption in~/.chatcli/auth-profiles.json. The encryption key is automatically generated and saved in ~/.chatcli/.auth-key with permission 0600 (owner-only read).
| File | Permission | Content |
|---|---|---|
~/.chatcli/auth-profiles.json | 0600 | Encrypted OAuth credentials |
~/.chatcli/.auth-key | 0600 | AES-256-GCM key |
~/.chatcli/coder_policy.json | 0600 | Coder policy rules |
Best Practices for Production
Keep gRPC reflection disabled
Do not set
CHATCLI_GRPC_REFLECTION=true in production. Use only for local debugging.Use namespace-scoped RBAC
Keep
rbac.clusterWide: false (default) unless you need to monitor multiple namespaces.Next Steps
Coder Mode Governance
Policy rules to control what the Coder can execute.
Configure the server
gRPC server deployment and configuration.
Deploy with Docker and Helm
Complete containerized deployment guide.
Configuration reference
All available environment variables.