diff --git a/Dockerfile b/Dockerfile index ebe22be71..d4f96dc53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -ARG BUILD_IMAGE=golang:1.22.3@sha256:f43c6f049f04cbbaeb28f0aad3eea15274a7d0a7899a617d0037aec48d7ab010 +ARG BUILD_IMAGE=golang:1.22.4@sha256:969349b8121a56d51c74f4c273ab974c15b3a8ae246a5cffc1df7d28b66cf978 ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:e9ac71e2b8e279a8372741b7a0293afda17650d926900233ec3a7b2b7c22a246 # Prepare to cross-compile by always running the build stage in the build platform, not the target platform. diff --git a/generated/1.30/apis/go.mod b/generated/1.30/apis/go.mod index b63cc1bdc..2dcc40ab0 100644 --- a/generated/1.30/apis/go.mod +++ b/generated/1.30/apis/go.mod @@ -3,7 +3,7 @@ module go.pinniped.dev/generated/1.30/apis go 1.22.0 -toolchain go1.22.3 +toolchain go1.22.4 require ( k8s.io/api v0.30.1 diff --git a/generated/1.30/client/go.mod b/generated/1.30/client/go.mod index bccd89e51..5db1a675c 100644 --- a/generated/1.30/client/go.mod +++ b/generated/1.30/client/go.mod @@ -3,7 +3,7 @@ module go.pinniped.dev/generated/1.30/client go 1.22.0 -toolchain go1.22.3 +toolchain go1.22.4 replace go.pinniped.dev/generated/1.30/apis => ../apis diff --git a/go.mod b/go.mod index 292678ef2..29d0f72a5 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.pinniped.dev go 1.22.0 -toolchain go1.22.2 +toolchain go1.22.4 // This version taken from https://github.com/kubernetes/apiserver/blob/v0.30.0/go.mod#L14 to avoid compile failures. replace github.com/google/cel-go => github.com/google/cel-go v0.17.8 @@ -65,12 +65,12 @@ require ( github.com/tdewolff/minify/v2 v2.20.32 go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.23.0 - golang.org/x/net v0.25.0 - golang.org/x/oauth2 v0.20.0 + golang.org/x/crypto v0.24.0 + golang.org/x/net v0.26.0 + golang.org/x/oauth2 v0.21.0 golang.org/x/sync v0.7.0 - golang.org/x/term v0.20.0 - golang.org/x/text v0.15.0 + golang.org/x/term v0.21.0 + golang.org/x/text v0.16.0 k8s.io/api v0.30.1 k8s.io/apiextensions-apiserver v0.30.1 k8s.io/apimachinery v0.30.1 @@ -188,9 +188,9 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/sys v0.20.0 // indirect + golang.org/x/sys v0.21.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/go.sum b/go.sum index 30cb6720f..a3489111b 100644 --- a/go.sum +++ b/go.sum @@ -694,8 +694,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -780,8 +780,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -791,8 +791,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -867,8 +867,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -878,8 +878,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -891,8 +891,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -957,8 +957,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/hack/Dockerfile_fips b/hack/Dockerfile_fips index c0302f7b3..7b423ad47 100644 --- a/hack/Dockerfile_fips +++ b/hack/Dockerfile_fips @@ -16,7 +16,7 @@ # See https://go.googlesource.com/go/+/dev.boringcrypto/README.boringcrypto.md # and https://kupczynski.info/posts/fips-golang/ for details. -ARG BUILD_IMAGE=golang:1.22.3@sha256:f43c6f049f04cbbaeb28f0aad3eea15274a7d0a7899a617d0037aec48d7ab010 +ARG BUILD_IMAGE=golang:1.22.4@sha256:969349b8121a56d51c74f4c273ab974c15b3a8ae246a5cffc1df7d28b66cf978 ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:e9ac71e2b8e279a8372741b7a0293afda17650d926900233ec3a7b2b7c22a246 # This is not currently using --platform to prepare to cross-compile because we use gcc below to build diff --git a/site/config.yaml b/site/config.yaml index 68b46e355..4706eab7e 100644 --- a/site/config.yaml +++ b/site/config.yaml @@ -7,7 +7,7 @@ params: github_url: "https://github.com/vmware-tanzu/pinniped" slack_url: "https://go.pinniped.dev/community/slack" community_url: "https://go.pinniped.dev/community" - latest_version: v0.30.0 + latest_version: v0.31.0 latest_codegen_version: 1.30 pygmentsCodefences: true pygmentsStyle: "pygments" diff --git a/site/content/docs/howto/supervisor/configure-supervisor-with-github.md b/site/content/docs/howto/supervisor/configure-supervisor-with-github.md index 4d42e6142..60d85bed6 100644 --- a/site/content/docs/howto/supervisor/configure-supervisor-with-github.md +++ b/site/content/docs/howto/supervisor/configure-supervisor-with-github.md @@ -32,7 +32,6 @@ The Pinniped Supervisor supports both. The instructions below reference the steps needed to configure a GitHub App or GitHub OAuth2 App on https://github.com at the time of writing. GitHub UI and documentation changes frequently and may not exactly match the steps below. -The below steps have not been tested with any version of GitHub Enterprise Server. Please submit a PR at the [Pinniped repo](https://github.com/vmware-tanzu/pinniped) to resolve any discrepancies. ## Alternative 1: Create a GitHub App diff --git a/site/content/docs/reference/cli.md b/site/content/docs/reference/cli.md index 42e491034..ddf9e45e7 100644 --- a/site/content/docs/reference/cli.md +++ b/site/content/docs/reference/cli.md @@ -205,7 +205,7 @@ pinniped get kubeconfig [flags] --timeout duration Timeout for autodiscovery and validation (default 10m0s) --upstream-identity-provider-flow string The type of client flow to use with the upstream identity provider during login with a Supervisor (e.g. 'cli_password', 'browser_authcode') --upstream-identity-provider-name string The name of the upstream identity provider used during login with a Supervisor - --upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap', 'activedirectory') + --upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap', 'activedirectory', 'github') ``` ### SEE ALSO @@ -277,7 +277,7 @@ pinniped login oidc --issuer ISSUER [flags] --skip-browser Skip opening the browser (just print the URL) --upstream-identity-provider-flow string The type of client flow to use with the upstream identity provider during login with a Supervisor (e.g. 'browser_authcode', 'cli_password') --upstream-identity-provider-name string The name of the upstream identity provider used during login with a Supervisor - --upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap', 'activedirectory') (default "oidc") + --upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap', 'activedirectory', 'github') (default "oidc") ``` ### SEE ALSO diff --git a/site/content/posts/2024-06-06-githubidentityprovider.md b/site/content/posts/2024-06-06-githubidentityprovider.md new file mode 100644 index 000000000..cada2c775 --- /dev/null +++ b/site/content/posts/2024-06-06-githubidentityprovider.md @@ -0,0 +1,193 @@ +--- +title: "Pinniped v0.31.0: GitHub as an identity provider" +slug: github-idp-support +date: 2024-06-06 +author: Ryan Richard +image: https://images.unsplash.com/photo-1557657043-23eec69b89c9?q=80&w=3008&auto=format&fit=crop&ixlib=rb-4.0.3 +excerpt: "With the release of v0.31.0, Pinniped brings GitHub identities to Kubernetes clusters everywhere" +tags: ['Ryan Richard', 'release'] +--- + +![sunbathing seal](https://images.unsplash.com/photo-1557657043-23eec69b89c9?q=80&w=3008&auto=format&fit=crop&ixlib=rb-4.0.3) +*Photo from [Unsplash](https://unsplash.com/photos/white-seal-on-soil-giZJHm2m9yY)* + +Pinniped's v0.31.0 release brings your enterprise's developer and operator GitHub identities +to all your Kubernetes clusters. +Previously, Pinniped supported external identity providers of types +OpenID Connect (OIDC), Lightweight Directory Access Protocol (LDAP), and Active +Directory (AD) configured for either one or many clusters. +If you're already managing your source code on github.com or using GitHub Enterprise, +then your developers and operators already have GitHub identities. +Now you can easily control their authentication and authorization to your fleets of Kubernetes clusters +using that same GitHub identity, with the same great security and user experience that Pinniped already offers. + +Additionally, the release includes several dependency updates and other changes. +See the [release notes](https://github.com/vmware-tanzu/pinniped/releases/tag/v0.31.0) for more details. + +## Configuring GitHub authentication + +Using GitHub is as easy as creating a GitHubIdentityProvider resource in your Supervisor's namespace, and then +adding it to your FederationDomain resource's spec.identityProviders. Once configured, then you can generate +kubeconfigs for your clusters and hand those out to your end-users. As always with the Pinniped Supervisor, +these kubeconfig files will not contain any particular identity or credentials, and can be shared among +all users of that cluster. + +## The minimum configuration + +Here is the most basic example of a GitHubIdentityProvider. +You'll need to configure a new GitHub App or GitHub OAuth app on GitHub +and note the client ID and client secret for use in your Pinniped configuration. +See the [GitHub configuration guide]({{< ref "docs/howto/supervisor/configure-supervisor-with-github.md" >}}) +for details about how to create a GitHub App or GitHub OAuth app. + +```yaml +apiVersion: idp.supervisor.pinniped.dev/v1alpha1 +kind: GitHubIdentityProvider +metadata: + name: my-github-provider + namespace: pinniped-supervisor +spec: + allowAuthentication: + organizations: + policy: AllGitHubUsers + client: + secretName: my-github-provider-client-secret +--- +apiVersion: v1 +kind: Secret +type: "secrets.pinniped.dev/github-client" +metadata: + name: my-github-provider-client-secret + namespace: pinniped-supervisor +stringData: + clientID: + clientSecret: +``` + +This GitHubIdentityProvider uses github.com (the default) and allows any user of github.com to authenticate. + +But wait a minute! Any user of github.com? Aren't there millions of users? Yes, there are. +This simplest configuration example is great for a demo or for a Kubernetes cluster running on your laptop, +but you may not want to use this for your enterprise's fleets of Kubernetes clusters. + +However, note that you could use the above GitHubIdentityProvider along with a policy on the FederationDomain +to reject authentication for any user unless they belong to certain GitHub teams. For example: + +```yaml +apiVersion: config.supervisor.pinniped.dev/v1alpha1 +kind: FederationDomain +metadata: + name: my-federation-domain + namespace: pinniped-supervisor +spec: + issuer: https://pinniped.example.com/my-issuer-path + identityProviders: + - displayName: "My GitHub IDP 🚀" + objectRef: + apiGroup: idp.supervisor.pinniped.dev + kind: GitHubIdentityProvider + name: my-github-provider + transforms: + expressions: + - type: policy/v1 + expression: 'groups.exists(g, g in ["my-github-org/team1", "my-github-org/team2"])' + message: "Only users in certain GitHub teams are allowed to authenticate" +``` + +Now users must belong to one of the two teams configured above to be able to successfully authenticate. + +## Restricting authentication by GitHub organization membership + +Would you rather only allow members of certain GitHub organizations to authenticate? No problem, we've got you covered. +Just make a small change to your GitHubIdentityProvider. + +```yaml +apiVersion: idp.supervisor.pinniped.dev/v1alpha1 +kind: GitHubIdentityProvider +metadata: + name: my-github-provider + namespace: pinniped-supervisor +spec: + allowAuthentication: + organizations: + policy: OnlyUsersFromAllowedOrganizations + allowed: + - my-enterprise-organization # this is case-insensitive + client: + secretName: my-github-provider-client-secret +``` + +Now users must belong to the organization configured above to successfully authenticate. + +When multiple orgs are `allowed` then the user must belong to any one of those orgs. + +Want to further restrict auth by GitHub team membership? +No problem, you can still create a `policy/v1` expression as shown in the previous example above. + +## Using GitHub Enterprise + +Are you running GitHub Enterprise for your source control needs? You can use your GitHub Enterprise server's user +identities by specifying the `host` and optional `tls.certificateAuthorityData`. + +```yaml +apiVersion: idp.supervisor.pinniped.dev/v1alpha1 +kind: GitHubIdentityProvider +metadata: + name: my-github-provider + namespace: pinniped-supervisor +spec: + host: github.my-enterprise.example.com + tls: + certificateAuthorityData: LS0tLS1CRUdJTiBDRVJUSUZJQ0FU.... # optional + allowAuthentication: + organizations: + policy: OnlyUsersFromAllowedOrganizations + allowed: + - my-enterprise-organization + client: + secretName: my-github-provider-client-secret +``` + +## Kubernetes username and group names + +The GitHubIdentityProvider resource offers several choices for how your users' Kubernetes usernames and group names should look. + +`spec.claims.username` allows you to choose from: +- `login`: The user's GitHub username as shown on their profile. Note that a user can change their own username, + so this is not recommended for production use with identities from public github.com. +- `id`: The numeric user ID assigned by GitHub will be used as the username. On public github.com, this can be found for any user + by putting their login name into this GitHub API URL: `https://api.github.com/users/cfryanr` (replace `cfryanr` with the login name). + This is automatically assigned and immutable for each user. +- `login:id`: Blends the readability of using login names with the immutability of using IDs by putting both into + the Kubernetes usernames, separated by a colon. This keeps your RBAC policies nicely readable. This is the default. + +`spec.claims.groups` allows you to choose from: +- `name`: GitHub team names can include mixed-case characters, spaces, and punctuation, e.g. `Kube admins!`. +- `slug`: GitHub slug names are lower-cased, with spaces replaced by hyphens, and other punctuation removed, e.g. `kube-admins`. + This is the default. +- Either way, the team names will automatically be prefixed by the name of the org in which the team resides, with a `/` separator, + e.g. `My-org/kube-admins`. The org name will preserve its case from GitHub. + +## Control new and existing sessions by changing org and team memberships on GitHub + +Did one of your developers or operators just change teams or leave your enterprise? Fear not. Simply update their +GitHub organization and/or GitHub team memberships on github.com and Pinniped will respect those changes almost immediately. + +When one of your end users starts a new session, your org and team-based restrictions will apply using your +updated org and team memberships immediately. + +For your end-users with pre-existing ongoing sessions Pinniped will see the new org and team memberships at the next +session refresh, which happens approximately every 5 minutes in a standard Pinniped configuration for active sessions. +Your Kubernetes RBAC policies will see the updated group memberships after the next refresh. +There is no way for your end users to avoid these refreshes without losing access to your clusters. + +## Where to read more + +This blog post is just a quick overview of this new feature. To learn about how to configure the Pinniped Supervisor +with this new feature, see: + +- The [GitHub configuration guide]({{< ref "docs/howto/supervisor/configure-supervisor-with-github.md" >}}). +- The [GitHubIdentityProvider resource](https://github.com/vmware-tanzu/pinniped/blob/main/generated/latest/README.adoc#githubidentityprovider) documentation. +- The documentation for [configuring identity providers on FederationDomains]({{< ref "docs/howto/supervisor/configure-supervisor-federationdomain-idps.md" >}}). + +{{< community >}} diff --git a/test/testlib/browsertest/browsertest.go b/test/testlib/browsertest/browsertest.go index 90a521075..317295251 100644 --- a/test/testlib/browsertest/browsertest.go +++ b/test/testlib/browsertest/browsertest.go @@ -499,6 +499,18 @@ func handleOccasionalGithubLoginPage(t *testing.T, b *Browser, upstream testlib. b.ClickFirstMatch(t, submitConfirmButtonSelector) return true + case strings.HasPrefix(lowercaseTitle, "verify two-factor authentication"): + // Next GitHub might occasionally as you to confirm your MFA settings. + // Wait for the page to be rendered. + t.Logf("waiting for GitHub skip link") + // There are several buttons and links. We want to click this link to "skip 2FA verification": + //