Hide your f🤬🤬king API keys and credentials from versioned code
Tags: aws, security, javascript, webdev
Published: 2020-01-24 11:09:02

As a developer, you deal every day with API keys, passwords, credentials, tokens etc... and you **do NOT** want to share them. 

Here are the different ways to handle them : 

1 - A versioned settings file with secrets in it. 
***If you do that, please continue to read this post, internets need that.***
<img src="https://media.giphy.com/media/d10dMmzqCYqQ0/giphy.gif" width="200" height="200" />

2 - A non versioned settings file. 
***Better ! But when you'll onboard developers, it will be funny to check how you'll send them these values.***
<img src="https://media.giphy.com/media/B37cYPCruqwwg/giphy.gif" width="200" height="200" />

3 - Environments variables (the classic ***.env***) ! 
***Yeah ! Even better. Once again, how your future team members will have their own, by copy pasting yours ?***
<img src="https://media.giphy.com/media/5wWf7H89PisM6An8UAU/giphy.gif" width="200" height="200" />

4 - Store your secret into a secret management service !!!
***Yeah ! OK, let's see how to do so***
<img src="https://media.giphy.com/media/lMVNl6XxTvXgs/giphy.gif" width="200" height="200" />


There are several secrets management tools, but, I'll talk about the one I know best, because this is the one we're using at [Monisnap](https://www.monisnap.com) : **AWS Secret Manager**.

### What is AWS Secret Manager ? 

AWS Secrets Manager is a secrets management service which enables you to easily rotate, manage, and retrieve credentials, API keys, or other secrets. 
Using Secrets Manager, you can secure, audit, and manage secrets used to access your resources.  

You'll now be able to share your code (every file, every line), without any fear. Indeed, in your code, there will only be specific strings which describes your secrets, but not the secrets values themself.

|Before Secrets Manager|After Secrets Manager|
|---|---|
|`db-name.cluster-cifkjshyfli1p.eu-west-2.rds.amazonaws.com.`|`DB_HOST`|
|`username`|`DB_USER`|
|`password`|`DB_PASSWORD`|

### Security

AWS Secrets Manager automatically **rotates** your secrets. Your teammates or anyone else who clone/fork your code **can have access without any knowledge** on what are the secrets values. 

You only need to manage ACL via AWS IAM.

And so, for instance, your seniors developers can have access through their IAM roles and create/edit/update/delete new secrets, and interns can't.

### Usage

For every AWS Cloud based infrastructure, all you need to do is to grant access to the secrets.

Our MicroServices infrastructure is built on Serverless lambdas functions, so we just have to add the rights IAM roles to our lambdas.

Also, you can easily split them by environments.

```javascript
provider:
  name: aws
  runtime: nodejs10.x
  stage: ${opt:stage, 'dev'}
  region: eu-west-1

  iamRoleStatements:
    # Role for using AWS Secret Manager
    - Effect: "Allow"
      Action:
        - "secretsmanager:GetSecretValue"
      Resource: 
        - ${self:custom.jarvisAdminPassword.${self:provider.stage}}

  environment:
    JARVIS_ADMIN_PASSWORD: ${self:custom.jarvisAdminPassword.${self:provider.stage}}

custom:
  stage: "${opt:stage, self:provider.stage}"

  jarvisAdminPassword:
    local: "local_jarvis_admin_password_secrets_key"
    dev: "dev_jarvis_admin_password_secrets_key"
    staging: "staging_jarvis_admin_password_secrets_key"
    prod: "prod_jarvis_admin_password_secrets_key"
```

An extra cool thing about secrets: if you need to update your database accesses, an API key or any secret value you can just update the secret value into your Secret Manager, and every services that are using it will be automatically updated :) 


Hope it helps !