diff --git a/site/content/docs/howto/configure-concierge-jwt.md b/site/content/docs/howto/configure-concierge-jwt.md index 2bd957ef..aa0d06d1 100644 --- a/site/content/docs/howto/configure-concierge-jwt.md +++ b/site/content/docs/howto/configure-concierge-jwt.md @@ -1,5 +1,5 @@ --- -title: Configure the Pinniped Concierge to validate JWT tokens +title: Configure the Pinniped Concierge to Validate JWT tokens description: Set up JSON Web Token (JWT) based token authentication on an individual Kubernetes cluster. cascade: layout: docs @@ -15,6 +15,7 @@ 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" >}}). ## Prerequisites @@ -121,7 +122,7 @@ You should see: ```sh kubectl create clusterrolebinding my-user-admin \ - --clusterrole admin \ + --clusterrole edit \ --user my-username@example.com ``` diff --git a/site/content/docs/howto/configure-concierge-supervisor-jwt.md b/site/content/docs/howto/configure-concierge-supervisor-jwt.md index b0886b2a..db52fab7 100644 --- a/site/content/docs/howto/configure-concierge-supervisor-jwt.md +++ b/site/content/docs/howto/configure-concierge-supervisor-jwt.md @@ -1,5 +1,5 @@ --- -title: Configure the Pinniped Concierge to validate JWT tokens issued by the Pinniped Supervisor +title: Configure the Pinniped Concierge to Validate JWT Tokens Issued by the Pinniped Supervisor description: Set up JSON Web Token (JWT) based token authentication on an individual Kubernetes cluster using the Pinniped Supervisor as the OIDC Provider. cascade: layout: docs @@ -26,6 +26,9 @@ If you would rather not use the Supervisor, you may want to [configure the Conci This how-to guide assumes that you have already [installed the Pinniped Supervisor]({{< ref "install-supervisor" >}}) with working ingress, and that you have [configured a FederationDomain to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). +It also assumes that you have configured an `OIDCIdentityProvider` or an `LDAPIdentityProvider` for the Supervisor as the source of your user's identities. +Various examples of configuring these resources can be found in these guides. + It also assumes that you have already [installed the Pinniped Concierge]({{< ref "install-concierge" >}}) on all the clusters in which you would like to allow users to have a unified identity. @@ -64,62 +67,6 @@ kubectl apply -f my-supervisor-authenticator.yaml Do this on each cluster in which you would like to allow users from that FederationDomain to log in. Don't forget to give each cluster a unique `audience` value for security reasons. -## Generate a kubeconfig file +## Next Steps -Generate a kubeconfig file for one of the clusters in which you installed and configured the Concierge as described above: - -```sh -pinniped get kubeconfig > my-cluster.yaml -``` - -This assumes that your current kubeconfig is an admin-level kubeconfig for the cluster, such as the kubeconfig -that you used to install the Concierge. - -This creates a kubeconfig YAML file `my-cluster.yaml`, unique to that cluster, which targets your JWTAuthenticator -using `pinniped login oidc` as an [ExecCredential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins). -This new kubeconfig can be shared with the other users of this cluster. It does not contain any specific -identity or credentials. When a user uses this new kubeconfig with `kubectl`, the Pinniped plugin will -prompt them to log in using their own identity. - -## Use the kubeconfig file - -Use the kubeconfig with `kubectl` to access your cluster: - -```sh -kubectl --kubeconfig my-cluster.yaml get namespaces -``` - -You should see: - -- The `pinniped login oidc` command is executed automatically by `kubectl`. - -- Pinniped directs you to login with whatever identity provider is configured in the Supervisor, either by opening - your browser (for upstream OIDC Providers) or by prompting for your username and password (for upstream LDAP providers). - -- In your shell, you see your clusters namespaces. - - If instead you get an access denied error, you may need to create a ClusterRoleBinding for username of your account - in the Supervisor's upstream identity provider, for example: - - ```sh - kubectl create clusterrolebinding my-user-admin \ - --clusterrole admin \ - --user my-username@example.com - ``` - - Alternatively, you could create role bindings based on the group membership of your users - in the upstream identity provider, for example: - - ```sh - kubectl create clusterrolebinding my-auditors \ - --clusterrole view \ - --group auditors - ``` - -## Other notes - -- Pinniped kubeconfig files do not contain secrets and are safe to share between users. - -- Temporary session credentials such as ID, access, and refresh tokens are stored in: - - `~/.config/pinniped/sessions.yaml` (macOS/Linux) - - `%USERPROFILE%/.config/pinniped/sessions.yaml` (Windows). +Next, [log in to your cluster]({{< ref "login" >}})! diff --git a/site/content/docs/howto/configure-concierge-webhook.md b/site/content/docs/howto/configure-concierge-webhook.md index 755255e5..d631998b 100644 --- a/site/content/docs/howto/configure-concierge-webhook.md +++ b/site/content/docs/howto/configure-concierge-webhook.md @@ -1,5 +1,5 @@ --- -title: Configure the Pinniped Concierge to validate webhook tokens +title: Configure the Pinniped Concierge to Validate Webhook Tokens description: Set up webhook-based token authentication on an individual Kubernetes cluster. cascade: layout: docs @@ -112,5 +112,5 @@ You should see: If instead you get an access denied error, you may need to create a ClusterRoleBinding for the username/groups returned by your webhook, for example: ```sh - kubectl create clusterrolebinding my-user-admin --clusterrole admin --user my-username + kubectl create clusterrolebinding my-user-admin --clusterrole edit --user my-username ``` diff --git a/site/content/docs/howto/configure-supervisor-with-gitlab.md b/site/content/docs/howto/configure-supervisor-with-gitlab.md index f65ceb66..483de669 100644 --- a/site/content/docs/howto/configure-supervisor-with-gitlab.md +++ b/site/content/docs/howto/configure-supervisor-with-gitlab.md @@ -138,4 +138,5 @@ spec: ## Next Steps -Now that you have configured the Supervisor to use GitLab, you will want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}}). +Next, [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}})! +Then you'll be able to log into those clusters as any of the users from the GitLab directory. diff --git a/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md b/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md index f1b06d6f..8931cd61 100644 --- a/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md +++ b/site/content/docs/howto/configure-supervisor-with-jumpcloudldap.md @@ -154,5 +154,5 @@ Look at the `status` field. If it was configured correctly, you should see `phas ## Next Steps -Now that you have configured the Supervisor to use JumpCloud LDAP, you will want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}}). +Next, [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}})! Then you'll be able to log into those clusters as any of the users from the JumpCloud directory. diff --git a/site/content/docs/howto/configure-supervisor-with-okta.md b/site/content/docs/howto/configure-supervisor-with-okta.md index ab553e23..d7e9257a 100644 --- a/site/content/docs/howto/configure-supervisor-with-okta.md +++ b/site/content/docs/howto/configure-supervisor-with-okta.md @@ -108,4 +108,5 @@ Look at the `status` field. If it was configured correctly, you should see `phas ## Next steps -Now that you have configured the Supervisor to use Okta, you will want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}}). +Next, [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}})! +Then you'll be able to log into those clusters as any of the users from the Okta directory. diff --git a/site/content/docs/howto/configure-supervisor-with-openldap.md b/site/content/docs/howto/configure-supervisor-with-openldap.md index 17ae70f0..3c4ec145 100644 --- a/site/content/docs/howto/configure-supervisor-with-openldap.md +++ b/site/content/docs/howto/configure-supervisor-with-openldap.md @@ -294,5 +294,5 @@ Look at the `status` field. If it was configured correctly, you should see `phas ## Next Steps -Now that you have configured the Supervisor to use OpenLDAP, you will want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}}). +Next, [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}})! Then you'll be able to log into those clusters as any of the users from the OpenLDAP directory. diff --git a/site/content/docs/howto/configure-supervisor.md b/site/content/docs/howto/configure-supervisor.md index bc0ab594..f27cb3ab 100644 --- a/site/content/docs/howto/configure-supervisor.md +++ b/site/content/docs/howto/configure-supervisor.md @@ -163,3 +163,9 @@ You can create the certificate Secrets however you like, for example you could u or `kubectl create secret tls`. Keep in mind that your users must load some of these endpoints in their web browsers, so the TLS certificates should be signed by a certificate authority that is trusted by their browsers. + +## Next Steps + +Next, configure an `OIDCIdentityProvider` or an `LDAPIdentityProvider` for the Supervisor (several examples are available in these guides), +and [configure the Concierge to use the Supervisor for authentication]({{< ref "configure-concierge-supervisor-jwt" >}}) +on each cluster! diff --git a/site/content/docs/howto/install-cli.md b/site/content/docs/howto/install-cli.md index 7e5ddd21..c18e89a9 100644 --- a/site/content/docs/howto/install-cli.md +++ b/site/content/docs/howto/install-cli.md @@ -36,7 +36,7 @@ To find specific versions or view all available platforms and architectures, vis ### Gatekeeper -If you are using macOS, you may get an error dialog when you first run `pinniped` that says `“pinniped” cannot be opened because the developer cannotbe verified`. +If you are using macOS, you may get an error dialog when you first run `pinniped` that says `“pinniped” cannot be opened because the developer cannot be verified`. Cancel this dialog, open System Preferences, click Security & Privacy, and click the Allow Anyway button next to the Pinniped message. Run the command again and another dialog appears saying `macOS cannot verify the developer of “pinniped”. Are you sure you want to open it?`. @@ -44,6 +44,8 @@ Click Open to allow the command to proceed. ## Install a specific version via script +Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number and use it to replace the version number in the URL below. + For example, to install v0.9.2 on Linux/amd64: ```sh @@ -52,4 +54,8 @@ curl -Lso pinniped https://get.pinniped.dev/v0.9.2/pinniped-cli-linux-amd64 \ && sudo mv pinniped /usr/local/bin/pinniped ``` -*Next, [install the Concierge]({{< ref "install-concierge.md" >}})!* +*Replace v0.9.2 with your preferred version number.* + +## Next Steps + +Next, [install the Supervisor]({{< ref "install-supervisor.md" >}}) and/or [install the Concierge]({{< ref "install-concierge.md" >}})! diff --git a/site/content/docs/howto/install-concierge.md b/site/content/docs/howto/install-concierge.md index 582e2c18..13ec2c54 100644 --- a/site/content/docs/howto/install-concierge.md +++ b/site/content/docs/howto/install-concierge.md @@ -68,4 +68,8 @@ Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/) `ytt --file . | kapp deploy --yes --app pinniped-concierge --diff-changes --file -` -*Next, configure the Concierge for [JWT]({{< ref "configure-concierge-jwt.md" >}}) or [webhook]({{< ref "configure-concierge-webhook.md" >}}) authentication.* +## Next Steps + +Next, configure the Concierge for +[JWT]({{< ref "configure-concierge-jwt.md" >}}) or [webhook]({{< ref "configure-concierge-webhook.md" >}}) authentication, +or [configure the Concierge to use the Supervisor for authentication]({{< ref "configure-concierge-supervisor-jwt" >}}). diff --git a/site/content/docs/howto/install-supervisor.md b/site/content/docs/howto/install-supervisor.md index 796648f1..27de74fc 100644 --- a/site/content/docs/howto/install-supervisor.md +++ b/site/content/docs/howto/install-supervisor.md @@ -69,4 +69,4 @@ Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/) ## Next Steps -Now that you have installed the Supervisor, you will want to [configure the Supervisor]({{< ref "configure-supervisor" >}}). +Next, [configure the Supervisor as an OIDC issuer]({{< ref "configure-supervisor" >}})! diff --git a/site/content/docs/howto/login.md b/site/content/docs/howto/login.md new file mode 100644 index 00000000..8487b370 --- /dev/null +++ b/site/content/docs/howto/login.md @@ -0,0 +1,138 @@ +--- +title: Logging into your Cluster using Pinniped +description: Logging into your Kubernetes Cluster using Pinniped for Authentication. +cascade: + layout: docs +menu: + docs: + name: Log in to a Cluster + weight: 500 + parent: howtos +--- + +## Prerequisites + +This how-to guide assumes that you have already configured the following Pinniped server-side components within your Kubernetes cluster(s): + +1. If you would like to use the Pinniped Supervisor for federated authentication across multiple Kubernetes clusters + then you have already: + 1. [Installed the Pinniped Supervisor]({{< ref "install-supervisor" >}}) with working ingress. + 1. [Configured a FederationDomain to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). + 1. Configured an `OIDCIdentityProvider` or an `LDAPIdentityProvider` for the Supervisor as the source of your user's identities. + Various examples of configuring these resources can be found in these guides. +1. In each cluster for which you would like to use Pinniped for authentication, you have [installed the Concierge]({{< ref "install-concierge" >}}). +1. In each cluster's Concierge, you have configured an authenticator. For example, if you are using the Pinniped Supervisor, + then you have configured each Concierge to [use the Supervisor for authentication]({{< ref "configure-concierge-supervisor-jwt" >}}). + +You should have also already [installed the `pinniped` command-line]({{< ref "install-cli" >}}) client, which is used to generate Pinniped-compatible kubeconfig files, and is also a `kubectl` plugin to enable the Pinniped-based login flow. + +## Overview + +1. A cluster admin uses Pinniped to generate a kubeconfig for each cluster, and shares the kubeconfig for each cluster with all users of that cluster. +1. A cluster user uses `kubectl` with the generated kubeconfig given to them by the cluster admin. `kubectl` interactively prompts the user to log in using their own unique identity. + +## Key Advantages of Using the Pinniped Supervisor + +Although you can choose to use Pinniped without using the Pinniped Supervisor, there are several key advantages of choosing to use the Pinniped Supervisor to manage identity across fleets of Kubernetes clusters. + +1. A generated kubeconfig for a cluster will be specific for that cluster, however **it will not contain any specific user identity or credentials. + This kubeconfig file can be safely shared with all cluster users.** When the user runs `kubectl` commands using this kubeconfig, they will be interactively prompted to log in using their own unique identity from the OIDC or LDAP identity provider configured in the Supervisor. + +1. The Supervisor will provide a federated identity across all clusters that use the same `FederationDomain`. + The user will be **prompted by `kubectl` to interactively authenticate once per day**, and then will be able to use all clusters + from the same `FederationDomain` for the rest of the day without being asked to authenticate again. + This federated identity is secure because behind the scenes the Supervisor is issuing very short-lived credentials + that are uniquely scoped to each cluster. + +1. The Supervisor makes it easy to **bring your own OIDC or LDAP identity provider to act as the source of user identities**. + It also allows you to configure how identities and group memberships in the OIDC or LDAP identity provider map to identities + and group memberships in the Kubernetes clusters. + +## Generate a Pinniped-Compatible kubeconfig File + +You will need to generate a Pinniped-compatible kubeconfig file for each cluster in which you have installed the Concierge. +This requires admin-level access to each cluster, so this would typically be performed by the same user who installed the Concierge. + +For each cluster, use `pinniped get kubeconfig` to generate the new kubeconfig file for that cluster. + +It is typically sufficient to run this command with no arguments, aside from pointing the command at your admin kubeconfig. +The command uses the [same rules](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) +as `kubectl` to find your admin kubeconfig: + +> "By default, `kubectl` looks for a file named config in the `$HOME/.kube` directory. You can specify other kubeconfig files by setting the `KUBECONFIG` environment variable or by setting the `--kubeconfig` flag." + +For example, if your admin `kubeconfig` file were at the path `$HOME/admin-kubeconfig.yaml`, then you could use: + +```sh +pinniped get kubeconfig \ + --kubeconfig "$HOME/admin-kubeconfig.yaml" > pinniped-kubeconfig.yaml +``` + +The new Pinniped-compatible kubeconfig YAML will be output as stdout, and can be redirected to a file. + +Various default behaviors of `pinniped get kubeconfig` can be overridden using [its command-line options]({{< ref "cli" >}}). + +## Use the Generated kubeconfig with `kubectl` to Access the Cluster + +A cluster user will typically be given a Pinniped-compatible kubeconfig by their cluster admin. They can use this kubeconfig +with `kubectl` just like any other kubeconfig, as long as they have also installed the `pinniped` CLI tool at the +same absolute path where it is referenced inside the kubeconfig's YAML. The `pinniped` CLI will act as a `kubectl` plugin +to manage the user's authentication to the cluster. + +For example, if the kubeconfig were saved at `$HOME/pinniped-kubeconfig.yaml`: + +```bash +kubectl get namespaces \ + --kubeconfig "$HOME/pinniped-kubeconfig.yaml" +``` + +This command, when configured to use the Pinniped-compatible kubeconfig, will invoke the `pinniped` CLI behind the scenes +as an [ExecCredential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins) +to authenticate the user to the cluster. + +If the Pinniped Supervisor is used for authentication to that cluster, then the user's authentication experience +will depend on which type of identity provider was configured. + +- For an OIDC identity provider, `kubectl` will open the user's web browser and direct it to the login page of + their OIDC Provider. This login flow is controlled by the provider, so it may include two-factor authentication or + other features provided by the OIDC Provider. + + If the user's browser is not available, then `kubectl` will instead print a URL which can be visited in a + browser (potentially on a different computer) to complete the authentication. + +- For an LDAP identity provider, `kubectl` will interactively prompt the user for their username and password at the CLI. + + Alternatively, the user can set the environment variables `PINNIPED_USERNAME` and `PINNIPED_PASSWORD` for the + `kubectl` process to avoid the interactive prompts. + +Once the user completes authentication, the `kubectl` command will automatically continue and complete the user's requested command. +For the example above, `kubectl` would list the cluster's namespaces. + +## Authorization + +Pinniped provides authentication (usernames and group memberships) but not authorization. Kubernetes authorization is often +provided by the [Kubernetes RBAC system](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) on each cluster. + +In the example above, if the user gets an access denied error, then they may need authorization to list namespaces. +For example, an admin could grant the user "edit" access to all cluster resources via the user's username: + + ```sh + kubectl create clusterrolebinding my-user-can-edit \ + --clusterrole edit \ + --user my-username@example.com + ``` + +Alternatively, an admin could create role bindings based on the group membership of the users +in the upstream identity provider, for example: + + ```sh + kubectl create clusterrolebinding my-auditors \ + --clusterrole view \ + --group auditors + ``` + +## Other notes + +- Temporary session credentials such as ID, access, and refresh tokens are stored in: + - `~/.config/pinniped/sessions.yaml` (macOS/Linux) + - `%USERPROFILE%/.config/pinniped/sessions.yaml` (Windows).