From 40d93ff33bbf80d39586ff0b1370619e1df3da85 Mon Sep 17 00:00:00 2001 From: Andrew Keesler Date: Fri, 18 Dec 2020 09:39:36 -0500 Subject: [PATCH] site/content/docs/architecture.md: another coat of paint with Supervisor updates Signed-off-by: Andrew Keesler --- site/content/docs/architecture.md | 80 ++++++++++++++----- site/content/docs/demo.md | 4 +- site/content/docs/img/README.md | 11 ++- ...ed.svg => pinniped-concierge-sequence.svg} | 0 ...ed.txt => pinniped-concierge-sequence.txt} | 0 ...pinniped-concierge-supervisor-sequence.svg | 60 ++++++++++++++ ...pinniped-concierge-supervisor-sequence.txt | 52 ++++++++++++ 7 files changed, 181 insertions(+), 26 deletions(-) rename site/content/docs/img/{pinniped.svg => pinniped-concierge-sequence.svg} (100%) rename site/content/docs/img/{pinniped.txt => pinniped-concierge-sequence.txt} (100%) create mode 100644 site/content/docs/img/pinniped-concierge-supervisor-sequence.svg create mode 100644 site/content/docs/img/pinniped-concierge-supervisor-sequence.txt diff --git a/site/content/docs/architecture.md b/site/content/docs/architecture.md index 8181259c..c3bfb531 100644 --- a/site/content/docs/architecture.md +++ b/site/content/docs/architecture.md @@ -10,14 +10,14 @@ The principal purpose of Pinniped is to allow users to access Kubernetes clusters. Pinniped hopes to enable this access across a wide range of Kubernetes environments with zero configuration. -This integration is composed of two parts. -One part, the supervisor, is an OIDC server which allows users -to authenticate with their external Identity Provider, -then issues its own federation id tokens to be passed on to clusters -based on the information from the external Identity Provider's token. -The other, the concierge, is a credential exchange API which takes as input a token -(from the supervisor or elsewhere), and returns a credential which is understood by -the host Kubernetes cluster. +Pinniped is composed of two parts. +1. The Pinniped Supervisor is an OIDC server which allows users to authenticate +with an external identity provider (IDP), and then issues its own federation ID tokens +to be passed on to clusters based on the user information from the IDP. +1. The Pinniped Concierge is a credential exchange API which takes as input a +credential from an identity source (e.g., Pinniped Supervisor, proprietary IDP), +authenticates the user via that credential, and returns another credential which is +understood by the host Kubernetes cluster. ![Pinniped Architecture Sketch](/docs/img/pinniped_architecture.svg) @@ -34,15 +34,29 @@ Support for other types of Kubernetes distributions is coming soon. ## External Identity Provider Integrations -Pinniped will consume identity from one or more external identity providers -(IDPs). Administrators will configure external IDPs via Kubernetes custom -resources allowing Pinniped to be managed using GitOps and standard Kubernetes tools. +The Pinniped Supervisor will federate identity from one or more IDPs. +Administrators will configure the Pinniped Supervisor to use IDPs via Kubernetes +custom resources allowing Pinniped to be managed using GitOps and standard +Kubernetes tools. + +Pinniped supports the following IDPs. + +1. Any [OIDC-compliant](https://openid.net/specs/openid-connect-core-1_0.html) + identity provider (e.g., [Dex](https://github.com/dexidp/dex), + [Okta](https://www.okta.com/)). + +The +[`idp.supervisor.pinniped.dev`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.19/README.adoc#k8s-api-idp-supervisor-pinniped-dev-v1alpha1) +API group contains the Kubernetes custom resources that configure the Pinniped +Supervisor's upstream IDPs. + +More IDP integrations are coming soon. ## Authenticators -The Pinniped concierge requires one or more **authenticators** to validate tokens before -issuing cluster specific certificates. -Administrators will configure external IDPs via Kubernetes custom +The Pinniped Concierge requires one or more **authenticators** to validate external credentials in order to +issue cluster specific credentials. +Administrators will configure authenticators via Kubernetes custom resources allowing Pinniped to be managed using GitOps and standard Kubernetes tools. Pinniped supports the following authenticator types. @@ -56,9 +70,20 @@ Pinniped supports the following authenticator types. sample implementation in Golang. See the `ServeHTTP` method of [cmd/local-user-authenticator/main.go](https://github.com/vmware-tanzu/pinniped/blob/main/cmd/local-user-authenticator/main.go). -1. A JwtAuthenticator resource, which will validate and parse claims from - JWT id tokens. - This can be used to validate tokens that are issued by the supervisor. +1. A JSON Web Token (JWT) authenticator, which will validate and parse claims + from JWTs. This can be used to validate tokens that are issued by the + Pinniped Supervisor, any + [OIDC-compliant](https://openid.net/specs/openid-connect-core-1_0.html) + identity provider, or various other identity sources. The JWT authenticator + provides the same functionality as the [Kubernetes OIDC authentication + mechanism](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens), + but it is configurable at cluster runtime instead of requiring flags to be + set on the `kube-apiserver` process. + +The +[`authentication.concierge.pinniped.dev`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.19/README.adoc#k8s-api-authentication-concierge-pinniped-dev-v1alpha1) +API group contains the Kubernetes custom resources that configure the Pinniped +Concierge's authenticators. ## Cluster Integration Strategies @@ -80,15 +105,26 @@ support more Kubernetes cluster types. ## kubectl Integration -With any of the above IDPs and integration strategies, `kubectl` commands receive the +With any of the above IDPs, authentication methods, and cluster integration strategies, `kubectl` commands receive the cluster-specific credential via a [Kubernetes client-go credential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins). Users may use the Pinniped CLI as the credential plugin, or they may use any proprietary CLI built with the [Pinniped Go client library](https://github.com/vmware-tanzu/pinniped/tree/main/generated). -## Example Cluster Authentication Sequence Diagram +## Example Cluster Authentication Sequence Diagrams -This diagram demonstrates using `kubectl get pods` with the Pinniped CLI configured as the credential plugin, -and with a webhook IDP configured as the identity provider for the Pinniped server. +### Concierge With Webhook -![example-cluster-authentication-sequence-diagram](/docs/img/pinniped.svg) +This diagram demonstrates using `kubectl get pods` with a [Kubernetes client-go credential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins) +that obtains an external credential to be sent to a webhook authenticator via the Pinniped Concierge. + +![concierge-with-webhook-sequence-diagram](/docs/img/pinniped-concierge-sequence.svg) + +### Concierge with Supervisor + +This diagram demonstrates using `kubectl get pods` with the Pinniped CLI +functioning as a [Kubernetes client-go credential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins) +that obtains a federation ID token from the Pinniped Supervisor to be sent to a +JWT authenticator via the Pinniped Concierge. + +![concierge-with-supervisor-sequence-diagram](/docs/img/pinniped-concierge-supervisor-sequence.svg) diff --git a/site/content/docs/demo.md b/site/content/docs/demo.md index 53254385..0e4be526 100644 --- a/site/content/docs/demo.md +++ b/site/content/docs/demo.md @@ -5,5 +5,5 @@ cascade: --- # Trying Pinniped -1. [Concierge with webhook demo](/docs/concierge-only-demo) -1. [Concierge with supervisor and JWTAuthenticator demo](/docs/concierge-and-supervisor-demo) +1. [Concierge with webhook demo](/docs/concierge-only-demo) +1. [Concierge with Supervisor and JWT authenticator demo](/docs/concierge-and-supervisor-demo) diff --git a/site/content/docs/img/README.md b/site/content/docs/img/README.md index e4db879a..6383c42e 100644 --- a/site/content/docs/img/README.md +++ b/site/content/docs/img/README.md @@ -2,8 +2,15 @@ ## How to Update these Images -- [pinniped.svg](pinniped.svg) was generated using [`plantuml`](https://plantuml.com/). - To regenerate the image, run `plantuml -tsvg pinniped.txt` from this directory. +- [pinniped-concierge-sequence.svg](pinniped-concierge-sequence.svg) was + generated using [`plantuml`](https://plantuml.com/). To regenerate the image, + run `plantuml -tsvg pinniped.txt` from this directory, or go to + https://www.planttext.com/. + +- [pinniped-concierge-supervisor-sequence.svg](pinniped-concierge-supervisor-sequence.svg) + was generated using [`plantuml`](https://plantuml.com/). To regenerate the + image, run `plantuml -tsvg pinniped.txt` from this directory, or go to + https://www.planttext.com/. - [pinniped_architecture.svg](pinniped_architecture.svg) was created on [draw.io](https://draw.io). It can be opened again for editing on that site by choosing "File" -> "Open from" -> "Device". diff --git a/site/content/docs/img/pinniped.svg b/site/content/docs/img/pinniped-concierge-sequence.svg similarity index 100% rename from site/content/docs/img/pinniped.svg rename to site/content/docs/img/pinniped-concierge-sequence.svg diff --git a/site/content/docs/img/pinniped.txt b/site/content/docs/img/pinniped-concierge-sequence.txt similarity index 100% rename from site/content/docs/img/pinniped.txt rename to site/content/docs/img/pinniped-concierge-sequence.txt diff --git a/site/content/docs/img/pinniped-concierge-supervisor-sequence.svg b/site/content/docs/img/pinniped-concierge-supervisor-sequence.svg new file mode 100644 index 00000000..60cc5cef --- /dev/null +++ b/site/content/docs/img/pinniped-concierge-supervisor-sequence.svg @@ -0,0 +1,60 @@ +WorkstationSupervisor ClusterConcierge ClusterCorporate NetworkUserUserBrowserBrowserKubectlKubectlPinniped CLIPinniped CLIPinnipedPinnipedPinnipedPinnipedOIDC IDPOIDC IDPkubectl get podsget credential for cluster authenticationstarts localhost listener"open browser to URL X"clicks linkGET https://supervisor.com/oauth2/authorize302 to IDP/authorize?redirect_uri=https://supervisor.com/callbackGET /authorize?redirect_uri=https://supervisor.com/callbackIDP authenticates user302 tohttps://supervisor.com/callbackGET https://supervisor.com/callbackPOST /tokenaccess token, ID token, refresh token302 tohttp://localhost:1234/callbackGET http://localhost:1234/callbackPOST https://supervisor.com/oauth2/tokenlookup auth codeissue refresh tokenissue ID+access tokensrefresh+access+ID tokensPOST /oauth2/token(w/ access token per RFC8693)cluster-specific ID tokencreate TokenCredentialRequest (w/ cluster-specific ID token)cluster-specific certificate and keycluster-specific certificate and keyGET /api/v1/podsGlean user and group information fromcluster-specific credential200 OKwith pods diff --git a/site/content/docs/img/pinniped-concierge-supervisor-sequence.txt b/site/content/docs/img/pinniped-concierge-supervisor-sequence.txt new file mode 100644 index 00000000..a006b508 --- /dev/null +++ b/site/content/docs/img/pinniped-concierge-supervisor-sequence.txt @@ -0,0 +1,52 @@ +@startuml Login + +actor User + +box "Workstation" +participant Browser +participant Kubectl +participant "Pinniped CLI" +end box + +box "Supervisor Cluster" +participant Pinniped as sp +end box + +box "Concierge Cluster" +participant Pinniped as wp +end box + +box "Corporate Network" +participant "OIDC IDP" as IDP +end box + +User -> Kubectl: kubectl get pods +Kubectl -> "Pinniped CLI" : get credential for cluster authentication +"Pinniped CLI" -> "Pinniped CLI": starts localhost listener +"Pinniped CLI" -> User: open browser to URL X +User -> Browser: clicks link +Browser -> sp : ""GET https://supervisor.com/oauth2/authorize"" +sp -> Browser: 302 to IDP ""/authorize?redirect_uri=https://supervisor.com/callback"" +Browser -> IDP: ""GET /authorize?redirect_uri=https://supervisor.com/callback"" +IDP -> IDP: IDP authenticates user +IDP -> Browser: 302 to ""https://supervisor.com/callback"" +Browser -> sp: ""GET https://supervisor.com/callback"" +sp -> IDP: ""POST /token"" +IDP -> sp: access token, ID token, refresh token +sp -> Browser: 302 to ""http://localhost:1234/callback"" +Browser -> "Pinniped CLI": ""GET http://localhost:1234/callback"" +"Pinniped CLI" -> sp: ""POST https://supervisor.com/oauth2/token"" +sp -> sp: lookup auth code +sp -> sp: issue refresh token +sp -> sp: issue ID+access tokens +sp -> "Pinniped CLI": refresh+access+ID tokens +"Pinniped CLI" -> sp: ""POST /oauth2/token"" (w/ access token per RFC8693) +sp -> "Pinniped CLI": cluster-specific ID token +"Pinniped CLI" -> wp: create TokenCredentialRequest (w/ cluster-specific ID token) +wp -> "Pinniped CLI": cluster-specific certificate and key +"Pinniped CLI" -> Kubectl: cluster-specific certificate and key +Kubectl -> wp : ""GET /api/v1/pods"" +wp -> wp : Glean user and group information from\ncluster-specific credential +wp -> Kubectl : ""200 OK"" with pods + +@enduml