For developer-facing documentation on using environment variables and secrets, see Environment Variables & Secrets.
Overview
Skyhook uses Bitnami Sealed Secrets to encrypt sensitive configuration data before storing it in Git repositories. This ensures secrets remain secure even when version-controlled alongside application code.How Sealed Secrets Work
Sealed Secrets uses asymmetric cryptography to enable GitOps-compatible secret management:Architecture
Key Components
Public Key (Cluster-Specific):- Each cluster’s Sealed Secrets controller generates a unique public/private key pair
- Skyhook fetches the public key to encrypt secrets
- Public keys are safe to store or share
- Stored securely within the Sealed Secrets controller in the cluster
- Never leaves the cluster
- Used to decrypt SealedSecret resources into standard Kubernetes Secrets
- Runs in the target Kubernetes cluster (typically in the
kube-systemnamespace) - Watches for SealedSecret custom resources
- Decrypts them into standard Secrets that pods can consume
- Manages key rotation and renewal
Security Model
The security model ensures zero-knowledge architecture:- Encryption happens client-side: Skyhook encrypts secrets before they leave the UI
- Git stores encrypted data: Only encrypted
SealedSecretresources are committed to repositories - Decryption happens in-cluster: Only the target cluster’s controller can decrypt secrets
- Skyhook has no access: The platform cannot decrypt secrets; only your clusters can
- Secrets are safe to commit to version control
- Git provides audit trail (who changed what, when)
- No central secret store vulnerability
- Compatible with GitOps workflows
- Cluster isolation via cluster-specific keys
Installing Sealed Secrets
The Sealed Secrets controller must be installed on all clusters where you want to use secrets.Installation via Skyhook GitOps
Recommended: Install via Skyhook’s GitOps settings for automated management. Prerequisites:- ArgoCD installed on your management cluster (see GitOps Setup)
- Clusters connected to Skyhook
- Navigate to GitOps Settings in Skyhook
- Under Featured Addons, locate Sealed Secrets controller
- Select the clusters where you want secrets support (typically all clusters)
- Review the default configuration or customize as needed
- Generate and merge the pull request to deploy the controller
- Namespace:
kube-system - Controller image:
quay.io/bitnami/sealed-secrets-controller - Key renewal: Enabled (30-day rotation)
- Service type:
ClusterIP
Manual Installation
Alternatively, install Sealed Secrets manually using kubectl or Helm: Using kubectl:Verifying Installation
Check that the controller is running:How Skyhook Integrates with Sealed Secrets
Secret Encryption Flow
When a developer adds or updates a secret in Skyhook:- Fetch Public Key: Skyhook retrieves the public certificate from the target cluster’s Sealed Secrets controller
- Encrypt Secret: The secret value is encrypted client-side using the public key
- Create SealedSecret: A
SealedSecretKubernetes custom resource is generated - Store in Git: The encrypted SealedSecret is committed to the deployment repository
- Deploy via GitOps: ArgoCD or another GitOps tool syncs the SealedSecret to the cluster
- Controller Decrypts: The Sealed Secrets controller decrypts the SealedSecret into a standard Kubernetes Secret
- Pods Consume: Application pods mount the Secret as environment variables or files
Secret Storage in Git
Sealed Secrets are stored in your deployment repository as Kubernetes custom resources:encryptedData fields contain encrypted values that are safe to commit to Git.
Environment-Specific Secrets
Skyhook creates a SealedSecret resource for each service, named after the service itself (e.g.,my-service) and deployed to the service’s namespace. Secrets are environment-specific, with separate encrypted values for each environment (production, staging, development, etc.) stored within the same SealedSecret resource.
This ensures:
- Environment isolation through separate encrypted values
- Different credentials per environment
- Cluster-specific encryption (production cluster can’t decrypt staging secrets if using different controllers)
Reloader Integration
Overview
Kubernetes does not automatically restart pods when ConfigMaps or Secrets change. Reloader solves this by monitoring configuration resources and triggering rolling restarts when changes are detected.How Reloader Works
- Watch for Changes: Reloader watches ConfigMaps and Secrets referenced by Deployments, StatefulSets, and DaemonSets
- Detect Updates: When a ConfigMap or Secret is updated, Reloader detects the change
- Trigger Restart: Reloader updates an annotation on the Deployment, triggering a rolling restart
- Zero Downtime: Pods restart gracefully with the new configuration
Installing Reloader
Via Skyhook GitOps:- Go to GitOps Settings
- Locate Reloader under Featured Addons
- Select target clusters
- Generate and merge the pull request
Enabling Per-Service
Developers can enable auto-reload for individual services in the Env Vars & Secrets tab by checking Reload on Environment Variables or Secrets Update. This adds the necessary annotations to the service’s Deployment:Troubleshooting
Secrets Not Decrypting
Symptoms: SealedSecret exists but no corresponding Secret is created Causes:- Sealed Secrets controller not installed or not running
- Wrong cluster public key used for encryption
- Controller doesn’t have RBAC permissions
Key Rotation Issues
Symptoms: Old secrets work but newly created secrets fail to decrypt Causes:- Cluster certificate was rotated but Skyhook is using old public key
- Manual certificate replacement without proper key backup
- Ensure Skyhook refetches the cluster’s current public key
- Verify the controller’s certificate:
Pods Not Reloading
Symptoms: Secrets updated but pods still use old values Causes:- Reloader not installed
- Reloader annotations missing or incorrect
- Reloader not watching the correct namespace
kubectl Integration
Sealing Secrets Manually
Thekubeseal CLI can manually encrypt secrets:
Install kubeseal:
Backing Up Encryption Keys
Important: Back up the Sealed Secrets controller’s private key to prevent data loss during cluster migrations. Export private key:Security Best Practices
Key Management
- Backup private keys: Store sealed-secrets controller keys securely for disaster recovery
- Rotate keys regularly: Enable automatic key rotation (default: 30 days)
- Separate keys per cluster: Never share private keys between clusters
Access Control
- Limit RBAC: Restrict who can view/edit Secrets and SealedSecrets
- Audit changes: Review Git history for unauthorized secret modifications
- Encrypt Git repos: Use private repositories with strict access controls
Secret Hygiene
- Rotate secrets: Update API keys, passwords, and tokens periodically
- Delete unused secrets: Remove deprecated secrets to reduce attack surface
- Monitor usage: Track which secrets are actually being used
