Skip to content

Secrets

Secrets with OpenFaaS Cloud

There are two ways to bind to OpenFaaS secrets with OpenFaaS Cloud which apply when self-hosted.

Create secrets manually

You can create secrets manually via faas-cli secret create or by using kubectl. These secrets will be available to users if the prefix of the secret matches the owner of the code being deployed, i.e.

If you are using an organization or repo named myorg and want a secret named api-key you could run:

$ faas-cli secret create myorg-api-key

In your stack.yml file in the secrets section, you could then reference the api-key secret.

This method relies on you having administrative access or making a request to your administrator.

Use SealedSecrets in your repo

The preferred method available for Kubernetes uses SealedSecrets by Bitnami. We will use the kubeseal tool to encrypt our secrets using the public key of the cluster. These can then be placed in a file named secrets.yaml in your repo no matter whether it is public or private, your data will remain confidential.

Pre-reqs:

  • If you installed OpenFaaS Cloud using ofc-bootstrap then SealedSecrets will already be enabled, otherwise you can follow the development guide.

  • Follow these instructions to install kubeseal and to export the public key of your cluster.

Note: If you are using the Community Cluster, then you can fetch the public key here.

Seal a secret

  1. Create a new repo under your account username
  2. Create function faas new --lang go <name-of-function> --prefix=username
  3. Download pub-cert.pem from the my-fn repo above, you can commit the cert if you want. It's public.
  4. Update your faas-cli to get the new cloud sub-command
  5. Create secrets.yml with faas-cli cloud seal - https://github.com/openfaas/faas-cli#openfaas-cloud-extensions - make sure you prefix the secret with your GitHub username i.e. alexellis-hallo - the suffix is the repo name (not the function name). Inside your function consume the secret passed in to--literal=key=value from /var/openfaas/secrets/key. i.e. faas-cli cloud seal --name alexellis-poker-face --literal key=value
  6. Reference the secret in stack.yml without your username this time i.e. - hallo - note this is the name of the repo without your username prefixed. The prefix will be added automatically.
  7. Install the GitHub App if you haven't done this already.
  8. Do a Git push to trigger a build
  9. Await the success status on the commit then click it to follow through to the live link

View your overview page at: https://system.DOMAIN-NAME.TLD/dashboard/username

Example from reference repository:

We'll encrypt an incoming webhook URL for Slack, which should be considered as confidential information.

Let's write the example function:

def handle(req):
    webhook_url = None
    with open("/var/openfaas/secrets/incoming-webhook-url") as webhook_url_text:
        webhook_url = webhook_url_text.read().strip()

    respond_to_user(req, webhook_url)
handler.py

We see that the secret is read as per any other OpenFaaS secret, from the mounted location on disk at: /var/openfaas/secrets/.

Now let's look at how we seal the secret:

# Seal secrets for owner alexellis named `fn-secrets`

faas-cli cloud seal --name alexellis-fn-secrets --literal incoming-webhook-url=https://...

Here's the file generated by the command above:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: alexellis-fn-secrets
  namespace: openfaas-fn
spec:
  encryptedData:
    incoming-webhook-url: (redacted)
secrets.yaml

And finally, we now need to reference the name of our secret in stack.yml. Notice that the key and the secret name do not have to match, this is because we can have multiple secret key/values within a single secret.

provider:
  name: faas
  gateway: http://127.0.0.1:8080

functions:
  slack-me:
    lang: python
    handler: ./slack-me
    image: alexellis/slack-me
    secrets:
      - fn-secrets
stack.yml

Troubleshooting

The steps above must be followed precisely and if you have mis-read any of the details this may result in the secret not being accessible.

Notes:

  • When using kubeseal your secret name needs to be prefixed with your username i.e. alexellis-my-secret
  • Each --literal must have no prefix, it's the exact name you will use in stack.yml
  • In stack.yml your secrets should have no prefix, this is added later automatically
  • You must commit secrets.yaml into your repo and do a git push

If in doubt check your results against this reference repository.