Heroku

Using Keepers Secrets Manager to store your Heroku application sensitive secrets.

Features

  • Securely store secret credentials in the Keeper Vault and use them in Heroku without exposure

  • Copy files from the Keeper vault into your Heroku Apps

  • Utilize other Secrets Manager SDK features (such as record creation and TOTP codes) from Heroku

For a complete list of Keeper Secrets Manager features see the Overview

About

Heroku offers the ability to store configuration variables for your application. The problem is it stores the values in a viewable format. Keeper Secrets Manager allows you to store your sensitive secrets offsite in a zero knowledge environment.

The Keeper Secrets Manager SDK can be used with Heroku

See the example project below to get an idea of the capabilities of Keeper Secrets Manager with Heroku

Example - Slack notification using Python SDK

This example uses the Keeper Secrets Manager SDK to retrieve a webhook token to send messages to a channel in Slack from a Heroku web application.

Slack Setup

The first step is getting a webhook token from your instance of Slack. Login into the Slack website and go to Your Apps.

Create a new app by clicking the Create New App button and selecting From scratch from the dialog box. At this point enter an App Name and select the workspace you want to develop your app in.

Next click the Incoming Webhooks button.

Turn On the Incoming Webhooks. This will show the Webhook URLs for Your Workspace section. Click the Add New Webhook to Workspace button.

Then select a channel in your workspace.

Now at the bottom of the Incoming Webhooks page, there will be a Webhook URL. For this example, Copy the url. This will be placed in Keeper Vault record.

Keeper Vault setup

In the Keeper Vault create a Login record to hold the Slack Webhook URL in the Shared Folder. The Shared Folder can be added used by an Application. Reference the Quick Start Guide for more details.

Heroku

For this example, a Heroku account and Python 3 are requiered. The next step is to install the Heroku CLI following their instructions.

With the Heroku CLI installed an application can be created.

$ heroku create
Creating app... done,  random-name-30564
https://random-name-30564.herokuapp.com/ | https://git.heroku.com/random-name-30564.git

The generated name of your application will be different than in this example.

That will create a blank Git repository that will be used for the application. The Git repository can then be cloned. There will be a warning about it being empty. After that change into the repository directory.

$ git clone https://git.heroku.com/random-name-30564.git
Cloning into 'random-name-30564'...
warning: You appear to have cloned an empty repository.

$ cd random-name-30564

With the repository cloned, the config variables can be set. There are two config variables that need to be set. The first is RECORD_UID which the Record UID of the record that contains the Webhook URL. The second is KSM_CONFIG which contains the Base64 encoded Secrets Manager configuration.

See the Configuration documentation for details on creating a Base64 configuration

$ heroku config:set RECORD_UID=XXXXXX
Setting RECORD_UID and restarting  random-name-30564... done, v11
RECORD_UID: XXXXXX

$ heroku config:set KSM_CONFIG=ewogI ..... Igp9
Setting KSM_CONFIG and restarting  random-name-30564... done, v11
KSM_CONFIG: ewogI ..... Igp9

With the configuration variables in place, the application can be added. The first step is to defined the requirements for the Python 3 application. The requirements.txt file contains Flask used for the website, slack_sdk used to communicate with Slack, and keeper-secrets-manager-core to communicate with Secrets Manager.

$ cat << EOF > requirements.txt
Flask
slack_sdk
keeper-secrets-manager-core
EOF

In your preferred editor save the contents of the following to app.py.

import os
from flask import Flask, request
from slack_sdk.webhook import WebhookClient
from keeper_secrets_manager_core import SecretsManager

app = Flask(__name__)
secret_manager = SecretsManager()
record_id = os.environ.get("RECORD_UID")
webhook = WebhookClient(secret_manager.get_notation("{}/field/url".format(record_id)))


@app.route('/')
def hello():

    message = request.args.get("message")
    if message is not None and message != "":
        response = webhook.send(text=message)

    html = """
<html>
    <head><title>Send a Slack Message</title></head>
    <body>
        <form method="GET">
            Message:
            <input type="text" name="message" />
            <input type="submit" />
        </form>
    </body>
</html>
    """

    return html


if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

This is a simple Flask web application that will display a form input box and a submit button. Any text entered into the input box will be sent to your Slack channel.

The last part is to give Heroku information on how to start your application using the Procfile file.

$ cat << EOF > Procfile
web: python app.py
EOF

Now the application is ready to be run. Add the file it your the Git repository and push the main branch. This will build and launch the application.

$ git add requirements.txt app.py Procfile
$ git commit -m "Initial Commit"
[main 0f31f23] Initial Commit
 3 file changed, 0 insertion(+), 0 deletion(-)
...

$ git push origin main
...
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/python
remote: -----> Python app detected
remote: -----> No Python version was specified. Using the same version as the last build: python-3.9.9
remote:        To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes
remote: -----> No change in requirements detected, installing from cache
remote: -----> Using cached install of python-3.9.9
remote: -----> Installing pip 21.3.1, setuptools 57.5.0 and wheel 0.37.0
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 62.4M
remote: -----> Launching...
remote:        Released v13
remote:        https://random-name-30564.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/random-name-30564.git
   89b16a2..fda1835  main -> main

At this point you can visit the web site by either going to the URL, i.e. https://random-name-30564.herokuapp.com/, or by using the following command line.

$ heroku open

This will display a simple web site. Enter a message and click submit.

The message should appear in the channel for the created Webhook.

Last updated