From 19b60fe56348a3e8f5f89d517b888bd4d83ef0a1 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Mon, 3 Apr 2023 16:22:21 -0700 Subject: [PATCH] Clarify audience value in Concierge-only auth doc, and other doc updates Also renamed a couple of integration test files to make their names more clear. --- .../docs/howto/configure-concierge-jwt.md | 93 ++++++++++++++++++- ...nfigure-supervisor-with-activedirectory.md | 2 +- ...configure-supervisor-with-jumpcloudldap.md | 2 +- .../configure-supervisor-with-openldap.md | 2 +- site/content/docs/howto/install-concierge.md | 5 + site/content/docs/howto/install-supervisor.md | 5 + ...hoami_test.go => concierge_whoami_test.go} | 2 +- ...oncierge_kubectl_test.go => smoke_test.go} | 2 +- 8 files changed, 103 insertions(+), 10 deletions(-) rename test/integration/{whoami_test.go => concierge_whoami_test.go} (99%) rename test/integration/{concierge_kubectl_test.go => smoke_test.go} (86%) diff --git a/site/content/docs/howto/configure-concierge-jwt.md b/site/content/docs/howto/configure-concierge-jwt.md index b502e5ca..ddd58dee 100644 --- a/site/content/docs/howto/configure-concierge-jwt.md +++ b/site/content/docs/howto/configure-concierge-jwt.md @@ -15,11 +15,12 @@ This guide shows you how to use this capability _without_ the Pinniped Superviso This is most useful if you have only a single cluster and want to authenticate to it via an existing OIDC provider. If you have multiple clusters, you may want to [install]({{< ref "install-supervisor" >}}) and [configure]({{< ref "configure-supervisor" >}}) the Pinniped Supervisor. -Then you can [configure the Concierge to use the Supervisor for authentication]({{< ref "configure-concierge-supervisor-jwt" >}}). +Then you can [configure the Concierge to use the Supervisor for authentication]({{< ref "configure-concierge-supervisor-jwt" >}}) +instead of following the guide below. ## Prerequisites -Before starting, you should have the [command-line tool installed]({{< ref "install-cli" >}}) locally and [Concierge running in your cluster]({{< ref "install-concierge" >}}). +Before starting, you should have the [Pinniped command-line tool installed]({{< ref "install-cli" >}}) locally and [Concierge running in your cluster]({{< ref "install-concierge" >}}). You should also have some existing OIDC issuer configuration: @@ -37,6 +38,7 @@ metadata: name: my-jwt-authenticator spec: issuer: https://my-issuer.example.com/any/path + # This audience value must be the same as your OIDC client's ID. audience: my-client-id claims: username: email @@ -60,6 +62,9 @@ pinniped get kubeconfig \ > my-cluster.yaml ``` +Note that the value for the `--oidc-client-id` flag must be your OIDC client's ID, which must also be the same +value declared as the `audience` in the JWTAuthenticator. + This creates a kubeconfig YAML file `my-cluster.yaml` that targets your JWTAuthenticator using `pinniped login oidc` as an [ExecCredential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins). It should look something like below: @@ -126,6 +131,82 @@ You should see: --user my-username@example.com ``` +## Including group membership + +If your OIDC provider supports adding user group memberships as a claim in the ID tokens, then you can +use Pinniped to transmit those group memberships into Kubernetes. + +For example, one popular OIDC provider can include group memberships in an ID token claim called `groups`, +if the client requests the scope called `groups` at authorization time. + +Unfortunately, each OIDC provider handles scopes a little differently, so please refer to your provider's documentation +to see if it is possible for the provider to add group membership information to the ID token. + +### Update the JWTAuthenticator + +Update the JWTAuthenticator to describe the name of the ID token claim where groups names will reside: + +```yaml +apiVersion: authentication.concierge.pinniped.dev/v1alpha1 +kind: JWTAuthenticator +metadata: + name: my-jwt-authenticator +spec: + issuer: https://my-issuer.example.com/any/path + audience: my-client-id + claims: + username: email + # Tell the JWTAuthenticator the name of the ID token claim + # where groups names will reside. For example, the name of + # the ID token claim is "groups", then set it as the value + # here. The name of this key is always "groups". + groups: groups +``` + +If you've saved this into a file `my-jwt-authenticator.yaml`, then update it into your cluster using: + +```sh +kubectl apply -f my-jwt-authenticator.yaml +``` + +### Generate an updated kubeconfig file + +Generate a kubeconfig file to target the updated JWTAuthenticator. Note that this is almost the same command +as before, but since our particular OIDC issuer requires that we also request the `groups` scope at +authorization time, then we add it to the list of scopes here. + +```sh +pinniped get kubeconfig \ + --oidc-client-id my-client-id \ + --oidc-scopes openid,email,groups \ + --oidc-listen-port 12345 \ + > my-cluster.yaml +``` + +### Use the kubeconfig file + +Use the kubeconfig with `kubectl` to access your cluster, as before: + +```sh +# Remove the client-side session cache, which is equivalent to +# performing a client-side logout. +rm -rf ~/.config/pinniped + +# Log in again by issuing a kubectl command. +kubectl --kubeconfig my-cluster.yaml get namespaces +``` + +To see the username and group membership as understood by the Kubernetes cluster, you can use +this command: + +```sh +pinniped whoami --kubeconfig my-cluster.yaml +``` + +If your groups configuration worked, then you should see your list of group names from your OIDC provider +included in the output. These group names may now be used with Kubernetes RBAC to provide authorization to +resources on the cluster. + ## Other notes - Pinniped kubeconfig files do not contain secrets and are safe to share between users. @@ -137,7 +218,9 @@ You should see: - If your OIDC provider supports [wildcard port number matching](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-16#section-2.1) for localhost URIs, you can omit the `--oidc-listen-port` flag to use a randomly chosen ephemeral TCP port. - The Pinniped command-line tool can only act as a public client with no client secret. - If your provider only supports non-public clients, consider using the Pinniped Supervisor. + If your provider only supports non-public clients, consider using the Pinniped Supervisor instead of following this guide. -- In general, it is not safe to use the same OIDC client across multiple clusters. - If you need to access multiple clusters, please [install the Pinniped Supervisor]({{< ref "install-supervisor" >}}). +- In general, it is not safe to use the same OIDC client across multiple clusters. Each cluster should use its own OIDC client + to ensure that tokens sent to one cluster cannot also be used for another cluster. + If you need to provide access to multiple clusters, please consider [installing the Pinniped Supervisor]({{< ref "install-supervisor" >}}) + instead of following this guide. diff --git a/site/content/docs/howto/configure-supervisor-with-activedirectory.md b/site/content/docs/howto/configure-supervisor-with-activedirectory.md index 37beadfc..68adcc02 100644 --- a/site/content/docs/howto/configure-supervisor-with-activedirectory.md +++ b/site/content/docs/howto/configure-supervisor-with-activedirectory.md @@ -104,7 +104,7 @@ spec: base: "OU=my-department,OU=Users,DC=activedirectory,DC=example,DC=com" # Specify how to filter the search to find the specific user by username. - # "{}" will be replaced # by the username that the end-user had typed + # "{}" will be replaced by the username that the end-user had typed # when they tried to log in. filter: "&(objectClass=person)(userPrincipalName={})" diff --git a/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md b/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md index 7faa2e7c..afd22e6d 100644 --- a/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md +++ b/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md @@ -71,7 +71,7 @@ spec: base: "ou=Users,o=YOUR_ORG_ID,dc=jumpcloud,dc=com" # Specify how to filter the search to find the specific user by username. - # "{}" will be replaced # by the username that the end-user had typed + # "{}" will be replaced by the username that the end-user had typed # when they tried to log in. filter: "&(objectClass=inetOrgPerson)(uid={})" diff --git a/site/content/docs/howto/configure-supervisor-with-openldap.md b/site/content/docs/howto/configure-supervisor-with-openldap.md index aafb635f..286c0ebe 100644 --- a/site/content/docs/howto/configure-supervisor-with-openldap.md +++ b/site/content/docs/howto/configure-supervisor-with-openldap.md @@ -219,7 +219,7 @@ spec: base: "ou=users,dc=pinniped,dc=dev" # Specify how to filter the search to find the specific user by username. - # "{}" will be replaced # by the username that the end-user had typed + # "{}" will be replaced by the username that the end-user had typed # when they tried to log in. filter: "&(objectClass=inetOrgPerson)(uid={})" diff --git a/site/content/docs/howto/install-concierge.md b/site/content/docs/howto/install-concierge.md index 570dd1d3..4fac95ef 100644 --- a/site/content/docs/howto/install-concierge.md +++ b/site/content/docs/howto/install-concierge.md @@ -90,6 +90,11 @@ Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/) - `ytt --file . --file site/dev-env.yaml | kapp deploy --app pinniped-concierge --file -` +## Other notes + +_Important:_ Configure Kubernetes authorization policies (i.e. RBAC) to prevent non-admin users from reading the +resources, especially the Secrets, in the Concierge's namespace. + ## Next steps Next, configure the Concierge for diff --git a/site/content/docs/howto/install-supervisor.md b/site/content/docs/howto/install-supervisor.md index d24ab6c9..15c38766 100644 --- a/site/content/docs/howto/install-supervisor.md +++ b/site/content/docs/howto/install-supervisor.md @@ -91,6 +91,11 @@ Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/) `ytt --file . --file site/dev-env.yaml | kapp deploy --app pinniped-supervisor --file -` +## Other notes + +_Important:_ Configure Kubernetes authorization policies (i.e. RBAC) to prevent non-admin users from reading the +resources, especially the Secrets, in the Supervisor's namespace. + ## Next steps Next, [configure the Supervisor as an OIDC issuer]({{< ref "configure-supervisor" >}})! diff --git a/test/integration/whoami_test.go b/test/integration/concierge_whoami_test.go similarity index 99% rename from test/integration/whoami_test.go rename to test/integration/concierge_whoami_test.go index d8eb7de5..7fb5a909 100644 --- a/test/integration/whoami_test.go +++ b/test/integration/concierge_whoami_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package integration diff --git a/test/integration/concierge_kubectl_test.go b/test/integration/smoke_test.go similarity index 86% rename from test/integration/concierge_kubectl_test.go rename to test/integration/smoke_test.go index a113c465..b9108a97 100644 --- a/test/integration/concierge_kubectl_test.go +++ b/test/integration/smoke_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package integration