npm package: @renault-digital/kubernetes-authentication-proxy-middleware
Description: Kubernetes authentication proxy that use impersonate
Author: Romain DARY
Latest version: 1.0.1

# Kubernetes Authentication Proxy

[![Build Status](https://travis-ci.org/renault-digital/kubernetes-authentication-proxy-middleware.svg?branch=master)](https://travis-ci.org/renault-digital/kubernetes-authentication-proxy-middleware)

If you are looking for a Kube Proxy OIDC Authentication, please follow the links :

- Kube Proxy OIDC source code
- Kube Proxy OIDC Docker
- Kube Proxy OIDC Helm Chart

## Install

```sh

$ yarn add @renault-digital/kubernetes-authentication-proxy

# or

$ npm install @renault-digital/kubernetes-authentication-proxy

```

## Read Before

Impersonation is a Kubernetes param that permit for an account to operate over another user account.

Before using this middleware, you MUST : 
- own a service account
- have the associated authentication token
- have the right to impersonate 

You can find an example of kubernetes manifest in `/examples/kubernetes`.

## Usage

### Configuration

This is the `opts` available for the `router` :

| key                   | description                                     | type      | default              | sample     |
|-----------------------|-------------------------------------------------|-----------|----------------------|------------|
| `auth.type`           | Kind of authentication schema found in header   | `string`  | `"Bearer"`           |            |
| `auth.token`          | Token used for Kubernetes authentication        | `string`  |                      | `"secret"` |
| `user.anonymous`      | Kubernetes account used for anonymous operation | `string`  | `"system:anonymous"` |            |
| `user.allowAnonymous` | Allow Kubernetes anonymous usage                | `boolean` | `false`              |            |
| `user.accountPath`    | Path in `req` to find account name              | `string`  | `"user.account"`     |            |
| `proxy.target`        | Kubernetes api                                  | `string`  | `"user.account"`     |            |
| `proxy.extra`         | Extra config for proxy (please see: )           | `object`  |                      |            |
    
### Basic Usage (Dangerous usage)

Authentication is based on the user account present in request. The `dummyAuth` middleware should be replaced by your
authentication process to inject user account in request properly.

```javascript
const express = require('express');
const router = require('@renault-digital/kubernetes-proxy-auth');

const dummyAuth = (req, res, next) => {
  req.user = { account : 'foo@bar.com' };

  return next();
};

const app = express();
const token = process.env.KUBERNETES_AUTH_TOKEN || 's3cr3t';
const target = process.env.KUBERNETES_URL || 'http://requestbin.fullcontact.com/14tnv911';
const port = process.env.PORT || 3000;

const extra = {
  // if you want to remove path prefix
  pathRewrite: {'^/kubernetes' : ''},
  
  // if necessary
  changeOrigin: true,
};

app
  .use('/kubernetes', dummyAuth, router({
    proxy: { target, extra },
    auth: { token },
  }))
  .listen(port, () => console.log(`Example app listening on port ${port}!`));

```

### With Passport and an http strategy

```javascript
const express = require('express');
const passport = require('passport');
const { BasicStrategy } = require('passport-http');

const router = require('@renault-digital/kubernetes-proxy-auth');

const app = express();
const usernameField = process.env.USERNAME || 'john';
const passwordField = process.env.PASSWORD || 's3cr3t';
const token = process.env.KUBERNETES_AUTH_TOKEN || 's3cr3t';
const target = process.env.KUBERNETES_URL || 'http://requestbin.fullcontact.com/14tnv911';
const port = process.env.PORT || 3000;

const extra = {
  // if you want to remove path prefix
  pathRewrite: { '^/kubernetes': '' },

  // if necessary
  changeOrigin: true,
};

passport.use(new BasicStrategy(
  function(username, password, done) {
    if(username !== usernameField || password !== passwordField ) {
      return done(new Error('Bad Credentials'));
    }

    return done(null, { account: username });
  }
));

app
  .use(
    '/kubernetes',
    passport.initialize(),
    passport.authenticate('basic', { session: false}),
    router({
      proxy: {
        target,
        extra,
      },
      auth: { token },
    }))
  .listen(port, () => console.log(`Example app listening on port ${port}!`));
```

### More complex example

Please have a look to `/examples`.