VMware Pinniped is an open-source authentication service for Kubernetes clusters. It allows you to plug external OpenID Connect (OIDC) or LDAP identity providers (IdP) into Kubernetes clusters so that you can control user access to those clusters.
Pinniped is composed of two parts.
- The Pinniped Supervisor is an OIDC server that allows users to authenticate with external identity providers (IDP).
- The Pinniped Concierge is a credential exchange API that takes as input a credential from the Pinniped Supervisor. authenticates the user via that credential, and returns another credential that is understood by the host Kubernetes cluster.
This article shows you how to install and integrate Pinniped with Microsoft Entra ID (Azure AD).
Prerequisites:
- Domain Name (FQDN) for Pinniped-Supervisor endpoint.
- K8s Layer 4 Load Balancer/Ingress.
Microsoft Entra (Azure AD)
Perform the following steps to prepare Microsoft Entra (Azure AD) for Pinniped integration:
- Sign in to the Microsoft Azure portal.
- Navigate to Microsoft Entra ID.
- Select App registrations under the Manage side menu.
- Enter the name of the application. For example, tkg-pinniped-supervisor-app.
- Under Supported account types, select Accounts in this organizational directory only (Single tenant).
- Enter the call URI to the supervisor. For example, https://pinniped-supervisor.domain.com/azure-ad/callback.
- Select Register to create the app.
- Select Token Configuration under the Manage menu.
- Select Add groups claim > All groups (includes distribution lists but not groups assigned to the application).
- Select Add to create the group claim.
- Select the app name in the navigation to return to the app settings page.
- Select the Endpoints tab and record the value in the OpenID Connect metadata document field.
- Return to the app settings page and record the Application (client) ID.
- Select Certificates & secrets under the Manage menu.
Create a new client secret and record this value.
- Select Groups under the Manage side menu.
- Identify or create a list of groups for each of the needed roles (tkg-operator, tkg-viewer, and tkg-editor).
- Retrieve the corresponding object IDs for each group and add users to the groups accordingly.
Pinniped Supervisor
Expose the Pinniped Supervisor endpoint outside the K8s cluster
The supervisor endpoint should be exposed as HTTPS endpoints with proper TLS certificates through TCP LoadBalancer or Ingress.
Create a Load Balancer Service
Create a Service to expose port 8443 of the Supervisor app outside the cluster.
apiVersion: v1
kind: Service
metadata:
name: pinniped-supervisor-loadbalancer
namespace: pinniped-supervisor
spec:
type: LoadBalancer
selector:
app: pinniped-supervisor
ports:
- protocol: TCP
port: 443
targetPort: 8443
Configuring TLS for the Supervisor OIDC endpoints
The TLS certificate for the Supervisor should be created for the DNS Name (FQDN) that end users will use to make requests to the Supervisor.
Install cert-manager
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml
Create a TLS Certificate
Pinniped Supervisor needs TLS certificates that are trusted by the end users’ web browsers.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-cluster-issuer
namespace: cert-manager
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: supervisor-tls-cert
namespace: pinniped-supervisor
spec:
secretName: supervisor-tls-cert
dnsNames:
- "$DNS_NAME"
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
Install Pinniped Supervisor
Install the latest version of the Supervisor into the pinniped-supervisor
namespace with default options:
kubectl apply -f https://get.pinniped.dev/v0.27.0/install-pinniped-supervisor.yaml
Configuring the Supervisor to act as an OIDC provider
At least one FederationDomain must be configured for the Supervisor to provide its functionality. You can create multiple FederationDomains in a single Pinniped Supervisor, as long as each has a unique issuer string.
When the user has started a single sign-on session with that FederationDomain which will last approximately 9 hours. The user will not need to authenticate again into any cluster or any cluster that chooses to trust the FederationDomain for authentication until the session expires.
Behind the scenes, the user’s client (e.g. kubectl) will only be given short-lived access to each cluster (approximately 5 minutes), but will automatically refresh those credentials without the need for user interaction.
---
apiVersion: idp.supervisor.pinniped.dev/v1alpha1
kind: OIDCIdentityProvider
metadata:
namespace: pinniped-supervisor
name: azure-ad
spec:
# Specify the upstream issuer URL.
issuer: https://login.microsoftonline.com/{Value}/v2.0
authorizationConfig:
additionalScopes: ["openid", "email", "profile"]
allowPasswordGrant: false
# Specify how claims are mapped to Kubernetes identities.
claims:
username: preferred_username
groups: groups
# Specify the name of the Kubernetes Secret that contains your
# application's client credentials (created below).
client:
secretName: azure-ad-client-credentials
---
apiVersion: v1
kind: Secret
metadata:
namespace: pinniped-supervisor
name: azure-ad-client-credentials
type: secrets.pinniped.dev/oidc-client
stringData:
clientID: "{Value}"
clientSecret: "{Value}"
---
apiVersion: config.supervisor.pinniped.dev/v1alpha1
kind: FederationDomain
metadata:
name: pinniped-supervisor-federation-domain
namespace: pinniped-supervisor
spec:
issuer: "https://{$DNS_NAME}/azure-ad"
tls:
secretName: supervisor-tls-cert
Check that the DNS, certificate, and FederationDomain are all working together by trying to fetch one of its endpoints. If it works it should return a JSON-formatted discovery response.
curl "https://{$DNS_NAME}/azure-ad/.well-known/openid-configuration"
Install Pinniped Concierge
Install the latest version of the Concierge CustomResourceDefinitions:
kubectl apply -f "https://get.pinniped.dev/v0.27.0/install-pinniped-concierge-crds.yaml"
Install the latest version of the Concierge into the pinniped-concierge
namespace with default options:
kubectl apply -f "https://get.pinniped.dev/v0.27.0/install-pinniped-concierge-resources.yaml"
Configure the Concierge to trust the Supervisor’s FederationDomain for authentication by creating a JWTAuthenticator.
apiVersion: authentication.concierge.pinniped.dev/v1alpha1
kind: JWTAuthenticator
metadata:
name: pinniped-jwt-authenticator
spec:
issuer: https://{$DNS_NAME}/azure-ad #
audience: workload1 # Replace this with your own unique value.
tls:
certificateAuthorityData: #LS0tLS1CRUdJTiBDRVJUSUZJQ0...0tLQo=
Where:
- $DNS_NAME should be the issuer URL that was declared in the FederationDomain.
- CA DATA is the public key of the signing CA or the public key of the Pinniped certificate in base64 format.
Configure RBAC rule for DevOps users
RBAC rules can be defined using usernames and/or group memberships.# Allow DevOps users to view everything in all namespaces.
kubectl create clusterrolebinding devops-view --clusterrole view --user devops01@domain.onmicrosoft.com
Install the Pinniped command-line tool
The Pinniped command-line tool is used to generate Pinniped-compatible kubeconfig files and is also an important part of the Pinniped-based login flow.
It must be installed by administrators setting up a Pinniped cluster as well as by users accessing a Pinniped-enabled cluster.
curl -Lso pinniped https://get.pinniped.dev/v0.27.0/pinniped-cli-linux-amd64 \
&& chmod +x pinniped \
&& sudo mv pinniped /usr/local/bin/pinniped
Generate a kubeconfig file
Create kubeconfig file for the workload clusters that can be used by the DevOps users. It does not contain any identity or credentials.
pinniped get kubeconfig --oidc-ca-bundle ca.pem > devops-view.yaml
Use the kubeconfig with kubectl
DevOps users can run any kubectl command using a kubeconfig file that was provided to them.
kubectl --kubeconfig devops-view.yaml get namespaces
You should see:
- The
pinniped login oidc
command is executed automatically bykubectl
. - Pinniped opens your browser window and directs you to log in with your identity provider.
- After you’ve logged in, you see a page telling you
you have been logged in and may now close this tab.
- In your shell, you see your clusters’ namespaces.
To see the username and group membership as understood by the Kubernetes cluster, you can use this command:
pinniped whoami --kubeconfig devops-view.yaml
Notes:
- Pinniped kubeconfig files do not contain secrets.
- Temporary OIDC session credentials such as ID, access, and refresh tokens are stored in:
~/.config/pinniped/sessions.yaml
(macOS/Linux)%USERPROFILE%/.config/pinniped/sessions.yaml
(Windows).
Reference: Pinniped Documentation