Tips & Best Practices
Practical advice for getting the most out of ctx.
Production Safety
Contexts with environment: production or environment: prod:
- Display a warning indicator in prompts
- Require confirmation before switching (use
--confirmto skip) - Show a warning icon in status displays
Per-Shell Isolation
Each terminal session maintains its own context independently:
# Terminal 1
ctx use production
kubectl get pods # → production cluster
# Terminal 2
ctx use development
kubectl get pods # → development cluster
This means you can work in multiple environments simultaneously without conflicts.
Credential Isolation
ctx stores credentials separately per context to prevent conflicts:
| Service | Isolation |
|---|---|
| Vault | Per-context tokens in system keychain |
| Bitwarden | Per-context sessions in system keychain |
| 1Password | Per-context sessions in system keychain |
| Azure | Per-context config in ~/.config/ctx/state/cloud/<context>/azure/ |
| GCP | Per-context config in ~/.config/ctx/state/cloud/<context>/gcloud/ |
| AWS (profile) | Uses AWS profiles (managed by AWS CLI in ~/.aws/credentials) |
| AWS (aws-vault) | Per-context temp credentials in ~/.config/ctx/state/tokens/<context>.aws |
This means you can have multiple shells with different contexts, each with their own authenticated sessions - no more 403 errors from token conflicts.
Auto-Connect Features
Set up automatic connections on context switch to minimize manual steps:
vpn:
auto_connect: true # Connect VPN automatically
tunnels:
- name: db
auto_connect: true # Start tunnel automatically
aws:
sso_login: true # Run AWS SSO login automatically
vault:
auto_login: true # Run Vault login automatically
Database Access via Tunnels
Combine tunnels with database configuration for seamless access:
tunnels:
- name: postgres
local_port: 5432
remote_host: db.internal
remote_port: 5432
auto_connect: true
databases:
- name: primary
type: postgres
host: localhost # Connect via tunnel
port: 5432
database: mydb
username: app_user
Then:
The tunnel is automatically established, and PGHOST, PGPORT, PGDATABASE, and PGUSER are set.
Sharing VPN Across Contexts
If multiple contexts use the same VPN, configure them to not disconnect when switching:
# base-vpn-context.yaml
name: base-vpn-context
abstract: true
vpn:
type: openvpn
config_file: ~/vpn/company.ovpn
auto_connect: true
deactivate:
disconnect_vpn: false # Keep VPN when switching to another context
# project-a.yaml
name: project-a
extends: base-vpn-context
aws:
profile: project-a
# project-b.yaml
name: project-b
extends: base-vpn-context
aws:
profile: project-b
Now switching between project-a and project-b keeps the VPN connected.
Organizing Contexts with Inheritance
Use abstract base contexts to avoid repetition:
# company-base.yaml
name: company-base
abstract: true
ssh:
bastion:
host: bastion.company.com
user: deploy
identity_file: ~/.ssh/company_key
git:
user_email: "you@company.com"
urls:
jira: https://company.atlassian.net
wiki: https://wiki.company.com
Then inherit in specific contexts:
# project-prod.yaml
name: project-prod
extends: company-base
environment: production
aws:
profile: project-prod
Quick URL Access
Define frequently used URLs in your context:
urls:
nomad: http://localhost:4646
consul: http://localhost:8500
grafana: https://grafana.company.com
github: https://github.com/company-org
Then open them easily:
Uses your configured browser profile for proper SSO session.
Browser Profile for SSO
Keep SSO sessions isolated by using dedicated browser profiles:
All SSO flows (AWS SSO, Vault OIDC, GCP, Azure) will open in the correct profile, keeping your personal browsing separate.
List available profiles: