Skip to main content

Looking up values from secrets

This guide describes how to store sensitive information in Kubernetes Secrets instead of the Teleport Kubernetes operator CRs.

How it works

Some Teleport resources might contain sensitive values. Select CR fields can reference an existing Kubernetes secret and the operator will retrieve the value from the secret when reconciling.

Currently only the GithubConnector and OIDCConnector client_secret field support secret lookup.

Prerequisites

To follow this guide you need:

  • A running Teleport cluster
  • A functional Teleport Kubernetes operator setup
  • Kubernetes rights to edit CRs and Secrets in the operator namespace
  • kubectl installed locally and configured for your Kubernetes cluster
  • A working GitHub or OIDC connector you want to manage with the operator
  • tctl and tsh installed and logged in the Teleport cluster

Important Considerations

Even when you store sensitive values out of CRs, the CRs must still be considered as critical as the Kubernetes secrets themselves. Many CRs configure Teleport RBAC. Someone with permissions to edit CRs can become a Teleport administrator and retrieve the sensitive values from Teleport.

The secret lookup feature has two limitations you must take into account before configuring it:

  • for performance reasons, the secret is not watched. A secret content change is not immediately reflected on the resource. To force the operator to use the new secret value, you must trigger a reconciliation by editing the CR, restarting the operator, or waiting for the next full sync (every 12 hours).
  • for security reasons, the operator doesn't allow lookup from arbitrary secrets. The secret must be annotated with resources.teleport.dev/allow-lookup-from-cr. Possible values are *, or a comma-separated list of CR names.

Step 1/3. Create a Kubernetes Secret containing the sensitive value

For this guide, the sensitive value we want to store is the GitHub connector client secret.

Create the following secret.yaml manifest:

apiVersion: v1
kind: Secret
metadata:
name: teleport-github-connector
annotations:
# This annotation allows any CR to look up this secret
resources.teleport.dev/allow-lookup-from-cr: "*"
# We use stringData instead of data for the sake of simplicity, both are OK
stringData:
githubSecret: my-github-secret-value

If teleport-iac is your Teleport Kubernetes operator namespace, apply the manifest using kubectl:

$ kubectl apply -n teleport-iac -f secret.yaml
secret/teleport-github-connector created

Step 2/3. Create a custom resource referencing the secret

Create the following github-connector.yaml manifest:

apiVersion: resources.teleport.dev/v3
kind: TeleportGithubConnector
metadata:
name: github
spec:
# This value will be looked up from the secret. `teleport-github-connector` is the secret name and `githubSecret` is the secret key.
client_secret: "secret://teleport-github-connector/githubSecret"
# Replace all the values below by the ones to work with your github account
client_id: my-client-id
display: Github
redirect_url: "my value"
teams_to_roles:
- organization: ORG-NAME
roles:
- access
team: team-name

Apply the manifest in the same namespace as the operator and the secret:

$ kubectl apply -n teleport-iac -f github-connector.yaml
teleportgithubconnector.resources.teleport.dev/github created

Step 3/3. Validate the resource was created

The operator indicates if the reconciliation worked on the CR status field. Run the following command to know if it worked:

$ kubectl get -n -n teleport-iac teleportgithubconnector github -o yaml

apiVersion: resources.teleport.dev/v3
kind: TeleportGithubConnector
# [...]
status:
conditions:
- lastTransitionTime: "2022-07-25T16:15:52Z"
message: Teleport resource has the Kubernetes origin label.
reason: OriginLabelMatching
status: "True"
type: TeleportResourceOwned
- lastTransitionTime: "2022-07-25T17:08:58Z"
message: 'Teleport Resource was successfully reconciled, no error was returned by Teleport.'
reason: NoError
status: "True"
type: SuccessfullyReconciled

If everything worked, all condition statuses should be True. Of some status is False, the message and the reason will give you more information about what failed.

Finally, validate the resource has been properly created in Teleport:

$ tctl get github
version: v3
kind: github
metadata:
name: github
spec:
client_secret: "my-github-secret-value"
# ...

You should see that the content of spec.client_secret has been replaced by the secret's content.