From ef7c7d879b2a56b415335ee667edeb01b70e32e7 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 19 Jun 2024 10:50:02 -0700 Subject: [PATCH] add local demo tutorial to site --- site/content/docs/_index.md | 4 +- .../concierge-and-supervisor-demo.md | 8 +- .../local-concierge-and-supervisor-demo.md | 682 ++++++++++++++++++ 3 files changed, 691 insertions(+), 3 deletions(-) create mode 100644 site/content/docs/tutorials/local-concierge-and-supervisor-demo.md diff --git a/site/content/docs/_index.md b/site/content/docs/_index.md index 55742a8e8..c2f538a67 100644 --- a/site/content/docs/_index.md +++ b/site/content/docs/_index.md @@ -19,7 +19,9 @@ or [join the Pinniped community]({{< ref "/community" >}}). ## New to Pinniped? -- ⚠️ **Start here:** [Learn to use Pinniped for federated authentication to Kubernetes clusters]({{< ref "tutorials/concierge-and-supervisor-demo" >}}) +- ⚠️ **Start here:** + - [Learn to use Pinniped for federated authentication to Kubernetes clusters in a production-like environment]({{< ref "tutorials/concierge-and-supervisor-demo" >}}) + - Or, [try Pinniped on your local computer in a demo-like environment]({{< ref "tutorials/local-concierge-and-supervisor-demo" >}}) ## Background diff --git a/site/content/docs/tutorials/concierge-and-supervisor-demo.md b/site/content/docs/tutorials/concierge-and-supervisor-demo.md index e2056216e..53e12e84c 100644 --- a/site/content/docs/tutorials/concierge-and-supervisor-demo.md +++ b/site/content/docs/tutorials/concierge-and-supervisor-demo.md @@ -15,7 +15,7 @@ menu: There are many benefits to using the Pinniped Supervisor, Concierge, and CLI components together to provide Kubernetes authentication. -- It's easy to **bring your own OIDC, LDAP, or Active Directory identity provider** to act as the source of user identities. +- It's easy to **bring your own OIDC, LDAP, GitHub, or Active Directory identity provider** to act as the source of user identities. A user's identity in the external identity provider becomes their identity in Kubernetes. All other aspects of Kubernetes that are sensitive to identity, such as authorization policies and audit logging, are then based on the user identities from your identity provider. @@ -51,6 +51,10 @@ to provide Kubernetes authentication. ## What this tutorial will show +⚠️ This tutorial will use several Kubernetes clusters running in a cloud provider account in a production-like setup. +If you prefer to try Pinniped entirely on your own computer in a demo-like setup, please instead see the tutorial +[Concierge with Supervisor: a complete example of every step, demonstrated using a local Kind cluster]({{< ref "local-concierge-and-supervisor-demo" >}}). + This tutorial will show: - A detailed example of how to install and configure a Supervisor with ingress, DNS, TLS, and an external identity provider - How to install the Concierge onto multiple workload clusters and configure them all to trust identities from the Supervisor @@ -78,7 +82,7 @@ There are many ways to install and configure Pinniped. To make the steps of this had to make some choices. The choices made for this tutorial were: - The Pinniped Supervisor can draw user identities from OIDC identity providers, Active Directory providers (via LDAP), - and generic LDAP providers. In this tutorial we will use Okta as an OIDC identity provider. + generic LDAP providers, and GitHub. In this tutorial we will use Okta as an OIDC identity provider. Okta offers a free developer account, so any reader should be able to sign up for an Okta account if they would like to try these steps themselves. - The Pinniped Supervisor can be installed on any type of Kubernetes cluster. In this tutorial we will diff --git a/site/content/docs/tutorials/local-concierge-and-supervisor-demo.md b/site/content/docs/tutorials/local-concierge-and-supervisor-demo.md new file mode 100644 index 000000000..cea454c4f --- /dev/null +++ b/site/content/docs/tutorials/local-concierge-and-supervisor-demo.md @@ -0,0 +1,682 @@ +--- +title: "Learn to use Pinniped for federated authentication to Kubernetes clusters - running the whole demo on your local computer" +description: See how the Pinniped Supervisor streamlines login to multiple Kubernetes clusters. +cascade: + layout: docs +menu: + docs: + name: Concierge with Supervisor Locally + parent: tutorials + weight: 1 +--- + +## Why Pinniped? + +There are many benefits to using the Pinniped Supervisor, Concierge, and CLI components together +to provide Kubernetes authentication. + +- It's easy to **bring your own OIDC, LDAP, GitHub, or Active Directory identity provider** to act as the source of user identities. + A user's identity in the external identity provider becomes their identity in Kubernetes. + All other aspects of Kubernetes that are sensitive to identity, such as authorization policies and audit logging, are then + based on the user identities from your identity provider. + +- You can **bring identities from your own identity provider into many types of Kubernetes clusters in a consistent way**. + This includes clusters from various vendors run on-prem, and clusters provided as a cloud service by various popular cloud companies. + +- Kubeconfig files **will not contain any specific user identity or credentials, so they can be safely shared**. + +- Deep integration with `kubectl` means that when a user runs `kubectl` commands, + they will be **interactively prompted to log in using their own unique identity** from your identity provider. + +- Users will be prompted by `kubectl` to interactively **authenticate only once per day**, and then will be able to + use multiple clusters for the rest of the day without being asked to authenticate again. + +- All credentials are short-lived, and refreshed often. Additionally, **frequent checks are made against your identity provider + to ensure that the user should continue to have access to the Kubernetes clusters**. For example, within minutes + of locking an Active Directory account, that user will lose access to Kubernetes clusters, even if they were + already logged in. + +- A **user can safely be granted high levels of authorization on a cluster**, if needed. + Even if they abuse their privilege by capturing the credentials sent by other users to the cluster, + they will not be able to use the captured credentials to access other clusters, because all credentials + sent to clusters are uniquely scoped to each individual cluster. + +- Pinniped will not interfere with a cluster's original vendor-specific authentication system. + The **original admin-level kubeconfig from a cluster can be privately kept by the cluster's creator** for + bootstrapping and break-glass access purposes. + +- Pinniped is **open source** and will never be tied to any one vendor's authentication system. + As Pinniped improves in the future, all your Kubernetes clusters can benefit, regardless of which vendor provided the clusters. + The code is available on GitHub for any expert to audit, and for any community member to contribute. + +## What this tutorial will show + +⚠️ This tutorial will use a Kind cluster running locally on your own computer. +This is a good way to try Pinniped for the first time, or demo Pinniped, but is not an example of how to use Pinniped for production systems. +If you prefer to try Pinniped in a more production-style setup using clusters hosted by a cloud provider, please instead see the tutorial +[Concierge with Supervisor: a complete example of every step, demonstrated using GKE clusters]({{< ref "concierge-and-supervisor-demo" >}}). + +This tutorial will show: +- A detailed example of how to install and configure a Supervisor on a local Kind cluster with ingress, TLS, and an external identity provider for demo purposes +- How to install the Concierge onto the local Kind cluster and configure it to trust identities from the Supervisor +- How an admin can create and distribute kubeconfig files +- How a developer or devops user can authenticate with kubectl using their identity from the external identity provider, + and how they can securely access clusters for the rest of the day without needing to authenticate again + +## Tutorial background + +This tutorial is intended to be a step-by-step example of installing and configuring the Pinniped components +on your own computer. It will show every +command needed to replicate the same setup to allow the reader to follow the same steps themselves. +To see how Pinniped can provide a multi-cluster federated authentication solution, please the other tutorial. + +A single Pinniped Supervisor can provide authentication for any number of Kubernetes clusters. In a typical deployment: + +- A single Supervisor is deployed on a special cluster where app developers and devops users have no access. + App developers and devops users should have no access at least to the resources in the Supervisor's namespace, + but usually have no access to the whole cluster. + For this tutorial, we will simplify the setup by installing all components onto a single cluster. +- App developers and devops users can then use their identities provided by the Supervisor to log in to many + clusters where they can manage their apps. + The Pinniped Concierge component is installed into each workload cluster and is configured to trust the single Supervisor. + The Concierge acts as an in-cluster agent to provide authentication services. + For this tutorial, we will simplify the setup by installing all components onto a single cluster. + +There are many ways to install and configure Pinniped. To make the steps of this tutorial as specific as possible, we +had to make some choices. The choices made for this tutorial were: + +- The Pinniped Supervisor can draw user identities from OIDC identity providers, Active Directory providers (via LDAP), + generic LDAP providers, and GitHub. In this tutorial we will use GitHub user identities. +- The Pinniped Supervisor can be installed on any type of Kubernetes cluster. In this tutorial we will + demonstrate the installation process on a Kind cluster to allow this demo to run on your local machine. +- The Pinniped Supervisor needs working ingress. There are many ways to configure ingress for apps running on + Kubernetes clusters, as described in the [howto guide for installing the Supervisor]({{< ref "../howto/install-supervisor" >}}). + For this tutorial we will use a [Contour](https://projectcontour.io) to provide ingress. + This is a simple setup for local demos which also allows us to terminate TLS inside the Supervisor app. +- Although it is possible to configure the Supervisor's FederationDomain to use an IP address, it is better to + use a DNS name. There are many ways to manage DNS. For this tutorial, we will use your local computer's `/etc/hosts` + file to create a hostname that will be recognized only by your computer. This should work on both MacOS and Linux computers. + Making this work on Windows computers will not be specifically documented here, but it should be possible. +- For web-based login flows as used by some identity provider types, the Pinniped Supervisor needs TLS certificates + that are trusted by the end users' web browsers. There are many ways to create TLS certificates. + There are also several ways to configure the TLS certificates on the Supervisor, as described in the + [docs for configuring the Supervisor]({{< ref "../howto/supervisor/configure-supervisor" >}}). + For this tutorial we will create a self-signed certificate authority. This will mean that we will need to navigate + through some certificate warnings in our web browser, but this is the easiest setup for a local demo. +- The Pinniped Concierge can be installed in many types of Kubernetes clusters, as described in + [supported Kubernetes clusters]({{< ref "../reference/supported-clusters" >}}). In this tutorial we will + install it into the same Kind cluster to keep things simple. In general, it can be installed into many clusters + to provide single sign-on authentication to fleets of clusters. +- Pinniped provides authentication, not authorization. Inside Kubernetes, a user authenticated via Pinniped will have a username + and may also have a list of group names. These usernames and group names can be used to create authorization policies using any + Kubernetes authorization system, usually using [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac). + +The details of the steps shown in this tutorial would be different if any of the above choices were made differently, +however the general concepts at each step would still apply. + +## Ready? Let's go! + +### Install the Pinniped CLI + +If you have not already done so, [install the Pinniped command-line tool]({{< ref "../howto/install-cli" >}}). + +On macOS or Linux, you can do this using Homebrew: + +```sh +brew install vmware-tanzu/pinniped/pinniped-cli +``` + +On other platforms, see the [command-line installation guide]({{< ref "../howto/install-cli" >}}) for more details. + +### Install Other Dependencies + +- If you have not already done so, [install Docker](https://docs.docker.com/get-docker/). Kind requires Docker. +- If you have not already done so, [install Kind](https://kind.sigs.k8s.io/docs/user/quick-start). + On macOS or Linux, you can do this using Homebrew: + + ```sh + brew install kind + ``` + +### Create a Kind cluster + +Create a Kind config file which exposes a port that we can use for networking ingress. Then use it to create a cluster. + +```sh +cat < /tmp/kind-config.yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + extraPortMappings: + - protocol: TCP + containerPort: 443 + hostPort: 443 + listenAddress: 127.0.0.1 +EOF + +kind create cluster --config /tmp/kind-config.yaml +``` + +Note that this will update your global kubeconfig and set your current context. Future `kubectl` commands will +target this local Kind cluster by default and will have admin access to the cluster. + +### Install the Pinniped Supervisor on the cluster + +There are several installation options described in the +[howto guide for installing the Supervisor]({{< ref "../howto/install-supervisor" >}}). +For this tutorial, we will install the latest version using the `kubectl` CLI. + +```sh +kubectl apply \ + -f https://get.pinniped.dev/{{< latestversion >}}/install-pinniped-supervisor.yaml +``` + +### Expose the Supervisor's Endpoints + +There are several options for exposing the Supervisor's endpoints outside the cluster, which are described in the +[howto guide for configuring the Supervisor]({{< ref "../howto/supervisor/configure-supervisor" >}}). For this tutorial, +we will use a ClusterIP Service to expose the Supervisor inside the cluster, and then use +[Contour](https://projectcontour.io) to expose that Service outside the cluster. + +Create a ClusterIP Service to expose the Supervisor's endpoints within the cluster. + +```sh +cat <> /etc/hosts" +``` + +Note that you can remove this line from your `/etc/hosts` file after you are finished with this tutorial. + +### Install and configure cert-manager + +The Supervisor needs TLS serving certificates. You can create these with `openssl` or any other tool that you prefer. +For this demo, let's use [cert-manager](https://cert-manager.io). + +Install cert-manager. + +```sh +kubectl apply -f \ + https://github.com/jetstack/cert-manager/releases/download/v1.15.0/cert-manager.yaml +``` + +Ask cert-manager to create a certificate authority and use that CA to issue a TLS serving certificate as a Secret. +Sorry, cert-manager requires a lot of YAML, but you can just copy/paste it. + +```sh +cat < /tmp/supervisor-ca.crt +``` + +### Configure an Identity Provider in the Pinniped Supervisor + +For this tutorial, we will use GitHub as an identity provider. +If you'd rather try another identity provider type, the steps would be roughly the same. +See the Pinniped documentation for [other supported identity provider types]({{< ref "../howto/supervisor" >}}). + +You will need to give the Supervisor permission to help you log in to GitHub. Pinniped will redirect you to +github.com in your web browser for login. Pinniped will never see your GitHub credentials. It will only be able to read +your basic profile information (e.g. your username) and some information about your organization and team memberships. + +1. Log in to GitHub. If you do not have a GitHub account, you can sign up for free. +2. Click on your profile icon in the top-right corner, and choose + Settings -> Developer Settings -> OAuth Apps -> New OAuth App. Fill out the form: + - Application Name: `Pinniped demo`, or any other name that you prefer. + - Homepage URL: `https://pinniped.dev`, or any other URL that you prefer. + - Authorization callback URL: `https://pinniped-supervisor.pinniped-supervisor.svc.cluster.local/demo-issuer/callback`. + You must use exactly this value for this tutorial. + - Enable device flow: leave this box unchecked +2. Click "Register Application" +3. Click "Generate New Client Secret" +4. Copy the client secret for use in the next step. It will not be shown to you again. +5. Also copy the client ID for use in the next step. + +```sh +# Set the client ID and client secret as env vars for use in the next step. +export GITHUB_APP_CLIENT_ID= +export GITHUB_APP_CLIENT_SECRET= +``` + +Configure the identity provider. + +```sh +cat <}}). + +### Configure a FederationDomain in the Pinniped Supervisor + +The Supervisor should be configured to have a [FederationDomain](https://github.com/vmware-tanzu/pinniped/blob/main/generated/latest/README.adoc#federationdomain), which, under the hood: +- Acts as an OIDC provider to the Pinniped CLI, creating a consistent interface for the CLI to use regardless + of which protocol the Supervisor is using to talk to the external identity provider +- Also acts as an OIDC provider to the workload cluster's Concierge component, which will receive JWT tokens + from the CLI and cryptographically validate that they were issued by the Supervisor + +Create the FederationDomain. + +```sh +cat <}}). +For this tutorial, we will install the latest version using the `kubectl` CLI. + +The Concierge can be installed on many clusters, and each can be configured to trust a single Pinniped Supervisor +to provide authentication services. +For this demo, we will install it on the same Kind cluster to keep things simple. + +```sh +kubectl apply -f \ + "https://get.pinniped.dev/{{< latestversion >}}/install-pinniped-concierge-crds.yaml" + +kubectl apply -f \ + "https://get.pinniped.dev/{{< latestversion >}}/install-pinniped-concierge-resources.yaml" +``` + +Configure the Concierge to trust the Supervisor's +FederationDomain for authentication by creating a +[JWTAuthenticator](https://github.com/vmware-tanzu/pinniped/blob/main/generated/latest/README.adoc#jwtauthenticator). + +```sh +cat < /tmp/developer.yaml +``` + +In this tutorial we only have one cluster, but in general you can have many workload clusters. +Each cluster will have its own kubeconfig. + +These new kubeconfig files may be distributed to the app developers and devops users who +will be using these workload clusters. They do not contain any particular identity or credential. + +As the cluster creator, do not share the admin kubeconfig files with your workload cluster users. +If this were a production cluster, you would save the admin kubeconfig files somewhere private and secure for your own future use. + +See the [full documentation for the `pinniped get kubeconfig` command]({{< ref "../reference/cli" >}}) +for other available optional parameters. + +### As a developer or devops user, access the workload clusters by using regular kubectl commands + +A developer or devops user who would like to use the workload clusters may do so using kubectl with +the kubeconfig files provided to them by the cluster admin in the previous step. + +The kubeconfig files tell kubectl how to invoke the Pinniped CLI as a plugin to aid in authentication. +First, the user will need to install the Pinniped CLI at the same full path where it is referenced +inside the kubeconfig file. Or, they can adjust the full path to the Pinniped CLI inside +their own copy of the kubeconfig file, to make it match where they have locally installed the Pinniped CLI. + +Then the developer can run any kubectl command using a kubeconfig file +that was provided to them by the cluster admin. For example, let's run a command against the first workload cluster. + +```sh +kubectl get namespaces --kubeconfig /tmp/developer.yaml +``` + +The first time this command is run, it will open their default web browser and redirect them to GitHub for login. +Because we are using a self-signed CA for the Supervisor in this tutorial, +you will need to click through a web browser certificate warning for the host `pinniped-supervisor.pinniped-supervisor.svc.cluster.local`. +The first time each user is prompted to log in to GitHub, it will ask if you want to authorize the application +to read your profile and org/team membership, and you must click "Authorize". + +After successfully logging in to GitHub, for example as the user `cfryanr`, the kubectl command will +continue and will try to list the namespaces. +The user's identity in Kubernetes (username and group memberships) came from GitHub, through Pinniped. + +Oops! This results in an RBAC error similar to +`Error from server (Forbidden): namespaces is forbidden: User "cfryanr" cannot list resource "namespaces" in API group "" at the cluster scope`. +Recall that the user only has RBAC permissions in the `dev` namespace. +Let's try again, but this time we will list something in the `dev` namespace. + +```sh +kubectl get serviceaccounts --namespace dev --kubeconfig /tmp/developer.yaml +``` + +This will successfully list the default service account in the `dev` namespace. +Note that you did not need to log in via GitHub again because you have an active session with Pinniped. + +If you had multiple workload clusters, you could switch developer kubeconfigs to run kubectl commands against other clusters. +Even though you are accessing a different cluster, the web browser will not open again. +You do not need to interactively sign in again for the rest of the day to access +any workload cluster within the same FederationDomain. +Behind the scenes, Pinniped is performing token refreshes and token exchanges +on behalf of the user to create a short-lived, cluster-scoped token to access +this new workload cluster using the same identity from GitHub. + +Note that users can use any of kubectl's supported means of providing kubeconfig information to kubectl. +They are not limited to only using the `--kubeconfig` flag. For example, they could set the `KUBECONFIG` +environment variable instead. + +For more information about logging in to workload clusters, see the [howto doc about login]({{< ref "../howto/login" >}}). + +### Whoami + +Not sure what identity you're using on the cluster? Pinniped has a convenient feature to help out with that. + +```sh +pinniped whoami --kubeconfig /tmp/developer.yaml +``` + +The output will include your username and group names, and will look similar to the following output. + +```sh +Current cluster info: + +Name: kind-kind-pinniped +URL: https://127.0.0.1:49688 + +Current user info: + +Username: cfryanr +Groups: my-github-org/my-team1, my-github-org/my-team2, system:authenticated +``` + +If you do not see the GitHub teams that you expected to be reflected as Kubernetes groups, +then the owner of your GitHub organization may need to allow your GitHub OAuth App to be used with that organization. +See the +[Configure Supervisor With GitHub howto doc]({{< ref "../howto/supervisor/configure-supervisor-with-github" >}}) +for more information. + +## What we've learned + +This tutorial showed: +- A detailed example of how to install and configure a Supervisor on a local Kind cluster with ingress, DNS, TLS, and an external identity provider +- How to install the Concierge onto a local Kind cluster clusters and configure it to trust identities from the Supervisor +- How an admin can create and distribute kubeconfig files for the workload clusters +- How a developer or devops user can authenticate with kubectl using their identity from the external identity provider, + and how they can securely access all workload clusters for the rest of the day without needing to authenticate again + +## Removing the resources created in this tutorial + +If you would like to delete the resources created in this tutorial, you can use the following commands. + +- Delete the kind cluster using `kind delete cluster`. +- Edit your `/etc/hosts` file to remove the line that you added in the step above. +- Delete the OAuth App that you created in your GitHub profile's Developer Settings on github.com.