Git Product home page Git Product logo

kiss's Introduction

kiss ๐Ÿ˜˜

Kaluza Infrastructure Secret Service

AWS-based secrets management for Kubernetes.

Leverages users' Kubernetes OIDC authentication tokens for AWS Secrets Manager secrets management. Can also manage AWS IAM policies for secrets if you're using the AWS provider for the k8s Secrets Store CSI driver.

You may be interested in this project if you:

  • use AWS Secrets Manager as your k8s secrets store
  • use OIDC tokens for auth/z'ing users against your k8s cluster
  • want your users to manage their own secrets without access to your AWS account

Why?

We're using external-secrets to synchronize AWS Secret Manager secrets in our k8s AWS account with k8s-native Secret resources.

We wanted to let our cluster users manage secrets logically scoped to their namespaces without hooking them up with direct access to the AWS account.

Since we were already using OIDC tokens for user auth/z to the cluster with kubectl (using kubelogin), we figured we could use those same tokens for auth/z against an intermediary secrets management service that simply wrapped around AWS Secrets Manager.

Synergy with external-secrets

Our service creates AWS Secrets Manager secrets with the following naming convention:

Breaking Change As of version 0.1.0, the secret naming convention has been updated

k8s-secret-secret-namespace-secret-name

We then have external-secrets annotations on our namespaces to only allow ExternalSecret resources in that namespace to sync with AWS Secrets Manager secrets logically scoped to the namespace. For example, this shows a namespace called security that is only allowed to read AWS Secrets Manager secrets prefixed by k8s-secret_security_:

apiVersion: v1
kind: Namespace
metadata:
  name: security
  annotations:
    externalsecrets.kubernetes-client.io/permitted-key-name: "k8s-secret_security-.*"

A member of the security namespace can then create a secret with kiss and use it as such:

apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
  name: foo
  namespace: security
spec:
  backendType: secretsManager
  data:
    - key: k8s-secret_security_foo
      name: foo

Synergy with AWS provider for k8s Secrets Store CSI driver

If you're using the AWS Secrets & Configuration Provider with your Kubernetes Secrets Store CSI driver you can use kiss to:

  • automatically create AWS IAM policies with read permissions when creating secrets
  • attach AWS IAM policies to IAM Roles for Service Accounts, allowing the relevant ServiceAccount to read your secret

Combined with our iam-service-account-controller, this can allow your users to safely manage IAM roles and secret reading policies directly from their k8s namespaces, with no AWS permissions.

Check the -policy flags and the bind command for more details.

Builds

We release binaries for the client. Please check the releases.

We don't provide any public images for the server, but it should be trivial to build your own. Check our ./.github/workflows/build-release.yaml if you're lost.

Tokens

Your OIDC tokens will vary depending on your setup. Kaluza's payloads look like this:

{
  "cognito:groups": ["kaluza:default", "kaluza:security"],
  "iss": "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_AbCdEf",
  "email": "[email protected]",
  "...": "..."
}

The cognito:groups is a list of namespaces the token grants access to, prefixed with our organization name. We'll need to tell the server how to extract these things.

Running locally

Server

$ cd server

$ go run cmd/main.go
	-jwks-url="https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_AbCdEf/.well-known/jwks.json"
	-namespaces-key="cognito:groups"
	-namespaces-regex="kaluza:([1-9a-z-]{1,63})"
	-identifier-key="email"
	-token-path=""

Note we're telling the server where and how to extract the namespaces from the token as well as which field contains the user identifier, for auditing purposes. We also need to pass the relevant JWKS file to validate user tokens.

The -token-path is a path to a Web ID token for AWS auth/z (not to be confused with our users' tokens!). When running locally, we can set an empty -token-path to use default AWS authentication instead. Naturally, this means your local environment should be configured for AWS access with necessary permissions.

Check the -help for more information.

Client

The ping command is a convenient way to test the connection and user auth/z against the server.

$ cd client

$ go run cmd/main.go ping
	-token-path="~/.kube/cache/oidc-login/c19ad9a81c5044b90e02259679c9f8037acdb23d970de3425f9377a1a7242da7"
	-namespace="security"
	-server-addr="localhost:10000"
	-secure=false
Successfully sent ping


$ go run cmd/main.go ping
	-token-path="~/.kube/cache/oidc-login/c19ad9a81c5044b90e02259679c9f8037acdb23d970de3425f9377a1a7242da7"
	-namespace="kube-system"
	-server-addr="localhost:10000"
	-secure=false
2021/07/02 13:29:37 [ERROR] Error ocurred while sending ping: rpc error: code = PermissionDenied desc = user '[email protected]' is not authorized for namespace 'kube-system'
exit status 1

Other commands include create, create-from, update, delete and list which do pretty much what you'd expect with AWS Secret Manager secrets logically scoped to the user's k8s namespace. Check the relevant -help for more information.

Creating a secret from a file

Sometimes it may be necessary to create a secret which contains newlines, to support this, you can use the create-from command, specifying the filepath in the -value argument.

Notes

  • The -token-path is optional for all commands. Without it kiss will attempt to find the first file in the default ~/.kube/cache/oidc-login directory
  • On a Mac you can't use the ~/ path when specifying the token path - instead use $HOME/
  • When you create a secret it will be base64 encoded, so you should specify it's value in plaintext
  • A secret name cannot contain underscores as this will result in the "Error occurred while creating secret" error
  • The -interactive flag can be used to help choose which token to load if there are multiple in your ~/.kube/cache/oidc-login` directory.

kiss's People

Contributors

serain avatar rileywilliams avatar potsec avatar

Stargazers

 avatar  avatar  avatar Benjamin-Yves Trapp avatar Paul Schwarzenberger avatar Peter C avatar

Watchers

Marco Delaurenti avatar James Cloos avatar Chris avatar Ignacio Dominguez avatar  avatar

kiss's Issues

Support storing secrets that include newlines

Secrets such as private keys contain newlines, at present there appears to be no way to store such secrets with the KISS CLI. I have tried both piping in from standard input (results in only the first line being stored) and replacing newlines with \n (gives [ERROR] failed to read input from stdin. Either -value is required or you provided an invalid input)

create-from adds a trailing newline, there's no update-from

A script that we use uses kiss with input that might or might not be multi line.

Our approach was to use delete / sleep / create-from (not ideal, but there's no update-from) which appeared to work.

However if the value is a single line without a trailing newline (eg a username or password) create-from will append a newline to it, thus producing an environment variable with a newline.

Our workaround is to check the file length in lines and if it's 1, just use update and if it's over 1 use delete / create-from

No such logic should be necessary on a script that uses kiss though, and ideally there should be:

  • an update-from to avoid the delete / sleep / create-from hack
  • update-from/create-from should not be adding a trailing newline that doesn't exist

Add 'version' flag

Add a -v and --version flag to show which version of the client is installed.

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.