Giter Club home page Giter Club logo

vault-controller's Introduction

Vault Controller

The Vault Controller automates the creation of Vault tokens for Kubernetes Pods. This repo includes a set of hands-on tutorials and example programs you can use to try out the Vault Controller.

Status

This is a prototype. Do not use this in production.

Use Case

  • Each Pod requires a dedicated Vault token tied to the Pod's life-cycle
  • Each Pod will use a dedicated Vault token to request secrets from a Vault server

Documentation

How it Works

The following diagram demonstrates the flow Pods use to obtain a dedicated token when running in a Kubernetes cluster.

Vault Controller Flow

  1. An Init container requests a wrapped token from the Vault Controller
  2. The Vault Controller retrieves the Pod details from the Kubernetes API server
  3. If the Pod exists and contains the vaultproject.io/policies annotation a unique wrapped token is generated for the Pod.
  4. The Vault Controller "callsback" the Pod using the Pod IP obtained from the Kubernetes API.
  5. The Init container unwraps the token to obtain a dedicated Vault token.
  6. The dedicated token is written to a well-known location and the Init container exits.
  7. Another container in the Pod reads the token from the token file.
  8. Another container in the Pod renews the token to keep it from expiring.

More details can be found in the How it Works document.

Usage

The following tutorials will guide you through the deployment of the vault-controller and an example application to see how it all works.

Prerequisites

Clone this repository:

git clone https://github.com/kelseyhightower/vault-controller.git
cd vault-controller

Before you can complete the tutorials you'll need access to a Kubernetes clusters. Google Container Engine (GKE) or minikube should work.

Tutorials

Cleanup

Once you are done with the tutorials run the following command to clean up:

kubectl delete namespace vault-controller

vault-controller's People

Contributors

kelseyhightower avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vault-controller's Issues

Need to clarify Kubernetes requirements

The deployment tutorial requires Kubernetes 1.4 to run as is. This needs to be stated or the tutorial needs to be modified.

To make it compatible with earlier versions:

  • Use the full --namespace flag
  • Use DNS-compatible labels

AWS admin has access to all secrets?

Hello, am I right that AWS admin has access to all secrets?
According to https://github.com/kelseyhightower/vault-controller/blob/master/docs/deployment-guide.md, the root token or admin token is written in
kubernetes secret

kubectl -n vault-controller
create secret generic vault-controller
--from-literal "vault_token=3e4a5ba1-kube-422b-d1db-844979cab098"

So AWS admin could read this config from kubernetes secret and use the token to read all secrets from vault?

cannot unmarshal string into Go value of type main.Status

This is a test against Kubernetes 1.6.1. Had to give vault-controller RBAC role permission to list pods in the cluster. After that, I am getting the following error:

2017-04-29T00:36:13.693068057Z 2017/04/29 00:36:13 Starting vault-controller app...
2017-04-29T00:36:13.693097663Z 2017/04/29 00:36:13 Listening for token requests.
2017-04-29T00:36:21.455439182Z 2017/04/29 00:36:21 token request from 10.200.9.22:42974
2017-04-29T00:36:21.45809124Z 2017/04/29 00:36:21 error parsing pod (vault-example-lxx67) details: json: cannot unmarshal string into Go value of type main.Status

On the kube-apiserver side, the log shows:

/api/v1/namespaces/vault-example-lxx67/pods/vault-example-lxx67: (1.889456ms) 404 [[Go-http-client/1.1] 10.240.101.145:51154]

It seems the vault-controller is trying to get pod details from namespace /api/v1/namespaces/vault-example-lxx67/ instead of /api/v1/namespaces/vault-controller.

The vault-example rs looks okay in vault-controller namespace:

$ kubectl -n vault-controller get pods
NAME                     READY     STATUS     RESTARTS   AGE
vault-cgscv              1/1       Running    0          1h
vault-controller-1phqz   2/2       Running    0          7m
vault-example-lxx67      0/1       Init:0/1   0          17m

Anyone get it working with Kubernetes 1.6.1?

Would you like to join forces?

hey @kelseyhightower !

We started Boostport/kubernetes-vault last year because we needed a way to get Vault tokens into our pods, in order to use Vault as our secret manager. We recently found out about your project and noticed that our goals are essentially the same: to get a token into a pod securely.

However, in terms of implementation our projects are quite different. Kubernetes-Vault uses AppRoles and a push approach, whereas Vault-Controller uses policies in an annotation and a pull approach.

Would you be interested in exploring ways to join forces and merge our projects together?

Cheers,
Francis

Error from vault-init

Hi

I'm trying your implemetation on k8s 1.4.6
I just follow
https://github.com/kelseyhightower/vault-controller/blob/master/docs/deployment-guide.md
https://github.com/kelseyhightower/vault-controller/blob/master/docs/example-usage.md

but it puts some error while I deploy the vault-example

2017/01/10 01:39:02 Requesting a new wrapped token from http://vault-controller
2017/01/10 01:39:02 token request: Request error error parsing pod (vault-example-cerkm) details: invalid character 'F' looking forbeginning of value; retrying in 5s

it failed at requesting very init token.
Could you inform me how can I fix it ?

EnvVar usecase

Would it be possible to use/extend this controller to support the following usecase?

I want to use secrets from Vault as environment variables of my containers.
My idea was to use an init-container that extracts secrets from Vault and somehow pass those secrets as environment variables to the "normal" containers of the pod.

I've implemented this in Vault-monkey (the tool I already use for extracting vault secrets, see pulcy/vault-monkey#4). It can extract secrets to file (which is no problem with a memory backed emptyDir volume), but extracting it to environment variables in an issue because I cannot find something similar to dockers --env-file option.
So as a temporary solution I ended up extracting secrets from vault, storing them in a K8S secret which in then mapped into the container as environment variable. Of course that exposes secrets in the K8S api server, which I would like to avoid.

Would this controller have a way to solve this use case?

is there a docker file for the image of kelseyhightower/kubectl

could you help to provide the docker file of kubectl:1.4.0 as well?
which is used in vault-controller, but that failed to start in my case, I would like to start why, thanks.

some information on the failure: when running the image, it returns below error:

docker run -it docker.io/kelseyhightower/kubectl:1.4.0 proxy
The connection to the server localhost:8080 was refused - did you specify the right host or port?

and my API server is listen on 8080, curl works.

maybe the kubtctl tries to connect itself for API server, instead of the host?

curl http://127.0.0.1:8080/api/v1/namespaces/vault-controller
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "vault-controller",
"selfLink": "/api/v1/namespaces/vault-controller",
"uid": "cfdfcfcd-571c-11e7-8bcb-fa163e69223e",
"resourceVersion": "352",
"creationTimestamp": "2017-06-22T07:31:31Z"
},
"spec": {
"finalizers": [
"kubernetes"
]
},
"status": {
"phase": "Active"
}
}

replicasets/vault-controller.yaml

apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: vault-controller
spec:
replicas: 1
template:
metadata:
labels:
app: vault-controller
spec:
containers:
- name: vault-controller
image: "kelseyhightower/vault-controller:0.0.1"
imagePullPolicy: "IfNotPresent"
env:
- name: VAULT_TOKEN
valueFrom:
secretKeyRef:
name: vault-controller
key: vault_token
- name: VAULT_WRAP_TTL
# The wrapped vault token must unwrapped by the pod in
# this number of seconds.
value: "120"
- name: VAULT_ADDR
value: "http://vault:8200"
- name: kubectl
image: kelseyhightower/kubectl:1.4.0
args:
- "proxy"
~

Document the Trust model

It's not clear from the docs that we are trusting the network on step 4 of the token request flow. We are subject to MitM attacks on the response from the vault-controller back to the init-container. The wrapped token can be unwrapped by an untrusted 3rd party so we must set a timeout or raise an alarm so it can be tracked in the vault audit logs.

Proposal: Design for a more secure interaction

Right now the dependancies is on pod name to validate pod. Pods can mistakenly or maliciously use wrong names, more over people will use partially trusted code (i.e. layers of containers images, libraries and so forth). These things may load wrong names.

Proposal:

  1. Use ambassador pattern, each pod contributing to this needs to run a simple container that talks to the vault on behalf of the pod.
  2. The ambassador communicates with vault using client cert.
  3. The ambassador is the one that looks up pod name.
  4. The ambassador exposes a simple rest api locally to the pod. this is a proxy api to the actual vault.

Additional future features can be added to the ambassador, offloading common functions such as token validation, token renewal etc.

Leverage TLS between all the components

This prototype should demonstrate how to leverage TLS between all the components and possibly use TLS client auth to limit communication between components.

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.