sealed-secrets

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2017 License: Apache-2.0

README

"Sealed Secrets" for Kubernetes

Problem: "I can manage all my K8s config in git, except Secrets."

Solution: Encrypt your Secret into a SealedSecret, which is safe to store - even to a public repository. The SealedSecret can be decrypted only by the controller running in the target cluster and nobody else (not even the original author) is able to obtain the original Secret from the SealedSecret.

Installation

See https://github.com/ksonnet/sealed-secrets/releases for the latest release.

# Install client-side tool into $GOPATH/bin
$ go get github.com/ksonnet/sealed-secrets/cmd/ksonnet-seal

# Install server-side controller into kube-system namespace (by default)
$ kubectl create -f https://github.com/ksonnet/sealed-secrets/releases/download/v0.0.1b/controller.yaml

controller.yaml will create the SealedSecret third-party-resource, install the controller into kube-system namespace, create a service account and necessary RBAC roles.

After a few moments, the controller will start, generate a key pair, and be ready for operation. If it does not, check the controller logs.

The key certificate (public key portion) is used for sealing secrets, and needs to be installed wherever ksonnet-seal is going to be used. The certificate is not secret information, although you need to ensure you are using the correct file.

The certificate is printed to the controller log on startup, and can also be retrieved directly from the underlying secret (the latter requires access to the sealing secret, which is generally an undesirable thing). (TODO: Improve this part)

# Fetch cluster-wide certificate used for encrypting.
# The certificate is also printed to the controller log on startup.
$ kubectl get secret -n kube-system sealed-secrets-key -o go-template='{{index .data "tls.crt"}}' | base64 -d > seal.crt

Usage

# This is the important bit:
$ ksonnet-seal --cert seal.crt <mysecret.json >mysealedsecret.json

# mysealedsecret.json is safe to upload to github, post to twitter,
# etc.  Eventually:
$ kubectl create -f mysealedsecret.json

# Profit!
$ kubectl get secret mysecret

Note the SealedSecret and Secret must have the same namespace and name. This is a feature to prevent other users on the same cluster from re-using your sealed secrets. Any labels, annotations, etc on the original Secret are preserved, but not automatically reflected in the SealedSecret.

Details

This controller adds a new SealedSecret third-party resource. The interesting part of which is a base64-encoded asymmetrically encrypted Secret.

The controller looks for a cluster-wide private/public key pair on startup, and generates a new key pair if not found. The key is persisted in a regular Secret in the same namespace as the controller. The public key portion of this (in the form of a self-signed certificate) should be made publicly available to anyone wanting to use SealedSecrets with this cluster.

During encryption, the original Secret is JSON-encoded and symmetrically encrypted using AES-GCM with a randomly-generated single-use session key. The session key is then asymmetrically encrypted with the controller's public key using RSA-OAEP, and the original Secret's namespace/name as the OAEP input parameter (aka label). The final output is: 2 byte encrypted session key length || encrypted session key || encrypted Secret.

Note that during decryption by the controller, the SealedSecret's namespace/name is used as the OAEP input parameter, ensuring that the SealedSecret and Secret are tied to the same namespace and name.

The generated Secret is marked as "owned" by the SealedSecret and will be garbage collected if the SealedSecret is deleted.

Directories

Path Synopsis
apis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL