We run AWS and Kubernetes with plain Helm installs from Jenkins—there's no GitOps tool involved. Our Helm values.yaml currently contains hardcoded environment-variable secrets and is kept only on the Jenkins server. We'd like to move it into Git for versioning and easier maintenance, but we don't want plaintext credentials in the repository.
One option is git-crypt, so the file remains encrypted in the repository and is only decrypted for authorized users or CI jobs. Are there important operational or security pitfalls with that approach? Since we already use AWS, would AWS Secrets Manager with the External Secrets Operator be a better pattern, or would that be unnecessarily complex for a small team? I'd also appreciate guidance on where SOPS with AWS KMS or Sealed Secrets would fit. The goal is a low-maintenance way to keep configuration manageable and secrets protected.
4 Answers
For runtime credentials, the cleaner pattern is usually to keep them in AWS Secrets Manager or Parameter Store and have Kubernetes retrieve them through the External Secrets Operator. Build-time credentials can stay in the CI system’s protected secret store. This avoids putting decryptable secret files directly into the repository and gives you centralized rotation and access control.
SOPS is often a better fit than git-crypt when you genuinely need encrypted configuration committed to Git. With an AWS KMS key, SOPS can encrypt only the sensitive fields, supports structured YAML, and lets you control decryption through AWS IAM. CI can decrypt the file only during deployment. git-crypt encrypts selected files based on repository key access, which makes key distribution and revocation more awkward; anyone who obtains the key can generally decrypt the protected history.
A values file does not need to contain the secret values themselves. Keep normal Helm configuration in Git, then reference Kubernetes Secrets or externally managed values for sensitive fields. AWS Secrets Manager is fine, but Parameter Store is often a cheaper and simpler choice for a small setup, especially when basic parameter versioning is enough.
Sealed Secrets is useful when the encrypted secret is meant to be stored as a Kubernetes custom resource and decrypted only by a controller in the cluster. It is less convenient if Jenkins needs to render and manage ordinary Helm values before deployment. For a small AWS-based team, External Secrets with Parameter Store or Secrets Manager is usually the lowest-maintenance long-term design; SOPS with KMS is a reasonable alternative when Git must contain the encrypted secret data itself.

That approach can work with Jenkins too; there’s no need to move CI just to use a hosted repository’s secret feature. The important part is keeping the credentials in a dedicated secret store with tightly scoped access.