From 678a63187b3de045fbb185c0096c8e77b659c255 Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Mon, 16 Sep 2024 15:26:08 -0400 Subject: [PATCH 1/9] Allow operator secret lookup --- .../resources/github_connector_controller.go | 15 ++++++ .../github_connector_controller_test.go | 51 +++++++++++++++++++ .../resources/oidc_connector_controller.go | 15 ++++++ .../oidc_connector_controller_test.go | 51 +++++++++++++++++++ 4 files changed, 132 insertions(+) diff --git a/integrations/operator/controllers/resources/github_connector_controller.go b/integrations/operator/controllers/resources/github_connector_controller.go index cb400d3ce4c7..36c2b42bfde4 100644 --- a/integrations/operator/controllers/resources/github_connector_controller.go +++ b/integrations/operator/controllers/resources/github_connector_controller.go @@ -20,6 +20,7 @@ package resources import ( "context" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" "github.com/gravitational/trace" kclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -34,6 +35,7 @@ import ( // githubConnectorClient implements TeleportResourceClient and offers CRUD methods needed to reconcile github_connectors type githubConnectorClient struct { teleportClient *client.Client + kubeClient kclient.Client } // Get gets the Teleport github_connector of a given name @@ -59,10 +61,23 @@ func (r githubConnectorClient) Delete(ctx context.Context, name string) error { return trace.Wrap(r.teleportClient.DeleteGithubConnector(ctx, name)) } +func (r githubConnectorClient) Mutate(ctx context.Context, new, _ types.GithubConnector, crKey kclient.ObjectKey) error { + secret := new.GetClientSecret() + if secretlookup.IsNeeded(secret) { + resolvedSecret, err := secretlookup.Try(ctx, r.kubeClient, crKey.Name, crKey.Namespace, secret) + if err != nil { + return trace.Wrap(err) + } + new.SetClientSecret(resolvedSecret) + } + return nil +} + // NewGithubConnectorReconciler instantiates a new Kubernetes controller reconciling github_connector resources func NewGithubConnectorReconciler(client kclient.Client, tClient *client.Client) (controllers.Reconciler, error) { githubClient := &githubConnectorClient{ teleportClient: tClient, + kubeClient: client, } resourceReconciler, err := reconcilers.NewTeleportResourceWithoutLabelsReconciler[types.GithubConnector, *resourcesv3.TeleportGithubConnector]( diff --git a/integrations/operator/controllers/resources/github_connector_controller_test.go b/integrations/operator/controllers/resources/github_connector_controller_test.go index 321f61cfae73..136544b526c1 100644 --- a/integrations/operator/controllers/resources/github_connector_controller_test.go +++ b/integrations/operator/controllers/resources/github_connector_controller_test.go @@ -24,12 +24,15 @@ import ( "github.com/google/go-cmp/cmp" "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gravitational/teleport/api/types" resourcesv3 "github.com/gravitational/teleport/integrations/operator/apis/resources/v3" "github.com/gravitational/teleport/integrations/operator/controllers/reconcilers" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" "github.com/gravitational/teleport/integrations/operator/controllers/resources/testlib" ) @@ -136,3 +139,51 @@ func TestGithubConnectorUpdate(t *testing.T) { test := &githubTestingPrimitives{} testlib.ResourceUpdateTest[types.GithubConnector, *resourcesv3.TeleportGithubConnector](t, test) } + +func TestGithubConnectorSecretLookup(t *testing.T) { + test := &githubTestingPrimitives{} + setup := testlib.SetupTestEnv(t) + test.Init(setup) + ctx := context.Background() + + crName := validRandomResourceName("github") + secretName := validRandomResourceName("github-secret") + secretKey := "client-secret" + secretValue := validRandomResourceName("secret-value") + + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: setup.Namespace.Name, + Annotations: map[string]string{ + secretlookup.AllowInclusionAnnotation: crName, + }, + }, + StringData: map[string]string{ + secretKey: secretValue, + }, + Type: v1.SecretTypeOpaque, + } + kubeClient := setup.K8sClient + require.NoError(t, kubeClient.Create(ctx, secret)) + + github := &resourcesv3.TeleportGithubConnector{ + ObjectMeta: metav1.ObjectMeta{ + Name: crName, + Namespace: setup.Namespace.Name, + }, + Spec: resourcesv3.TeleportGithubConnectorSpec(githubSpec), + } + + github.Spec.ClientSecret = "secret://" + secretName + "/" + secretKey + + require.NoError(t, kubeClient.Create(ctx, github)) + + testlib.FastEventually(t, func() bool { + gh, err := test.GetTeleportResource(ctx, crName) + if err != nil { + return false + } + return gh.GetClientSecret() == secretValue + }) +} diff --git a/integrations/operator/controllers/resources/oidc_connector_controller.go b/integrations/operator/controllers/resources/oidc_connector_controller.go index d6f5cc340184..1010ad1b6750 100644 --- a/integrations/operator/controllers/resources/oidc_connector_controller.go +++ b/integrations/operator/controllers/resources/oidc_connector_controller.go @@ -20,6 +20,7 @@ package resources import ( "context" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" "github.com/gravitational/trace" kclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -34,6 +35,7 @@ import ( // oidcConnectorClient implements TeleportResourceClient and offers CRUD methods needed to reconcile oidc_connectors type oidcConnectorClient struct { teleportClient *client.Client + kubeClient kclient.Client } // Get gets the Teleport oidc_connector of a given name @@ -59,10 +61,23 @@ func (r oidcConnectorClient) Delete(ctx context.Context, name string) error { return trace.Wrap(r.teleportClient.DeleteOIDCConnector(ctx, name)) } +func (r oidcConnectorClient) Mutate(ctx context.Context, new, _ types.OIDCConnector, crKey kclient.ObjectKey) error { + secret := new.GetClientSecret() + if secretlookup.IsNeeded(secret) { + resolvedSecret, err := secretlookup.Try(ctx, r.kubeClient, crKey.Name, crKey.Namespace, secret) + if err != nil { + return trace.Wrap(err) + } + new.SetClientSecret(resolvedSecret) + } + return nil +} + // NewOIDCConnectorReconciler instantiates a new Kubernetes controller reconciling oidc_connector resources func NewOIDCConnectorReconciler(client kclient.Client, tClient *client.Client) (controllers.Reconciler, error) { oidcClient := &oidcConnectorClient{ teleportClient: tClient, + kubeClient: client, } resourceReconciler, err := reconcilers.NewTeleportResourceWithoutLabelsReconciler[types.OIDCConnector, *resourcesv3.TeleportOIDCConnector]( diff --git a/integrations/operator/controllers/resources/oidc_connector_controller_test.go b/integrations/operator/controllers/resources/oidc_connector_controller_test.go index 5b3984ce7b6e..21f67e6a112d 100644 --- a/integrations/operator/controllers/resources/oidc_connector_controller_test.go +++ b/integrations/operator/controllers/resources/oidc_connector_controller_test.go @@ -20,6 +20,9 @@ package resources_test import ( "context" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" "testing" "github.com/google/go-cmp/cmp" @@ -135,3 +138,51 @@ func TestOIDCConnectorUpdate(t *testing.T) { test := &oidcTestingPrimitives{} testlib.ResourceUpdateTest[types.OIDCConnector, *resourcesv3.TeleportOIDCConnector](t, test) } + +func TestOIDCConnectorSecretLookup(t *testing.T) { + test := &oidcTestingPrimitives{} + setup := testlib.SetupTestEnv(t) + test.Init(setup) + ctx := context.Background() + + crName := validRandomResourceName("oidc") + secretName := validRandomResourceName("oidc-secret") + secretKey := "client-secret" + secretValue := validRandomResourceName("secret-value") + + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: setup.Namespace.Name, + Annotations: map[string]string{ + secretlookup.AllowInclusionAnnotation: crName, + }, + }, + StringData: map[string]string{ + secretKey: secretValue, + }, + Type: v1.SecretTypeOpaque, + } + kubeClient := setup.K8sClient + require.NoError(t, kubeClient.Create(ctx, secret)) + + oidc := &resourcesv3.TeleportOIDCConnector{ + ObjectMeta: metav1.ObjectMeta{ + Name: crName, + Namespace: setup.Namespace.Name, + }, + Spec: resourcesv3.TeleportOIDCConnectorSpec(oidcSpec), + } + + oidc.Spec.ClientSecret = "secret://" + secretName + "/" + secretKey + + require.NoError(t, kubeClient.Create(ctx, oidc)) + + testlib.FastEventually(t, func() bool { + oidc, err := test.GetTeleportResource(ctx, crName) + if err != nil { + return false + } + return oidc.GetClientSecret() == secretValue + }) +} From 5ac88035dd21cda8788f20f16a7d960b8bdc49c9 Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Tue, 17 Sep 2024 11:32:35 -0400 Subject: [PATCH 2/9] Document which fields can lookup secrets --- ...esources.teleport.dev_githubconnectors.mdx | 2 +- .../resources.teleport.dev_oidcconnectors.mdx | 2 +- ...sources.teleport.dev_githubconnectors.yaml | 4 ++- ...resources.teleport.dev_oidcconnectors.yaml | 4 ++- .../teleport-operator/templates/role.yaml | 10 ++++++ .../teleport-operator/tests/role_test.yaml | 9 ++++++ ...sources.teleport.dev_githubconnectors.yaml | 4 ++- ...resources.teleport.dev_oidcconnectors.yaml | 4 ++- .../operator/crdgen/additional_doc.go | 32 +++++++++++++++++++ integrations/operator/crdgen/schemagen.go | 11 +++++-- ...sources.teleport.dev_githubconnectors.yaml | 4 ++- ...resources.teleport.dev_oidcconnectors.yaml | 4 ++- 12 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 integrations/operator/crdgen/additional_doc.go diff --git a/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx b/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx index 66132ae92133..0b95b075c0a7 100644 --- a/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx +++ b/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx @@ -29,7 +29,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |api_endpoint_url|string|APIEndpointURL is the URL of the API endpoint of the Github instance this connector is for.| |client_id|string|ClientID is the Github OAuth app client ID.| |client_redirect_settings|[object](#specclient_redirect_settings)|ClientRedirectSettings defines which client redirect URLs are allowed for non-browser SSO logins other than the standard localhost ones.| -|client_secret|string|ClientSecret is the Github OAuth app client secret.| +|client_secret|string|ClientSecret is the Github OAuth app client secret. This field supports secret lookup. See the operator documentation for more details.| |display|string|Display is the connector display name.| |endpoint_url|string|EndpointURL is the URL of the GitHub instance this connector is for.| |redirect_url|string|RedirectURL is the authorization callback URL.| diff --git a/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx b/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx index 1b650cbd95b4..891d87a06763 100644 --- a/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx +++ b/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx @@ -31,7 +31,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |claims_to_roles|[][object](#specclaims_to_roles-items)|ClaimsToRoles specifies a dynamic mapping from claims to roles.| |client_id|string|ClientID is the id of the authentication client (Teleport Auth server).| |client_redirect_settings|[object](#specclient_redirect_settings)|ClientRedirectSettings defines which client redirect URLs are allowed for non-browser SSO logins other than the standard localhost ones.| -|client_secret|string|ClientSecret is used to authenticate the client.| +|client_secret|string|ClientSecret is used to authenticate the client. This field supports secret lookup. See the operator documentation for more details.| |display|string|Display is the friendly name for this provider.| |google_admin_email|string|GoogleAdminEmail is the email of a google admin to impersonate.| |google_service_account|string|GoogleServiceAccount is a string containing google service account credentials.| diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml index a92d5dbf5eff..be8404b633bc 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml @@ -64,7 +64,9 @@ spec: type: array type: object client_secret: - description: ClientSecret is the Github OAuth app client secret. + description: ClientSecret is the Github OAuth app client secret. This + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the connector display name. diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml index b801cf6db84f..10bbfed040a5 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml @@ -89,7 +89,9 @@ spec: type: array type: object client_secret: - description: ClientSecret is used to authenticate the client. + description: ClientSecret is used to authenticate the client. This + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the friendly name for this provider. diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml index 666c2ae7bed9..90bf13b69cc5 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml @@ -6,6 +6,7 @@ metadata: name: {{ include "teleport-cluster.operator.fullname" . }} namespace: {{ .Release.Namespace }} rules: + # Rights to manage the Teleport CRs - apiGroups: - "resources.teleport.dev" resources: @@ -41,6 +42,7 @@ rules: - patch - update - watch + # Used to perform leader election when running with multiple replicas - apiGroups: - "coordination.k8s.io" resources: @@ -49,11 +51,19 @@ rules: - create - get - update + # Ability to emit reconciliation events - apiGroups: - "" resources: - events verbs: - create + # Ability to lookup sensitive values from secrets rather than CRs + - apiGroups: + - "" + resources: + - "secrets" + verbs: + - "get" {{- end -}} {{- end -}} diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/tests/role_test.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/tests/role_test.yaml index a0dce6550486..3cbb29023dfa 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/tests/role_test.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/tests/role_test.yaml @@ -41,3 +41,12 @@ tests: kind: Role apiVersion: rbac.authorization.k8s.io/v1 name: RELEASE-NAME-operator + + - it: grants access to secret in the namespace + asserts: + - contains: + path: rules + content: + apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] \ No newline at end of file diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml index a92d5dbf5eff..be8404b633bc 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml @@ -64,7 +64,9 @@ spec: type: array type: object client_secret: - description: ClientSecret is the Github OAuth app client secret. + description: ClientSecret is the Github OAuth app client secret. This + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the connector display name. diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml index b801cf6db84f..10bbfed040a5 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml @@ -89,7 +89,9 @@ spec: type: array type: object client_secret: - description: ClientSecret is used to authenticate the client. + description: ClientSecret is used to authenticate the client. This + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the friendly name for this provider. diff --git a/integrations/operator/crdgen/additional_doc.go b/integrations/operator/crdgen/additional_doc.go new file mode 100644 index 000000000000..0beab2b0cbb9 --- /dev/null +++ b/integrations/operator/crdgen/additional_doc.go @@ -0,0 +1,32 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package crdgen + +const supportsSecretLookupDescription = `This field supports secret lookup. See the operator documentation for more details.` + +// additionalDescription contains additional description we want to add to select fields. +// This is used to document operator-specific behaviours, such as the secret lookup. +var additionalDescription = map[string]map[string]string{ + "GithubConnectorSpecV3": { + "ClientSecret": supportsSecretLookupDescription, + }, + "OIDCConnectorSpecV3": { + "ClientSecret": supportsSecretLookupDescription, + }, +} diff --git a/integrations/operator/crdgen/schemagen.go b/integrations/operator/crdgen/schemagen.go index 8f4c3c7795ec..9862780b66d2 100644 --- a/integrations/operator/crdgen/schemagen.go +++ b/integrations/operator/crdgen/schemagen.go @@ -280,6 +280,7 @@ func (generator *SchemaGenerator) traverseInner(message *Message) (*Schema, erro generator.memo[name] = schema for _, field := range message.Fields { + // Skip the ignored fields if _, ok := ignoredFields[message.Name()][field.Name()]; ok { continue } @@ -296,11 +297,17 @@ func (generator *SchemaGenerator) traverseInner(message *Message) (*Schema, erro continue } - var err error - schema.Properties[jsonName], err = generator.prop(field) + prop, err := generator.prop(field) if err != nil { return nil, trace.Wrap(err) } + + // If the field has custom additional description, we append it. + if desc, ok := additionalDescription[message.Name()][field.Name()]; ok { + prop.Description = prop.Description + " " + desc + } + + schema.Properties[jsonName] = prop } schema.built = true diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml index a92d5dbf5eff..be8404b633bc 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml @@ -64,7 +64,9 @@ spec: type: array type: object client_secret: - description: ClientSecret is the Github OAuth app client secret. + description: ClientSecret is the Github OAuth app client secret. This + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the connector display name. diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml index b801cf6db84f..10bbfed040a5 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml @@ -89,7 +89,9 @@ spec: type: array type: object client_secret: - description: ClientSecret is used to authenticate the client. + description: ClientSecret is used to authenticate the client. This + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the friendly name for this provider. From e316467c9eae16df2ef67f211cb32b8cfe7ae02b Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Tue, 17 Sep 2024 18:54:17 -0400 Subject: [PATCH 3/9] operator: support secret lookup --- .../teleport-operator.mdx | 11 ++ .../teleport-operator/secret-lookup.mdx | 135 ++++++++++++++++++ .../github_connector_controller_test.go | 2 +- .../oidc_connector_controller_test.go | 2 +- .../resources/secretlookup/secretlookup.go | 12 +- .../secretlookup/secretlookup_test.go | 14 +- 6 files changed, 161 insertions(+), 15 deletions(-) create mode 100644 docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx diff --git a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx index 118d00180741..73031efa0cff 100644 --- a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx +++ b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx @@ -72,6 +72,17 @@ finalizer or remove the ignore annotation. Possible values are `"true"` or `"false"` (those are strings, as Booleans are not valid label values in Kubernetes). +### Lookup values from secrets + +Some Teleport resources might contain sensitive values. Since 16.4, select CR fields can reference an existing +Kubernetes secret and the operator will retrieve the value from the secret when reconciling. + +Although this allows storing sensitive values out of CRs, the CRs must still be considered as critical as +the Kubernetes secrets themselves. Many CRs allow to configure Teleport RBAC, someone with CR edition rights can become +Teleport administrator and retrieve the sensitive values from Teleport. + +See [the dedicated guide](./teleport-operator/secret-lookup.mdx) for more details. + ### Troubleshooting (!docs/pages/includes/diagnostics/kubernetes-operator-troubleshooting.mdx!) diff --git a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx new file mode 100644 index 000000000000..5387b7567d0c --- /dev/null +++ b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx @@ -0,0 +1,135 @@ +--- +title: Looking up values from secrets +description: How to store sensitive values in a Kubernetes Secret and have the operator look them up. +--- + +## Introduction + +Some Teleport resources might contain sensitive values. Since Teleport 16.4, select CR fields can reference an existing +Kubernetes secret and the operator will retrieve the value from the secret when reconciling. + +This guide shows how to reference values from Kubernetes Secrets in your Teleport Kubernetes Operator CRs. + +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](../teleport-operator.mdx#setting-up-the-operator) +- 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 + +Although this allows storing sensitive values out of CRs, the CRs must still be considered as critical as +the Kubernetes secrets themselves. Many CRs allow to configure Teleport RBAC, someone with CR edition rights can become +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 does 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/2. 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: + +```yaml +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 is your Teleport Kubernetes Operator namespace, apply the manifest using `kubectl`: + +```code +$ kubectl apply -n -f secret.yaml +secret/teleport-github-connector created +``` + +## Step 2/2. Create a CR referencing the secret + +Create the following `github-connector.yaml` manifest: + +```yaml +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: + +```code +$ kubectl apply -n -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: + +```code +$ kubectl get -n -n 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 by doing: +```code +$ 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. + diff --git a/integrations/operator/controllers/resources/github_connector_controller_test.go b/integrations/operator/controllers/resources/github_connector_controller_test.go index 136544b526c1..2bc074a1825f 100644 --- a/integrations/operator/controllers/resources/github_connector_controller_test.go +++ b/integrations/operator/controllers/resources/github_connector_controller_test.go @@ -156,7 +156,7 @@ func TestGithubConnectorSecretLookup(t *testing.T) { Name: secretName, Namespace: setup.Namespace.Name, Annotations: map[string]string{ - secretlookup.AllowInclusionAnnotation: crName, + secretlookup.AllowLookupAnnotation: crName, }, }, StringData: map[string]string{ diff --git a/integrations/operator/controllers/resources/oidc_connector_controller_test.go b/integrations/operator/controllers/resources/oidc_connector_controller_test.go index 21f67e6a112d..eccb970b7fe0 100644 --- a/integrations/operator/controllers/resources/oidc_connector_controller_test.go +++ b/integrations/operator/controllers/resources/oidc_connector_controller_test.go @@ -155,7 +155,7 @@ func TestOIDCConnectorSecretLookup(t *testing.T) { Name: secretName, Namespace: setup.Namespace.Name, Annotations: map[string]string{ - secretlookup.AllowInclusionAnnotation: crName, + secretlookup.AllowLookupAnnotation: crName, }, }, StringData: map[string]string{ diff --git a/integrations/operator/controllers/resources/secretlookup/secretlookup.go b/integrations/operator/controllers/resources/secretlookup/secretlookup.go index 68d25b5f0e24..a156b9cc47c8 100644 --- a/integrations/operator/controllers/resources/secretlookup/secretlookup.go +++ b/integrations/operator/controllers/resources/secretlookup/secretlookup.go @@ -35,9 +35,9 @@ const ( secretScheme = "secret" secretPrefix = secretScheme + "://" - // AllowInclusionAnnotation is the annotation a secret must wear for the operator to allow looking up its content + // AllowLookupAnnotation is the annotation a secret must wear for the operator to allow looking up its content // when reconciling a resource. Its value is either a comma-separated list of allowed resources, or a '*'. - AllowInclusionAnnotation = "resources.teleport.dev/allow-inclusion-from-cr" + AllowLookupAnnotation = "resources.teleport.dev/allow-lookup-from-cr" ) // IsNeeded checks if a string starts with "secret://" and needs a secret lookup. @@ -89,13 +89,13 @@ func Try(ctx context.Context, clt kclient.Client, name, namespace, uri string) ( } // isInclusionAllowed checks if the secret allows inclusion from the CR. -// The secret must wear the AllowInclusionAnnotation and the annotation must either +// The secret must wear the AllowLookupAnnotation and the annotation must either // explicitly allow the resource, or allow any resource ("*"). func isInclusionAllowed(secret *corev1.Secret, name string) error { secretName := secret.Name - annotation, ok := secret.Annotations[AllowInclusionAnnotation] + annotation, ok := secret.Annotations[AllowLookupAnnotation] if !ok { - return trace.BadParameter("secret %q doesn't have the %q annotation", secretName, AllowInclusionAnnotation) + return trace.BadParameter("secret %q doesn't have the %q annotation", secretName, AllowLookupAnnotation) } if annotation == types.Wildcard { return nil @@ -106,5 +106,5 @@ func isInclusionAllowed(secret *corev1.Secret, name string) error { return nil } } - return trace.AccessDenied("secret %q have the annotation %q but it does not contain %q", secretName, AllowInclusionAnnotation, name) + return trace.AccessDenied("secret %q have the annotation %q but it does not contain %q", secretName, AllowLookupAnnotation, name) } diff --git a/integrations/operator/controllers/resources/secretlookup/secretlookup_test.go b/integrations/operator/controllers/resources/secretlookup/secretlookup_test.go index ec01f14b465d..64fea92f94b1 100644 --- a/integrations/operator/controllers/resources/secretlookup/secretlookup_test.go +++ b/integrations/operator/controllers/resources/secretlookup/secretlookup_test.go @@ -53,7 +53,7 @@ func TestLookupSecret(t *testing.T) { Type: v1.SecretTypeOpaque, } } - okAnnotations := map[string]string{AllowInclusionAnnotation: strings.Join([]string{"other-cr-name", crName}, ", ")} + okAnnotations := map[string]string{AllowLookupAnnotation: strings.Join([]string{"other-cr-name", crName}, ", ")} okSecret := secretWithAnnotations(okAnnotations) // Test setup: defining test cases @@ -107,7 +107,7 @@ func TestLookupSecret(t *testing.T) { { name: "secret annotations don't allow inclusion", input: fmt.Sprintf("secret://%s/%s", secretName, keyName), - secrets: v1.SecretList{Items: []v1.Secret{secretWithAnnotations(map[string]string{AllowInclusionAnnotation: "not-the-right-cr"})}}, + secrets: v1.SecretList{Items: []v1.Secret{secretWithAnnotations(map[string]string{AllowLookupAnnotation: "not-the-right-cr"})}}, assertErr: func(t require.TestingT, err error, i ...interface{}) { require.ErrorContains(t, err, "does not contain") }, @@ -192,7 +192,7 @@ func Test_isInclusionAllowed(t *testing.T) { secret: v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ - AllowInclusionAnnotation: "", + AllowLookupAnnotation: "", }, }, }, @@ -203,7 +203,7 @@ func Test_isInclusionAllowed(t *testing.T) { secret: v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ - AllowInclusionAnnotation: "foo, bar", + AllowLookupAnnotation: "foo, bar", }, }, }, @@ -214,7 +214,7 @@ func Test_isInclusionAllowed(t *testing.T) { secret: v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ - AllowInclusionAnnotation: crName, + AllowLookupAnnotation: crName, }, }, }, @@ -225,7 +225,7 @@ func Test_isInclusionAllowed(t *testing.T) { secret: v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ - AllowInclusionAnnotation: strings.Join([]string{"foo", "bar", crName}, ", "), + AllowLookupAnnotation: strings.Join([]string{"foo", "bar", crName}, ", "), }, }, }, @@ -236,7 +236,7 @@ func Test_isInclusionAllowed(t *testing.T) { secret: v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ - AllowInclusionAnnotation: "*", + AllowLookupAnnotation: "*", }, }, }, From c16555de0910296d4c6345d81bb090ed54d67093 Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Tue, 17 Sep 2024 19:02:07 -0400 Subject: [PATCH 4/9] fixup! operator: support secret lookup --- .../infrastructure-as-code/teleport-operator.mdx | 4 ++-- .../teleport-operator/secret-lookup.mdx | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx index 73031efa0cff..237243851015 100644 --- a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx +++ b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx @@ -77,8 +77,8 @@ Possible values are `"true"` or `"false"` (those are strings, as Booleans are no Some Teleport resources might contain sensitive values. Since 16.4, select CR fields can reference an existing Kubernetes secret and the operator will retrieve the value from the secret when reconciling. -Although this allows storing sensitive values out of CRs, the CRs must still be considered as critical as -the Kubernetes secrets themselves. Many CRs allow to configure Teleport RBAC, someone with CR edition rights can become +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 CR edition rights can become Teleport administrator and retrieve the sensitive values from Teleport. See [the dedicated guide](./teleport-operator/secret-lookup.mdx) for more details. diff --git a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx index 5387b7567d0c..2c98a95c6b78 100644 --- a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx +++ b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx @@ -3,18 +3,17 @@ title: Looking up values from secrets description: How to store sensitive values in a Kubernetes Secret and have the operator look them up. --- -## Introduction +## How it works Some Teleport resources might contain sensitive values. Since Teleport 16.4, select CR fields can reference an existing Kubernetes secret and the operator will retrieve the value from the secret when reconciling. -This guide shows how to reference values from Kubernetes Secrets in your Teleport Kubernetes Operator CRs. - 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](../teleport-operator.mdx#setting-up-the-operator) - Kubernetes rights to edit CRs and Secrets in the operator namespace @@ -24,8 +23,8 @@ To follow this guide you need: ## Important Considerations -Although this allows storing sensitive values out of CRs, the CRs must still be considered as critical as -the Kubernetes secrets themselves. Many CRs allow to configure Teleport RBAC, someone with CR edition rights can become +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 CR edition rights can become Teleport administrator and retrieve the sensitive values from Teleport. The secret lookup feature has two limitations you must take into account before configuring it: @@ -35,7 +34,7 @@ The secret lookup feature has two limitations you must take into account before - for security reasons, the operator does 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/2. Create a Kubernetes Secret containing the sensitive value +## 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. @@ -61,7 +60,7 @@ $ kubectl apply -n -f secret.yaml secret/teleport-github-connector created ``` -## Step 2/2. Create a CR referencing the secret +## Step 2/3. Create a CR referencing the secret Create the following `github-connector.yaml` manifest: From 8f791b6da5e3fa2582bc290dddca978d4dedbc5c Mon Sep 17 00:00:00 2001 From: Hugo Shaka Date: Wed, 18 Sep 2024 16:10:30 -0400 Subject: [PATCH 5/9] Apply suggestions from code review Co-authored-by: Paul Gottschling Co-authored-by: Roman Tkachenko --- .../infrastructure-as-code/teleport-operator.mdx | 6 +++--- .../teleport-operator/secret-lookup.mdx | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx index 237243851015..ca6fe1ca2148 100644 --- a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx +++ b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator.mdx @@ -72,13 +72,13 @@ finalizer or remove the ignore annotation. Possible values are `"true"` or `"false"` (those are strings, as Booleans are not valid label values in Kubernetes). -### Lookup values from secrets +### Look up values from secrets -Some Teleport resources might contain sensitive values. Since 16.4, select CR fields can reference an existing +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. 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 CR edition rights can become +the Kubernetes secrets themselves. Many CRs configure Teleport RBAC. Someone with CR editing permissions can become a Teleport administrator and retrieve the sensitive values from Teleport. See [the dedicated guide](./teleport-operator/secret-lookup.mdx) for more details. diff --git a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx index 2c98a95c6b78..51814314cd0b 100644 --- a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx +++ b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx @@ -5,7 +5,7 @@ description: How to store sensitive values in a Kubernetes Secret and have the o ## How it works -Some Teleport resources might contain sensitive values. Since Teleport 16.4, select CR fields can reference an existing +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. @@ -24,14 +24,14 @@ To follow this guide you need: ## 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 CR edition rights can become +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 does allow lookup from arbitrary secrets. The secret must be annotated with +- 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 @@ -60,7 +60,7 @@ $ kubectl apply -n -f secret.yaml secret/teleport-github-connector created ``` -## Step 2/3. Create a CR referencing the secret +## Step 2/3. Create a custom resource referencing the secret Create the following `github-connector.yaml` manifest: @@ -83,7 +83,7 @@ spec: team: team-name ``` -Apply the manifest, in the same namespace as the operator and the secret: +Apply the manifest in the same namespace as the operator and the secret: ```code $ kubectl apply -n -f github-connector.yaml @@ -118,7 +118,7 @@ status: 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 by doing: +Finally, validate the resource has been properly created in Teleport: ```code $ tctl get github version: v3 From 178fe3fe32246b5f560362c158291eb2f5cf5708 Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Fri, 20 Sep 2024 10:02:28 -0400 Subject: [PATCH 6/9] lint --- docs/cspell.json | 1 + .../controllers/resources/github_connector_controller.go | 2 +- .../controllers/resources/oidc_connector_controller.go | 2 +- .../controllers/resources/oidc_connector_controller_test.go | 6 +++--- integrations/operator/crdgen/additional_doc.go | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/cspell.json b/docs/cspell.json index 2bedf8ff506e..fa8bd97efc41 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -910,6 +910,7 @@ "teleportdevname", "teleportdevprotocol", "teleporters", + "teleportgithubconnector", "teleportinfra", "teleportopensshserverv", "teleportproxy", diff --git a/integrations/operator/controllers/resources/github_connector_controller.go b/integrations/operator/controllers/resources/github_connector_controller.go index 36c2b42bfde4..f0d2884b6feb 100644 --- a/integrations/operator/controllers/resources/github_connector_controller.go +++ b/integrations/operator/controllers/resources/github_connector_controller.go @@ -20,7 +20,6 @@ package resources import ( "context" - "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" "github.com/gravitational/trace" kclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -30,6 +29,7 @@ import ( resourcesv3 "github.com/gravitational/teleport/integrations/operator/apis/resources/v3" "github.com/gravitational/teleport/integrations/operator/controllers" "github.com/gravitational/teleport/integrations/operator/controllers/reconcilers" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" ) // githubConnectorClient implements TeleportResourceClient and offers CRUD methods needed to reconcile github_connectors diff --git a/integrations/operator/controllers/resources/oidc_connector_controller.go b/integrations/operator/controllers/resources/oidc_connector_controller.go index 1010ad1b6750..360e4c572ff7 100644 --- a/integrations/operator/controllers/resources/oidc_connector_controller.go +++ b/integrations/operator/controllers/resources/oidc_connector_controller.go @@ -20,7 +20,6 @@ package resources import ( "context" - "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" "github.com/gravitational/trace" kclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -30,6 +29,7 @@ import ( resourcesv3 "github.com/gravitational/teleport/integrations/operator/apis/resources/v3" "github.com/gravitational/teleport/integrations/operator/controllers" "github.com/gravitational/teleport/integrations/operator/controllers/reconcilers" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" ) // oidcConnectorClient implements TeleportResourceClient and offers CRUD methods needed to reconcile oidc_connectors diff --git a/integrations/operator/controllers/resources/oidc_connector_controller_test.go b/integrations/operator/controllers/resources/oidc_connector_controller_test.go index eccb970b7fe0..35228bc8188f 100644 --- a/integrations/operator/controllers/resources/oidc_connector_controller_test.go +++ b/integrations/operator/controllers/resources/oidc_connector_controller_test.go @@ -20,19 +20,19 @@ package resources_test import ( "context" - "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" - "github.com/stretchr/testify/require" - v1 "k8s.io/api/core/v1" "testing" "github.com/google/go-cmp/cmp" "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gravitational/teleport/api/types" resourcesv3 "github.com/gravitational/teleport/integrations/operator/apis/resources/v3" "github.com/gravitational/teleport/integrations/operator/controllers/reconcilers" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/secretlookup" "github.com/gravitational/teleport/integrations/operator/controllers/resources/testlib" ) diff --git a/integrations/operator/crdgen/additional_doc.go b/integrations/operator/crdgen/additional_doc.go index 0beab2b0cbb9..2458af6779bb 100644 --- a/integrations/operator/crdgen/additional_doc.go +++ b/integrations/operator/crdgen/additional_doc.go @@ -21,7 +21,7 @@ package crdgen const supportsSecretLookupDescription = `This field supports secret lookup. See the operator documentation for more details.` // additionalDescription contains additional description we want to add to select fields. -// This is used to document operator-specific behaviours, such as the secret lookup. +// This is used to document operator-specific behaviors, such as the secret lookup. var additionalDescription = map[string]map[string]string{ "GithubConnectorSpecV3": { "ClientSecret": supportsSecretLookupDescription, From 748d1a8aa5f442771e44a89a1b28c8857b25527c Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Fri, 20 Sep 2024 11:04:06 -0400 Subject: [PATCH 7/9] add link to operator docs --- .../resources.teleport.dev_githubconnectors.mdx | 2 +- .../resources.teleport.dev_oidcconnectors.mdx | 2 +- .../resources.teleport.dev_githubconnectors.yaml | 4 ++-- .../operator-crds/resources.teleport.dev_oidcconnectors.yaml | 4 ++-- .../crd/bases/resources.teleport.dev_githubconnectors.yaml | 4 ++-- .../crd/bases/resources.teleport.dev_oidcconnectors.yaml | 4 ++-- integrations/operator/crdgen/additional_doc.go | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx b/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx index 0b95b075c0a7..d9fb368af75f 100644 --- a/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx +++ b/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx @@ -29,7 +29,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |api_endpoint_url|string|APIEndpointURL is the URL of the API endpoint of the Github instance this connector is for.| |client_id|string|ClientID is the Github OAuth app client ID.| |client_redirect_settings|[object](#specclient_redirect_settings)|ClientRedirectSettings defines which client redirect URLs are allowed for non-browser SSO logins other than the standard localhost ones.| -|client_secret|string|ClientSecret is the Github OAuth app client secret. This field supports secret lookup. See the operator documentation for more details.| +|client_secret|string|ClientSecret is the Github OAuth app client secret. This field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) for more details.| |display|string|Display is the connector display name.| |endpoint_url|string|EndpointURL is the URL of the GitHub instance this connector is for.| |redirect_url|string|RedirectURL is the authorization callback URL.| diff --git a/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx b/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx index 891d87a06763..eb8a662a9b87 100644 --- a/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx +++ b/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx @@ -31,7 +31,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |claims_to_roles|[][object](#specclaims_to_roles-items)|ClaimsToRoles specifies a dynamic mapping from claims to roles.| |client_id|string|ClientID is the id of the authentication client (Teleport Auth server).| |client_redirect_settings|[object](#specclient_redirect_settings)|ClientRedirectSettings defines which client redirect URLs are allowed for non-browser SSO logins other than the standard localhost ones.| -|client_secret|string|ClientSecret is used to authenticate the client. This field supports secret lookup. See the operator documentation for more details.| +|client_secret|string|ClientSecret is used to authenticate the client. This field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) for more details.| |display|string|Display is the friendly name for this provider.| |google_admin_email|string|GoogleAdminEmail is the email of a google admin to impersonate.| |google_service_account|string|GoogleServiceAccount is a string containing google service account credentials.| diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml index be8404b633bc..54a0b93af19e 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml @@ -65,8 +65,8 @@ spec: type: object client_secret: description: ClientSecret is the Github OAuth app client secret. This - field supports secret lookup. See the operator documentation for - more details. + field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) + for more details. type: string display: description: Display is the connector display name. diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml index 10bbfed040a5..7a1dd9fec605 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml @@ -90,8 +90,8 @@ spec: type: object client_secret: description: ClientSecret is used to authenticate the client. This - field supports secret lookup. See the operator documentation for - more details. + field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) + for more details. type: string display: description: Display is the friendly name for this provider. diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml index be8404b633bc..54a0b93af19e 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml @@ -65,8 +65,8 @@ spec: type: object client_secret: description: ClientSecret is the Github OAuth app client secret. This - field supports secret lookup. See the operator documentation for - more details. + field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) + for more details. type: string display: description: Display is the connector display name. diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml index 10bbfed040a5..7a1dd9fec605 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml @@ -90,8 +90,8 @@ spec: type: object client_secret: description: ClientSecret is used to authenticate the client. This - field supports secret lookup. See the operator documentation for - more details. + field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) + for more details. type: string display: description: Display is the friendly name for this provider. diff --git a/integrations/operator/crdgen/additional_doc.go b/integrations/operator/crdgen/additional_doc.go index 2458af6779bb..f1e66333add3 100644 --- a/integrations/operator/crdgen/additional_doc.go +++ b/integrations/operator/crdgen/additional_doc.go @@ -18,7 +18,7 @@ package crdgen -const supportsSecretLookupDescription = `This field supports secret lookup. See the operator documentation for more details.` +const supportsSecretLookupDescription = `This field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) for more details.` // additionalDescription contains additional description we want to add to select fields. // This is used to document operator-specific behaviors, such as the secret lookup. From 8f9a3ccc17134a111b5eab01fa7575067a3df572 Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Fri, 20 Sep 2024 11:11:42 -0400 Subject: [PATCH 8/9] address feedback --- .../teleport-operator/secret-lookup.mdx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx index 51814314cd0b..9cf816d8a015 100644 --- a/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx +++ b/docs/pages/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup.mdx @@ -3,6 +3,9 @@ title: Looking up values from secrets description: How to store sensitive values in a Kubernetes Secret and have the operator look them up. --- +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 @@ -15,7 +18,7 @@ Currently only the GithubConnector and OIDCConnector `client_secret` field suppo To follow this guide you need: - A running Teleport cluster -- [A functional Teleport Kubernetes Operator setup](../teleport-operator.mdx#setting-up-the-operator) +- [A functional Teleport Kubernetes operator setup](../teleport-operator.mdx#setting-up-the-operator) - 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 @@ -53,7 +56,7 @@ stringData: githubSecret: my-github-secret-value ``` -If is your Teleport Kubernetes Operator namespace, apply the manifest using `kubectl`: +If is your Teleport Kubernetes operator namespace, apply the manifest using `kubectl`: ```code $ kubectl apply -n -f secret.yaml From 0655eeb0a70581b65b2801c4c41372a0f4966c0c Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Fri, 20 Sep 2024 12:00:35 -0400 Subject: [PATCH 9/9] Revert "add link to operator docs" This reverts commit cd812eb4534169eb632906daa5e90ba2ea4beef8. --- .../resources.teleport.dev_githubconnectors.mdx | 2 +- .../resources.teleport.dev_oidcconnectors.mdx | 2 +- .../resources.teleport.dev_githubconnectors.yaml | 4 ++-- .../operator-crds/resources.teleport.dev_oidcconnectors.yaml | 4 ++-- .../crd/bases/resources.teleport.dev_githubconnectors.yaml | 4 ++-- .../crd/bases/resources.teleport.dev_oidcconnectors.yaml | 4 ++-- integrations/operator/crdgen/additional_doc.go | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx b/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx index d9fb368af75f..0b95b075c0a7 100644 --- a/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx +++ b/docs/pages/reference/operator-resources/resources.teleport.dev_githubconnectors.mdx @@ -29,7 +29,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |api_endpoint_url|string|APIEndpointURL is the URL of the API endpoint of the Github instance this connector is for.| |client_id|string|ClientID is the Github OAuth app client ID.| |client_redirect_settings|[object](#specclient_redirect_settings)|ClientRedirectSettings defines which client redirect URLs are allowed for non-browser SSO logins other than the standard localhost ones.| -|client_secret|string|ClientSecret is the Github OAuth app client secret. This field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) for more details.| +|client_secret|string|ClientSecret is the Github OAuth app client secret. This field supports secret lookup. See the operator documentation for more details.| |display|string|Display is the connector display name.| |endpoint_url|string|EndpointURL is the URL of the GitHub instance this connector is for.| |redirect_url|string|RedirectURL is the authorization callback URL.| diff --git a/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx b/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx index eb8a662a9b87..891d87a06763 100644 --- a/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx +++ b/docs/pages/reference/operator-resources/resources.teleport.dev_oidcconnectors.mdx @@ -31,7 +31,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |claims_to_roles|[][object](#specclaims_to_roles-items)|ClaimsToRoles specifies a dynamic mapping from claims to roles.| |client_id|string|ClientID is the id of the authentication client (Teleport Auth server).| |client_redirect_settings|[object](#specclient_redirect_settings)|ClientRedirectSettings defines which client redirect URLs are allowed for non-browser SSO logins other than the standard localhost ones.| -|client_secret|string|ClientSecret is used to authenticate the client. This field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) for more details.| +|client_secret|string|ClientSecret is used to authenticate the client. This field supports secret lookup. See the operator documentation for more details.| |display|string|Display is the friendly name for this provider.| |google_admin_email|string|GoogleAdminEmail is the email of a google admin to impersonate.| |google_service_account|string|GoogleServiceAccount is a string containing google service account credentials.| diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml index 54a0b93af19e..be8404b633bc 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_githubconnectors.yaml @@ -65,8 +65,8 @@ spec: type: object client_secret: description: ClientSecret is the Github OAuth app client secret. This - field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) - for more details. + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the connector display name. diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml index 7a1dd9fec605..10bbfed040a5 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_oidcconnectors.yaml @@ -90,8 +90,8 @@ spec: type: object client_secret: description: ClientSecret is used to authenticate the client. This - field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) - for more details. + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the friendly name for this provider. diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml index 54a0b93af19e..be8404b633bc 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml @@ -65,8 +65,8 @@ spec: type: object client_secret: description: ClientSecret is the Github OAuth app client secret. This - field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) - for more details. + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the connector display name. diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml index 7a1dd9fec605..10bbfed040a5 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml @@ -90,8 +90,8 @@ spec: type: object client_secret: description: ClientSecret is used to authenticate the client. This - field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) - for more details. + field supports secret lookup. See the operator documentation for + more details. type: string display: description: Display is the friendly name for this provider. diff --git a/integrations/operator/crdgen/additional_doc.go b/integrations/operator/crdgen/additional_doc.go index f1e66333add3..2458af6779bb 100644 --- a/integrations/operator/crdgen/additional_doc.go +++ b/integrations/operator/crdgen/additional_doc.go @@ -18,7 +18,7 @@ package crdgen -const supportsSecretLookupDescription = `This field supports secret lookup. See [the operator documentation](https://goteleport.com/docs/admin-guides/infrastructure-as-code/teleport-operator/secret-lookup/) for more details.` +const supportsSecretLookupDescription = `This field supports secret lookup. See the operator documentation for more details.` // additionalDescription contains additional description we want to add to select fields. // This is used to document operator-specific behaviors, such as the secret lookup.