Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/monzo/vault-plugin-database-k8s-controller

A fork of Vault's database credential plugin allowing the use of annotations on service accounts as parameters in statements
https://github.com/monzo/vault-plugin-database-k8s-controller

cassandra kubernetes vault

Last synced: 3 months ago
JSON representation

A fork of Vault's database credential plugin allowing the use of annotations on service accounts as parameters in statements

Awesome Lists containing this project

README

        

# vault-plugin-database-k8s-controller
A fork of Vault's database credential plugin allowing the use of an annotation on service accounts to dynamically
specify user creation statements. Essentially, you can have many virtual 'roles' which each have tightly scoped
database user creation statements, where the roles are in fact defined in Kubernetes. At Monzo we use this to allow
for hundreds of Cassandra clients which each are allowed access to a single independent keyspace. Vault is not aware
of individual services; simply logging in with your Kubernetes service account token is enough to get permission to
issue the correct database credentials.

Non-builtin database plugins are not supported, as sadly custom plugins cannot call out to other custom plugins.
However, all of Vault's builtin database plugins are bundled into this binary and should work as normal.

Currently based on https://github.com/hashicorp/vault/tree/v1.3.0/builtin/logical/database

To rebase:
```bash
make rebase
```

## Instructions

This plugin differs from the default database plugin only if kubernetes config is provided
```bash
# if your plugin is registered as database-k8s
vault secrets enable -path=database -plugin-name=database-k8s database-k8s
vault write database/kubeconfig kubernetes_host=https://127.0.0.1 kubernetes_ca_cert=@cert jwt=@jwt
```

If this is provided, the plugin will attempt to maintain an in memory cache of all
service accounts in Kubernetes. If any service accounts contain an annotation
`monzo.com/keyspace`, the mapping from service account name to the annotation is also
stored in Vault. This is so that the mapping can be used before the cache is built from
the k8s API.

The purpose of this is to interpolate this annotation into any creation statements of a role,
to create essentially a dynamic role for every service account. If you provide a role named
like `k8s_rw_s-ledger_default` *and this role does not explicitly exist* then instead the
plugin will look up the concrete role named `rw`, and will look up the service account
`s-ledger` in the namespace `default`.

It will then replace all instances of `{{annotation}}` in the creation statements of
the concrete `rw` role with the value of the annotation on that service account.

You can also set an annotation `monzo.com/cluster` which allows you to override the db name
of the concrete `rw` role with the value of the annotation.

Annotation keys can be overridden with the `kubeconfig` endpoint,
using `keyspace_annotation` and `db_name_annotation`.

The role names are designed such that they can support a vault policy as follows:

```hcl
path "database/creds/k8s_rw_{{identity.entity.aliases.kubernetes.metadata.service_account_name}}_{{identity.entity.aliases.kubernetes.metadata.service_account_namespace}}"
{
capabilities = ["read"]
}
```

The role name is used for these parameters so that the plugin has the same API as its
upstream.

## Example

```bash
$ vault write database/roles/rw \
db_name=my-cassandra-database \
creation_statements="CREATE USER '{{username}}' WITH PASSWORD '{{password}}' NOSUPERUSER;" \
creation_statements="GRANT ALL PERMISSIONS ON KEYSPACE \"{{annotation}}\" TO {{username}};" \
default_ttl="1h" \
max_ttl="24h"
Success! Data written to: database/roles/rw

kubectl create serviceaccount s-ledger
kubectl annotate serviceaccount s-ledger monzo.com/keyspace='ledger'

$ vault read database/roles/k8s_rw_s-ledger_default
Key Value
--- -----
creation_statements [CREATE USER '{{username}}' WITH PASSWORD '{{password}}' NOSUPERUSER; GRANT ALL PERMISSIONS ON KEYSPACE "ledger" TO {{username}};]
db_name my-cassandra-database
default_ttl 1h
max_ttl 24h
renew_statements []
revocation_statements []
rollback_statements []
```