Coder Social home page Coder Social logo

kubestash's Introduction

kubestash

Push Credstash secrets to Kubernetes.

https://hub.docker.com/r/afinet/kubestash/

installing

pip3 install kubestash

usage

usage: kubestash push [-h] [-p PROXY] [-v] [--trace] [-f] [-n NAMESPACE]
                        [-l] [-c CONTEXT] [-r REGION]
                        table secret

positional arguments:
  table                 Credstash table you want to pull values from
  secret                Kubernetes secret you want to push values in

optional arguments:
  -h, --help            show this help message and exit
  -p PROXY, --proxy PROXY
                        hostname of a kubernetes apiserver to use, for
                        example: --proxy 127.0.0.1:8080
  -v, --verbose         verbose output
  --trace               show the full stack trace when an SSLError happens
  -f, --force           replace a secret if it already exists
  -n NAMESPACE, --namespace NAMESPACE
                        kubernetes namespace
  -U, --uppercase       For lowercase keys in credstash, convert them
                        to UPPER_CASE environment variables
  -l, --lowercase       For SECRET keys, lowercase and convert "_" to "-"
                        (DNS_SUBDOMAIN). Useful for compatibility with older
                        Kubernetes versions. (deprecated).
  -c CONTEXT, --context CONTEXT
                        kubernetes context
  -r REGION, --region REGION
                        aws region

adding envs to your deployment

add this to your container

envFrom:
- secretRef:
    name: secret-name

See test/example.deploy.yaml for an example of this.

use case

kubestash is most useful when:

  • You're using Credstash to store environment variables as secrets.

  • You're using Kubernetes, and storing environment variables as secrets.

If the above is true for you, kubestash can help!

Just run:

kubestash push -v TABLE SECRET

and you'll have a Kubernetes SECRET which maps 1:1 with your Credstash TABLE.

kubestash daemon -v TABLE SECRET will monitor DynamoDB for updates (using DynamoDB Streams), and automatically trigger a push command when necessary.

This is useful if you don't want to manually run the push command every time you update credstash.

secret key constraints

Keys must consist of alphanumeric characters, ‘-‘, ‘_’ or ‘.’. [1]

Environment variable names must consist solely of uppercase letters, digits, and the '_' (underscore). [2]

So when you run credstash -t=table put KEY VALUE, you should take care that KEY meets these constraints.

In older versions of Kubernetes, secret keys had to conform to DNS_SUBDOMAIN.

For this purpose, the -l --lowercase flag is present to help you convert your keys if necessary.

[1] https://kubernetes.io/docs/concepts/configuration/secret/

[2] http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html

known issues

There's a known issue with the kubernetes library: https://github.com/kubernetes-incubator/client-python#sslerror-on-macos

which causes some people with older versions of python to get an ssl error:

SSLError(SSLError(1, u'[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590)'),)

We recommend updating openssl and reinstalling python3 to fix this:

brew update
brew install openssl
brew uninstall python3
brew install python3

you can also subvert the issue by using a proxy:

kubectl proxy -p 8080
kubestash --proxy 127.0.0.1:8080 table secret

kubestash's People

Contributors

af-inet avatar captn3m0 avatar rapatel0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

kubestash's Issues

Selective Secret Storage with Expiration?

Before writing this up, just want to say I love where you've gone with this project.

I started earlier today writing up what is effectively a competitor to this package, and I wonder if it wouldn't just be better to converge the work.

For very large tables, I can see some potential issues with storing ALL the secrets from Credstash in the cluster. My thought was to be a bit more dynamic about things. What I've started writing is based on the annotations found on deployments. Instead of pulling the whole secrets table in wholesale, I thought a more viable option might be to run a pod in the kube-system namespace (and use kube2iam to grant that pod a role capable of reading from Credstash), and then create secrets based on what a given deployment has listed as needed, along with giving them an expiration field. The planned workflow is approximately as follows:

List all deployments on the cluster, across all namespaces. Retain any that have an annotation of "kubestash.secrets".
Loop through retained deployments.
Check for the existence, in the relevant namespace, of a secret whose name matches "kubestash-". If the secret does not exist, create it, by iterating over the list of comma-separated keys contained in the value of the annotation, and adding an expiration field of one hour from the current time. If the secret does exist, check to see if the expiration is less than 10 minutes away, and update all individual values as well as the expiration.
List all secrets on the cluster, across all namespaces. Retain any which begin with "kubestash-".
Loop through retained secrets. If the secret's expiration has passed, delete the secret.

As I see it, this has a couple of inherent perks. First of all, as credentials get updated in Credstash, they get refreshed shortly afterward in the k8s secret store, without a need to watch streams. Second, the principle of least access is maintained by ensuring only secrets which are required are actually stored on the cluster, and only for approximately as long as they are still in use. Third, this provides an automatic cleanup, which reduces the risk of secret leakage and prevents confusion due to an excessive number of secrets on the cluster. And fourth, it makes secret access very auditable, because a given deployment's secrets are all in one spot. One nice side-effect of this approach is that when you go to launch a deployment, the secrets won't yet exist, so the pod will fail to launch, but the monitoring will kick in before very long, creating the secret. Once that occurs, the pod will launch automatically and work as normal and expected.

I realize this is a somewhat significant shift in direction from the current design, but think it could very easily be viable. If it's not functionality you want, I can continue going down my path independently, but I think with what you have written at this point, it'd actually be a relatively easy task to add it to this project, compared with doing the same from the ground up.

Use secretKeyRef to expose entire secret to the deployment

It is possible to apply an entire secretRef to a deployment without editing the deployment.

kubectl get secret secrets -n envtest
NAME      TYPE      DATA      AGE
secrets   Opaque    2         3m
kubectl get deployment nginx-app -n envtest -o json | jq '.spec.template.spec.containers'
[
  {
    "envFrom": [
      {
        "secretRef": {
          "name": "secrets"
        }
      }
    ],
    "image": "nginx",
    "imagePullPolicy": "Always",
    "name": "nginx-app",
    "ports": [
      {
        "containerPort": 80,
        "protocol": "TCP"
      }
    ],
    "resources": {},
    "terminationMessagePath": "/dev/termination-log",
    "terminationMessagePolicy": "File"
  }
]
kubectl describe secret secret -n envtest
Name:         secrets
Namespace:    envtest
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
HELLO:  14 bytes
WORLD:  11 bytes
# env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.3.0.1:443
HELLO=nottesting123

This way, the deployment won't need frequent edits, and the credstash table can be 1:1 mapped against a secretKeyRef.

So credstash table has HELLO=1234, the secretRef will have the same variables, and and deployment gets the entire secret as-is.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.