Google Cloud logo Deploy an App to Google Cloud

Platform:

So you’ve seen the demo app in action on your local workstation. That’s great, but to truly experience the value of secrets management you’ll want to actually deploy something.

After doing so, you should be able to apply these concepts in the real world and add automatic secrets provisioning to your own production applications.

Let’s see what’s necessary to take it to the next level:

  1. Install binary on the host
  2. Create a service account
  3. Set access rules
  4. Pick a mechanism for loading secrets
  5. T-minus 3, 2, 1… 🚀

Step 1: Install binary on the host

To get the secrets, your app has to be able to authenticate to the SecretHub server and decrypt the requested secrets.

Because we don’t want you to modify all your application code for this, we’ve made sure that your codebase doesn’t need to know anything about SecretHub. Instead, you’ll use the CLI to load the secrets for you.

Install the CLI on the host that is running the app. It’s the same piece of software you’ve installed already on your workstation!

Docker

If you’re using Docker, you can just add the SecretHub CLI to the Docker image. This way, your apps don’t have to rely on orchestrator-level injection mechanisms and they run consistently from dev to prod, regardless of the ecosystem they’re launched in.

Furthermore, your secrets are no longer visible with kubectl describe and docker inspect.

In your Dockerfile, you can put any of the installation commands as a RUN statement.

Kubernetes / GKE

If you’re on Kubernetes and prefer to not include the CLI in your image, you can also use the SecretHub Mutating Webhook to automatically mount the binary onto a volume.

Linux

You can install the CLI from our Alpine repository using this one-liner:

apk add --repository https://alpine.secrethub.io/alpine/edge/main --allow-untrusted secrethub-cli

To install the CLI with apt-get, add the SecretHub repository to your sources.list:

echo "deb [trusted=yes] https://apt.secrethub.io stable main" > /etc/apt/sources.list.d/secrethub.sources.list && apt-get update

Then, use apt-get install to install the CLI:

apt-get install -y secrethub-cli

Shorthand

You can also use this one-liner instead:

curl https://apt.secrethub.io | bash

To install the CLI using yum, first add the SecretHub repo to your /etc/yum/repos.d:

curl https://yum.secrethub.io/secrethub.repo -o /etc/yum/repos.d/secrethub.repo --create-dirs

Then, install the CLI like any other yum package:

yum install secrethub-cli

Shorthand

You can also use this one-liner instead:

curl https://yum.secrethub.io | bash

Or you can link to the GitHub release directly, but you won’t be able to automatically yum update later on:

yum install https://github.com/secrethub/secrethub-cli/releases/download/v0.41.2/secrethub-v0.41.2-linux-amd64.rpm

To install the CLI on Debian/Ubuntu, download the latest Debian amd64 release and install it with dpkg:

curl -sLJO https://deb.secrethub.io/amd64
dpkg -i secrethub-cli-amd64.deb
rm secrethub-cli-amd64.deb

To update the CLI, you can just re-run this command.

For other architectures or earlier versions, see the complete list of CLI releases.

Windows Server

On Windows, you can install the CLI using a standard Windows installer. Download the latest amd64 .msi file and follow the installation wizard.

Windows installation wizard

For other architectures, see the complete list of CLI releases.

To install the CLI using Scoop, first add the SecretHub bucket:

scoop bucket add secrethub https://github.com/secrethub/scoop-secrethub

Afterwards, run this to actually install the CLI:

scoop install secrethub-cli

To download and install the secrethub CLI, run the following in Powershell as an Administrator:

iwr https://get.secrethub.io/windows | iex

And you’re done.

Note: this works for Windows Server 2012 R2, Windows 8, and upwards. For older operating systems (e.g. Windows Server 2008 R2), use the equivalent more verbose command:

(New-Object System.Net.WebClient).DownloadString("https://get.secrethub.io/windows") | iex

Other

To install the CLI with NPM, run:

npm install -g @secrethub/cli

You can also include the CLI as a dev dependency to your project:

npm install --save-dev @secrethub/cli

Global install as root

To do a global install as root, you have to run NPM with the unsafe-perm setting. You can do this by using the --unsafe-perm flag:

npm install -g --unsafe-perm @secrethub/cli

Or by updating your NPM config:

npm config set unsafe-perm true
npm install -g @secrethub/cli

To build the CLI yourself, you just need Go and GNU Make installed:

git clone https://github.com/secrethub/secrethub-cli
cd secrethub-cli
make build

You can then place the secrethub binary in a directory on your PATH, e.g. /usr/bin/.

Step 2: Create a service account

Bringing you end-to-end encrypted secrets management does mean that the application-end also needs to do decryption. So it needs a key.

Technically, you could re-use your personal keyfile for every app you deploy, but you’d be missing out on some core (security) features if you did.

If instead every app gets its own account, you can set app-specific access rules, see the app’s activity on the audit log, and revoke it when its confidentiality cannot be not guaranteed anymore.

For GCP, we’ve built a special type of service account that hides the SecretHub key for you. Instead, it gets its identity from Cloud IAM and uses Cloud KMS as the last turtle, making your apps ‘keyless’.

As long as your app takes on a Google Service Account, it can load the secrets it needs. To set it up, create a KMS key and give your app’s Service Account decryption rights. Then, create the SecretHub service account:

Run the following command and you’ll be prompted for the email of your Google Service Account and the resource id of the Cloud KMS key:

secrethub service gcp init your-username/demo

To see the service accounts tied to a repo, run:

secrethub service ls your-username/demo

Every service gets an ID assigned (e.g. s-a1b2c3d4e5), that you can use to set access rules or to delete the account.

resource "secrethub_service_gcp" "demo_app" {
  repo                  = "your-username/demo"
  service_account_email = google_service_account.demo_app.email
  kms_key_id            = google_kms_crypto_key.demo_app.id
}
resource "google_service_account" "demo_app" {
  account_id  = "demo-app"
  description = "SecretHub demo app"
}

resource "google_kms_key_ring" "secrethub" {
  name     = "secrethub"
  location = "global"
}

resource "google_kms_crypto_key" "demo_app" {
  name     = "demo-app"
  key_ring = google_kms_key_ring.secrethub.id
}

resource "google_kms_crypto_key_iam_binding" "crypto_key" {
  crypto_key_id = google_kms_crypto_key.demo_app.id
  role          = "roles/cloudkms.cryptoKeyDecrypter"

  members = [
    "serviceAccount:${google_service_account.demo_app.email}",
  ]
}

resource "secrethub_service_gcp" "demo_app" {
  repo                  = "your-username/demo"
  service_account_email = google_service_account.demo_app.email
  kms_key_id            = google_kms_crypto_key.demo_app.id
}

For a complete, start-to-finish walkthrough of deploying the demo app, follow these guides:

Step 3: Set access rules

Creating a service account alone doesn’t grant it access to anything. To do that, you need to set access rules.

To allow the service to read every secret under your-username/demo:

You first need the ID (e.g. s-a1b2c3d4e5) of the service account, which can be obtained by listing all service accounts for your repo:

secrethub service ls your-username/demo

This ID can then be used to create a new access rule that gives the service account read access to the repo:

secrethub acl set your-username/demo s-a1b2c3d4e5 read
resource "secrethub_access_rule" "your_app" {
  account_name = secrethub_service.your_app.id
  dir          = "your-username/demo"
  permission   = "read"
}

Step 4: Pick a mechanism for loading secrets

With a service account set up and the SecretHub CLI in place on the host, the last thing to do is to make your app load the secrets.

Your application code doesn’t have to change for this, it can just get the secret values from environment variables, config files, or key files:

The recommended way to load your secrets is through environment variables. As covered earlier, you can reference the secrets in your environment, instead of hardcoding them:

export DEMO_USERNAME=secrethub://your-username/demo/username
export DEMO_PASSWORD=secrethub://your-username/demo/password

Then, wrap the app launch command in secrethub run:

secrethub run -- ./start-your-app

When you stop your app (either gracefully or forcefully), all local copies of secrets are gone. The next time you launch your app, they’ll have to be fetched and decrypted again, adding a new read entry to the audit log.

Docker

In your Dockerfile, you can set secrethub run as the ENTRYPOINT and your app start command as the CMD:

ENTRYPOINT ["secrethub", "run", "--"]
CMD ["./start-your-app"]

If your app prefers config files, that’s fine too. Replace the secret values in the config with path references:

postgres:
    host: localhost
    port: 5432
    user: {{ your-username/demo/username }}
    password: {{ your-username/demo/password }}

Then, right before your app starts, inject the secret values into the config template:

secrethub inject -i config.yml.tpl -o config.yml

Keep in mind however that you have to make sure that the config file that contains the plaintext secrets gets deleted when your app stops.

If your app needs .crt, .pem, or other key files, we’ve got you covered as well.

For example, to write a TLS certificate key stored on SecretHub at your-username/demo/tls/example.com.key to a local file called example.com.key, run:

secrethub read -o example.com.key --filemode 0600 your-username/demo/tls/example.com.key

Keep in mind however that you have to make sure that the secret files get deleted when your app stops.

Whichever method you choose, make sure you set --identity-provider or SECRETHUB_IDENTITY_PROVIDER to gcp, so the app knows where to look for the key.

T-minus 3, 2, 1… 🚀

You’re all set up now, so let’s deploy the app!

After deploying, check the audit log again and you’ll see some new entries logged.

Next Up

👨‍💻🔑👩‍💻 Share Secrets with Your Team