Sealed Secret

Provide a step-by-step guide for setting up a sealed secret client

Prerequisites

Install kubeseal by visiting the Bitnami Sealed Secrets repository and selecting the appropriate package for your platform: https://github.com/bitnami-labs/sealed-secrets?tab=readme-ov-file#kubeseal

Windows users: You can also install kubeseal via Scoop, Chocolatey, or the VSCode extension.

Retrieve the Sealed Secrets public key directly from our GitLab repository: here. This step is required—any unsealed Secret in a GitLab merge request will be automatically rejected.

How Sealed Secrets Work

  1. Encryption with a Public Key When you seal a Secret, kubeseal uses the public key (from the Sealed Secrets controller’s RSA key pair) to encrypt your data. You can fetch the public key from the Sealed Secrets GitHub repository. Admins can export it directly from our cluster.

  2. Decryption and Secret Creation on the Cluster The Sealed Secrets controller running in our Kubernetes cluster holds the corresponding private key. When it detects a SealedSecret resource, it decrypts the encryptedData fields and creates (or updates) a standard Kubernetes Secret object.

  3. Referencing in Helm Charts Once the Secret is created in the cluster, you can reference it in your Helm chart templates just like any other secret:

    env:
      - name: DB_USERNAME
        valueFrom:
          secretKeyRef:
            name: myapp-secret
            key: username
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef:
            name: myapp-secret
            key: password
    
  4. Safe GitOps Workflows Because SealedSecret manifests contain only encrypted data, you can safely store them in version control (e.g., GitLab, GitHub) without exposing sensitive information. The only unencrypted Secret lives inside the cluster, accessible only to the Sealed Secrets controller.

Tip: Make sure all Secrets in your Git repository are sealed. Any unsealed Secret manifest could leak credentials if committed.

Encrypting a Secret

Sealing an Existing Secret

kubeseal --cert sealed-secret.pem -o yaml -f mysec.yaml > mysec-sealed.yaml

Creating and Sealing a New Secret in One Step

kubectl -n [your-namespace] create secret generic [your-app-name]-secret \
  [--from-literal=username=user] \
  [--from-literal=password=pass] \
  --dry-run=client -o yaml | \
  kubeseal --cert ./sealed-secret.pem -o yaml > [your-app-name]-sealed.yaml
  • Replace [your-namespace] with your application’s namespace.
  • Replace [your-app-name] with your application’s name.
  • Replace the --from-literal=… flags with your secret values.
  • For additional Kubernetes Secret options, see: Kubernetes docs: kubectl create secret generic.

Example

The command below:

kubectl -n testns create secret generic testsec --from-literal=username=user --from-literal=password=pass --dry-run=client -o yaml > mysec.yaml

generates the following Secret manifest:

apiVersion: v1
data:
  password: cGFzcw==
  username: dXNlcg==
kind: Secret
metadata:
  creationTimestamp: null
  name: testsec
  namespace: testns

The command below:

kubectl -n testns create secret generic testsec --from-literal=username=user --from-literal=password=pass --dry-run=client -o yaml | kubeseal --cert sealed-secret.pem -o yaml > mysec-sealed.yaml

and the command:

kubeseal --cert sealed.pem -f mysec.yaml -o yaml > mysec-sealed.yaml

both produce the following SealedSecret manifest:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: testsec
  namespace: testns
spec:
  encryptedData:
    password: AgAP6lQTMc8VDzji1Oc6FY68uD++HJYK0/bXimSIj8ZCI1XOQCQinpnKkjSrhxPpkk9GwhoNBVRVUlUisfcSdMIy+5EiBZFM3sCN4tfOoqRbIjrj693/bwQVN2qM89f4t6ex35SNgxs9fkAR61mvla1jlZJysju9OpItkuqn56zW7RUROf0sm3Ep5sVjZ0k1QUavK4ckhWgpfwyibCcZK3IRJz2SMpE68sD5AcyG+De4doKZ0m0+FPlyJoEWQhxjWLDonKLUsfcMDsz+jK+VjIZ7oD4ytdaVDpwxaThdyXjwtUFINxMupit+pBNqqxG7nRf81aZonefPooj0D2Vp3pzUHSLMrSXe7qW+OrJpzbmnXbY+v1bJUv1VFeOIRLUjYjKRQSi2UGFmhtGVFmA/hTs03FkOl7TEFhVrL9YL0vMqjRpWZrHi/ccgdBlU98jD1L/qcyNg3FTsDCznszhj3dnGSiUq2u8R1LV8cZi2SwNDEC9EtuD0U4FgFLBjsILer01EXqRmEolwOc7bGaeXuJ2f1oThPsJVTK/eyEDO2rXYVFmPPo82mRrZkPf/28eKBenHW/AALjP9KcSTOxY845vZMv7eKfbCgjETlFdMt8T3CJkjlE+rr98HgmihDomF9UGQZk7EySSlZbSIdk/oOBj0tnY5XNwheV3aIc8e/lGeEyksmNyqGa4TXcnqf8yTahsgdQnP
    username: AgBb3eU9AVhw60HOM7JqhFzA8kF7fiP6Xm3nhPDJq4yJGO6RYtdYMkvTvMjeXKZxTFwMNXRh3I/P+00p2ZEBKXoOjXkwsvwkxKjB94ZvCR86c8rlJdXq/cHGx5M4KZWs6nP3XqlZsTzVhFdm4Gbdjk1zR5gRfI3xXmsf7hI/5MxGO8axGNa/z9YLS/klU/gK1S8epSUFY4ib/poHVHZLR2nN2LpL+7PHIsNR620LpPZYYFlgT3TOs+9lQZGT6kQEq/kx41NvWEihlaVDtVHoYq3Wt9KbL8yy1S0US1uvqgyLnI9nkIUvZaJI6UhIVBZbGxL2ApGTyJcO/2hdm3gP5SXtC2QC5Ins+UlKmuDCRjJ6R/fjUEONprGh0o3Fcsefbs7ohbLJkEhJ+PKVlvb5RvY+GirGjdP9PRLGNoiuMV7Idkxn/rbrXMLk6e9o6TsFmOQQQ40GQnTebDmaMPhB9NHiy+OAvG3VR76jqTLt1rDj/lqt1290Jo01DZWBcii4zbSmgf6seKlHgnO/DASLJUiWReaB98e3osNZqe/rsHM/sHHwEm2joGAUDAGcXPaPGZBr3s1kNO65xyn9XGp7bvo2PnFXCV2wLFrVqoqPq3Gz5zYVGXGwuLfr//bHoYLh5+ixCj6tOvz5TKgVkGPgPzrRFmRj2W1fUOa6JQfRq7N2JmGym1B8JDM/g+K5iM8qkO/FH+9t
  template:
    metadata:
      creationTimestamp: null
      name: testsec
      namespace: testns
Last modified May 10, 2025: modify devops cluster docs (17549c6)