This document describes how to manage sensitive credentials and API keys for KubeTTY deployments.
KubeTTY requires several API keys and credentials to function properly. These secrets are injected into the pod as environment variables from Kubernetes Secrets, keeping them separate from the Docker image and git repository.
- Purpose: Access GitHub repositories, create issues, and interact with GitHub API
- Type: Personal Access Token (classic) or Fine-grained token
- Scopes needed:
repo(full repository access)workflow(if managing workflows)
- How to generate: https://github.com/settings/tokens
- Purpose: Access OpenAI GPT models for AI assistance
- Type: OpenAI API key
- Format: Starts with
sk-proj-orsk- - How to generate: https://platform.openai.com/api-keys
- Purpose: Specify the Google Cloud project for GCP operations
- Type: GCP Project ID (string)
- Note: This is not strictly secret but treated as configuration
- How to find: https://console.cloud.google.com/
- Purpose: Authenticate with Nexmonyx services
- Type: Access key ID
- How to generate: Contact your Nexmonyx administrator
- Purpose: Secret key for Nexmonyx authentication
- Type: Secret access key
- How to generate: Contact your Nexmonyx administrator
- Purpose: Override the default Anthropic API endpoint
- Type: URL
- Default: Uses standard Anthropic API endpoint
- Use case: Internal proxy or custom endpoint
- Example:
http://172.25.1.66:8080
Create a Kubernetes secret with all required credentials:
kubectl create secret generic kubetty-api-keys \
-n kubetty-beacon-support \
--from-literal=github-token='YOUR_GITHUB_TOKEN_HERE' \
--from-literal=openai-api-key='YOUR_OPENAI_KEY_HERE' \
--from-literal=google-cloud-project='YOUR_GCP_PROJECT_ID' \
--from-literal=nexmonyx-access-key='YOUR_NEXMONYX_KEY_HERE' \
--from-literal=nexmonyx-access-secret='YOUR_NEXMONYX_SECRET_HERE' \
--from-literal=anthropic-base-url='YOUR_ANTHROPIC_URL_HERE'Notes:
- Replace
kubetty-beacon-supportwith your namespace - Replace all
YOUR_*_HEREplaceholders with actual values - Remove the
--from-literallines for any keys you don't need - The secret name (
kubetty-api-keys) should match the value invalues.yaml
Create a file kubetty-secrets.yaml (DO NOT commit this to git):
apiVersion: v1
kind: Secret
metadata:
name: kubetty-api-keys
namespace: kubetty-beacon-support
type: Opaque
stringData:
github-token: "YOUR_GITHUB_TOKEN_HERE"
openai-api-key: "YOUR_OPENAI_KEY_HERE"
google-cloud-project: "YOUR_GCP_PROJECT_ID"
nexmonyx-access-key: "YOUR_NEXMONYX_KEY_HERE"
nexmonyx-access-secret: "YOUR_NEXMONYX_SECRET_HERE"
anthropic-base-url: "YOUR_ANTHROPIC_URL_HERE"Apply the secret:
kubectl apply -f kubetty-secrets.yamlSecurity Warning: Delete this file after creating the secret, or store it securely outside the git repository.
Update your Helm values file (or use --set flags) to reference the secret:
apiSecrets:
existingSecret: "kubetty-api-keys"Or via command line:
helm upgrade --install kubetty-my-project ./deploy/helm \
-n kubetty-my-project \
-f deploy/helm/values.project-template.yaml \
--set apiSecrets.existingSecret=kubetty-api-keys \
--set env.sessionID="$(uuidgen)"kubectl get secret kubetty-api-keys -n kubetty-beacon-supportkubectl describe secret kubetty-api-keys -n kubetty-beacon-support# View all keys and values
kubectl get secret kubetty-api-keys -n kubetty-beacon-support -o yaml
# View specific key (base64 encoded)
kubectl get secret kubetty-api-keys -n kubetty-beacon-support -o jsonpath='{.data.github-token}' | base64 -d# List environment variables in running pod
kubectl exec -it -n kubetty-beacon-support deployment/kubetty-beacon-support -- env | grep -E 'GITHUB_TOKEN|OPENAI_API_KEY'
# Or use describe
kubectl describe pod -n kubetty-beacon-support -l app.kubernetes.io/name=kubetty | grep -A 20 "Environment:"Generate new API keys/tokens from respective services.
kubectl create secret generic kubetty-api-keys \
-n kubetty-beacon-support \
--from-literal=github-token='NEW_GITHUB_TOKEN' \
--from-literal=openai-api-key='NEW_OPENAI_KEY' \
--from-literal=google-cloud-project='YOUR_GCP_PROJECT_ID' \
--from-literal=nexmonyx-access-key='NEW_NEXMONYX_KEY' \
--from-literal=nexmonyx-access-secret='NEW_NEXMONYX_SECRET' \
--from-literal=anthropic-base-url='YOUR_ANTHROPIC_URL' \
--dry-run=client -o yaml | kubectl apply -f -kubectl rollout restart deployment/kubetty-beacon-support -n kubetty-beacon-supportkubectl rollout status deployment/kubetty-beacon-support -n kubetty-beacon-supportRevoke the old API keys/tokens from respective services to complete the rotation.
-
NEVER commit secrets to git
- Secrets are in
.gitignore- keep it that way - If secrets are accidentally committed, they must be considered compromised
- Rotate all exposed credentials immediately
- Use tools like
git-secretsorgitleaksto prevent accidental commits
- Secrets are in
-
Rotate exposed credentials immediately
- If you've previously stored secrets in
.bash_profileor other files, those credentials are exposed - Generate new tokens/keys from all services
- Update Kubernetes secrets with new values
- Revoke the old credentials
- If you've previously stored secrets in
-
Limit secret access
- Use Kubernetes RBAC to restrict who can read secrets
- Only grant
getpermissions on secrets to necessary service accounts - Audit who has access to secrets regularly
-
Use namespace isolation
- Deploy KubeTTY to dedicated namespaces
- Don't share secrets across namespaces unless necessary
- Use separate secrets for dev/staging/production
-
Enable etcd encryption at rest
- Ensure your Kubernetes cluster has etcd encryption enabled
- Secrets are base64-encoded by default, NOT encrypted
- Contact your cluster administrator to enable encryption
-
Monitor and audit
- Enable Kubernetes audit logging
- Monitor secret access patterns
- Set up alerts for unusual secret access
Only include the API keys that your specific deployment needs:
- GitHub Token: Only if you need GitHub integration
- OpenAI Key: Only if using OpenAI models
- GCP Project: Only if using Google Cloud services
- Nexmonyx Keys: Only if using Nexmonyx services
- Anthropic URL: Only if using a custom Anthropic endpoint
For multiple environments (dev, staging, production), create separate secrets in each namespace:
# Development namespace
kubectl create secret generic kubetty-api-keys \
-n kubetty-dev \
--from-literal=github-token='DEV_GITHUB_TOKEN' \
...
# Staging namespace
kubectl create secret generic kubetty-api-keys \
-n kubetty-staging \
--from-literal=github-token='STAGING_GITHUB_TOKEN' \
...
# Production namespace
kubectl create secret generic kubetty-api-keys \
-n kubetty-production \
--from-literal=github-token='PROD_GITHUB_TOKEN' \
...Error: Error: secret "kubetty-api-keys" not found
Solution: Create the secret before deploying:
kubectl create secret generic kubetty-api-keys -n YOUR_NAMESPACE --from-literal=github-token='...'Symptom: Commands fail with "authentication failed" or "missing API key"
Check:
- Verify secret exists:
kubectl get secret kubetty-api-keys -n NAMESPACE - Check secret has correct keys:
kubectl describe secret kubetty-api-keys -n NAMESPACE - Verify values.yaml references the secret:
apiSecrets.existingSecret: "kubetty-api-keys" - Check pod environment:
kubectl exec -it POD_NAME -- env | grep TOKEN
Symptom: Authentication works but with wrong account/project
Solution: Update the secret values and restart the pod:
kubectl create secret generic kubetty-api-keys ... --dry-run=client -o yaml | kubectl apply -f -
kubectl rollout restart deployment/kubetty-DEPLOYMENT -n NAMESPACEFor production environments or advanced use cases, consider:
- Encrypt secrets that can be safely committed to git
- Requires
sealed-secretscontroller in cluster - Good for GitOps workflows
- https://github.com/bitnami-labs/sealed-secrets
- Sync secrets from external sources (AWS Secrets Manager, HashiCorp Vault, etc.)
- Automatic rotation support
- Centralized secret management
- https://external-secrets.io/
- Full-featured secret management platform
- Dynamic secrets with automatic rotation
- Detailed audit logs
- Requires Vault infrastructure
- https://www.vaultproject.io/
- Encrypt individual values in YAML files
- Can be committed to git safely
- Integrates with cloud KMS services
- https://github.com/mozilla/sops
If you previously used .bash_profile with embedded secrets:
- Create the Kubernetes secret with your credentials (as described above)
- Deploy with Helm referencing the secret
- Verify the pod has environment variables set
- Test that services work with injected credentials
- Rotate all credentials that were in the old .bash_profile
- Delete any local copies of .bash_profile with secrets
The new sanitized .bash_profile is included in the Docker image but contains no secrets - all sensitive values come from Kubernetes.
If you encounter issues with secret management:
- Check this documentation thoroughly
- Verify all steps were followed correctly
- Check Kubernetes pod logs:
kubectl logs -n NAMESPACE POD_NAME - Consult your cluster administrator for cluster-specific secret policies
- Review Kubernetes RBAC permissions