Pinniped Logo

Pinniped Documentation

Learn to use the Pinniped Concierge

Overview

This tutorial shows how to use the Pinniped Concierge on Kubernetes clusters. If you would like to learn how to use the Pinniped Supervisor and Concierge together to provided federated identity with a single sign-on user experience to many Kubernetes clusters, please instead see this other tutorial:

Installing and trying the Pinniped Concierge on any cluster consists of the following general steps. See the next section below for a more specific example of installing onto a local kind cluster, including the exact commands to use for that case.

  1. Install the Concierge.
  2. Install the Pinniped command-line tool.
  3. Configure the Concierge with a JWT or webhook authenticator.
  4. Generate a kubeconfig using the Pinniped command-line tool (run pinniped get kubeconfig --help for more information).
  5. Run kubectl commands using the generated kubeconfig. The Pinniped Concierge will automatically be used for authentication during those commands.

Please be aware that using the Concierge without the Supervisor is an advanced use case, not the typical use case. For example, the Supervisor issues cluster-scoped credentials that cannot be replayed against other clusters, so using the Concierge without the Supervisor removes that protection. You might have designed another system to provide that protection, but if not then please carefully consider the security implications.

Prerequisites

  1. A Kubernetes cluster of a type supported by Pinniped as described in architecture.

    Don’t have a cluster handy? Consider using kind on your local machine. See below for an example of using kind.

  2. An authenticator of a type supported by Pinniped as described in architecture.

    Don’t have an authenticator of a type supported by Pinniped handy? No problem, there is a demo authenticator available. Start by installing local-user-authenticator on the same cluster where you would like to try Pinniped by following the directions in deploy/local-user-authenticator/README.md. See below for an example of deploying this on kind.

  3. A kubeconfig where the current context points to the cluster and has administrator-like privileges on that cluster.

Example of deploying on kind

kind is a tool for creating and managing Kubernetes clusters on your local machine which uses Docker containers as the cluster’s nodes. This is a convenient way to try out Pinniped on a local non-production cluster.

The following steps deploy the latest release of Pinniped on kind using the local-user-authenticator component as the authenticator.

  1. Install the tools required for the following steps.

    • Install kind, if not already installed. For example, brew install kind on macOS.

    • kind depends on Docker. If not already installed, install Docker, for example brew cask install docker on macOS.

    • This demo requires kubectl, which comes with Docker, or can be installed separately.

    • This demo requires a tool capable of generating a bcrypt hash to interact with the webhook. The example below uses htpasswd, which is installed on most macOS systems, and can be installed on some Linux systems via the apache2-utils package (for example, apt-get install apache2-utils).

  2. Create a new Kubernetes cluster using kind create cluster. Optionally provide a cluster name using the --name flag. kind automatically updates your kubeconfig to point to the new cluster as a user with administrator-like permissions.

  3. Deploy the local-user-authenticator app. This is a demo authenticator. In production, you would configure an authenticator that works with your real identity provider, and therefore would not need to deploy or configure local-user-authenticator.

    kubectl apply -f https://get.pinniped.dev/v0.29.0/install-local-user-authenticator.yaml
    

    The install-local-user-authenticator.yaml file includes the default deployment options. If you would prefer to customize the available options, please see deploy/local-user-authenticator/README.md for instructions on how to deploy using ytt.

  4. Create a test user named pinny-the-seal in the local-user-authenticator namespace.

    kubectl create secret generic pinny-the-seal \
      --namespace local-user-authenticator \
      --from-literal=groups=group1,group2 \
      --from-literal=passwordHash=$(htpasswd -nbBC 10 x password123 | sed -e "s/^x://")
    
  5. Fetch the auto-generated CA bundle for the local-user-authenticator’s HTTP TLS endpoint.

    kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \
      -o jsonpath={.data.caCertificate} \
      | tee /tmp/local-user-authenticator-ca-base64-encoded
    
  6. Deploy the Pinniped Concierge.

    kubectl apply -f https://get.pinniped.dev/v0.29.0/install-pinniped-concierge-crds.yaml
    kubectl apply -f https://get.pinniped.dev/v0.29.0/install-pinniped-concierge-resources.yaml
    

    The install-pinniped-concierge-crds.yaml file contains the Concierge CustomResourceDefinitions. These define the custom APIs that you use to configure and interact with the Concierge.

    The install-pinniped-concierge-resources.yaml file includes the rest of the Concierge resources with default deployment options. If you would prefer to customize the available options, please see the Concierge installation guide for instructions on how to deploy using ytt.

  7. Create a WebhookAuthenticator object to configure the Pinniped Concierge to authenticate using local-user-authenticator.

    cat <<EOF | kubectl create -f -
    apiVersion: authentication.concierge.pinniped.dev/v1alpha1
    kind: WebhookAuthenticator
    metadata:
      name: local-user-authenticator
    spec:
      endpoint: https://local-user-authenticator.local-user-authenticator.svc/authenticate
      tls:
        certificateAuthorityData: $(cat /tmp/local-user-authenticator-ca-base64-encoded)
    EOF
    
  8. Download the latest version of the Pinniped command-line tool for your platform. On macOS or Linux, you can do this using Homebrew:

    brew install vmware-tanzu/pinniped/pinniped-cli
    

    On other platforms, see the command-line installation guide for more details.

  9. Generate a kubeconfig for the current cluster. Use --static-token to include a token which should allow you to authenticate as the user that you created previously.

    pinniped get kubeconfig \
      --static-token "pinny-the-seal:password123" \
      --concierge-authenticator-type webhook \
      --concierge-authenticator-name local-user-authenticator \
      > /tmp/pinniped-kubeconfig
    
  10. Try using the generated kubeconfig to issue arbitrary kubectl commands as the pinny-the-seal user.

    kubectl --kubeconfig /tmp/pinniped-kubeconfig \
      get pods -n pinniped-concierge
    

    Because this user has no RBAC permissions on this cluster, the previous command results in the error Error from server (Forbidden): pods is forbidden: User "pinny-the-seal" cannot list resource "pods" in API group "" in the namespace "pinniped-concierge". However, this does prove that you are authenticated and acting as the pinny-the-seal user.

  11. As the administrator user, create RBAC rules for the test user to give them permissions to perform actions on the cluster. For example, grant the test user permission to view all cluster resources.

    kubectl create clusterrolebinding pinny-can-read \
      --clusterrole view \
      --user pinny-the-seal
    
  12. Use the generated kubeconfig to issue arbitrary kubectl commands as the pinny-the-seal user.

    kubectl --kubeconfig /tmp/pinniped-kubeconfig \
      get pods -n pinniped-concierge
    

    The user has permission to list pods, so the command succeeds this time. Pinniped has provided authentication into the cluster for your kubectl command. 🎉

  13. Carry on issuing as many kubectl commands as you’d like as the pinny-the-seal user. Each invocation uses Pinniped for authentication. You may find it convenient to set the KUBECONFIG environment variable rather than passing --kubeconfig to each invocation.

    export KUBECONFIG=/tmp/pinniped-kubeconfig
    kubectl get namespaces
    kubectl get pods -A