Compare commits

...

794 Commits

Author SHA1 Message Date
Margo Crawford
b458cd43b9 Merge pull request #1159 from vmware-tanzu/fix-openldap-typo
Tiny fix to openldap group name: pinninpeds->pinnipeds
2022-05-05 12:50:43 -07:00
Margo Crawford
07a3faf449 Merge branch 'main' into fix-openldap-typo 2022-05-05 10:51:09 -07:00
anjalitelang
1a59b6a686 Update ROADMAP.md
Changes made to reflect status as of May 4th, 2022
2022-05-04 16:06:33 -04:00
Margo Crawford
eb891d77a5 Tiny fix: pinninpeds->pinnipeds
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-05-04 12:42:55 -07:00
Ryan Richard
572474605f Merge pull request #1151 from vmware-tanzu/more_unit_tests_for_ldap_escaping
More unit tests for LDAP DNs which contain special chars
2022-05-04 09:49:20 -07:00
Ryan Richard
a36688573b Merge pull request #1150 from vmware-tanzu/prepare_supervisor_on_kind_active_directory
Support AD in hack/prepare-supervisor-on-kind.sh
2022-05-04 09:16:13 -07:00
Ryan Richard
acc6c50e48 More unit tests for LDAP DNs which contain special chars
Adding explicit coverage for PerformRefresh().
2022-05-03 15:43:01 -07:00
Ryan Richard
eaa87c7628 support AD in hack/prepare-supervisor-on-kind.sh 2022-05-03 12:59:39 -07:00
Ryan Richard
d6e61012c6 Merge pull request #1149 from vmware-tanzu/update_kube_versions
Update kube codegen versions
2022-05-02 15:35:49 -07:00
Ryan Richard
cc1f0b8db9 Merge pull request #1148 from vmware-tanzu/ldap_group_search_escape
Escape special characters in LDAP DNs when used in search filters
2022-05-02 14:44:45 -07:00
Ryan Richard
90e88bb83c Update kube codegen versions
Note that attempting to update 1.18.18 to 1.18.20 didn't work for some
reason, so I skipped that one. The code generator didn't like 1.18.20
and it deleted all the generated code. Avoiding 1.18.19 because it is
listed as having a regression at
https://kubernetes.io/releases/patch-releases/#non-active-branch-history
2022-05-02 14:33:33 -07:00
Ryan Richard
2ad181c7dd Merge branch 'main' into ldap_group_search_escape 2022-05-02 13:49:55 -07:00
Mo Khan
ee881aa406 Merge pull request #1146 from enj/enj/i/bump_0007
Bump deps to latest and go mod compat to 1.17
2022-05-02 16:44:49 -04:00
Ryan Richard
c74dea6405 Escape special characters in LDAP DNs when used in search filters 2022-05-02 13:37:32 -07:00
Monis Khan
2cdb55e7da Bump deps to latest and go mod compat to 1.17
Signed-off-by: Monis Khan <mok@vmware.com>
2022-04-28 15:37:51 -04:00
Ryan Richard
24b0ddf600 Merge pull request #1140 from vmware-tanzu/bump_kube_deps_v0.23.6
bump kube deps from v0.23.5 to v0.23.6
2022-04-21 10:18:43 -07:00
Ryan Richard
cab9ac8368 bump kube deps from v0.23.5 to v0.23.6 2022-04-21 09:17:24 -07:00
Ryan Richard
793b8b9260 Merge pull request #1121 from anjaltelang/main
v0.16.0 Blog
2022-04-20 11:54:20 -07:00
Pinny
4071b48f01 Updated versions in docs for v0.16.0 release 2022-04-20 18:52:59 +00:00
Ryan Richard
46e61bdea9 Update 2022-04-15-fips-and-more.md
Update release date
2022-04-20 10:56:21 -07:00
Ryan Richard
52341f4e49 Merge pull request #1083 from vmware-tanzu/dependabot/go_modules/k8s.io/klog/v2-2.60.1
Bump k8s.io/klog/v2 from 2.40.1 to 2.60.1
2022-04-19 15:22:08 -07:00
dependabot[bot]
cd982655a2 Bump k8s.io/klog/v2 from 2.40.1 to 2.60.1
Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.40.1 to 2.60.1.
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.40.1...v2.60.1)

---
updated-dependencies:
- dependency-name: k8s.io/klog/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-19 20:33:38 +00:00
Margo Crawford
311bb05993 Merge pull request #1130 from vmware-tanzu/kube-versions-april-22
Update kube versions to latest patch
2022-04-19 13:30:40 -07:00
Ryan Richard
0ec5e57114 Merge pull request #1131 from vmware-tanzu/bump_some_deps
Bump some deps
2022-04-19 13:29:28 -07:00
Margo Crawford
63779ddac2 Merge pull request #1129 from vmware-tanzu/jwt-authenticator-client-field
JWTAuthenticator distributed claims resolution honors tls config
2022-04-19 13:28:43 -07:00
Ryan Richard
4de8004094 Empty commit to trigger CI 2022-04-19 12:12:45 -07:00
Margo Crawford
0b72f7084c JWTAuthenticator distributed claims resolution honors tls config
Kube 1.23 introduced a new field on the OIDC Authenticator which
allows us to pass in a client with our own TLS config. See
https://github.com/kubernetes/kubernetes/pull/106141.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-04-19 11:36:46 -07:00
Ryan Richard
132d2aac72 add a code comment 2022-04-19 11:35:46 -07:00
Ryan Richard
2d4f4e4efd Merge branch 'main' into bump_some_deps 2022-04-19 11:32:53 -07:00
Margo Crawford
c40bca5e65 Merge pull request #1127 from hectorj2f/add_code_challenge_method_support
oidc: add code challenge supported methods to the discovery doc
2022-04-19 11:23:57 -07:00
Margo Crawford
019750a292 Update kube versions to latest patch
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-04-19 11:19:24 -07:00
Anjali Telang
9e5d4ae51c Blog for v0.16.0
Signed-off-by: Anjali Telang <atelang@vmware.com>
2022-04-19 14:16:45 -04:00
Ryan Richard
5b9831d319 bump the kube direct deps 2022-04-19 11:13:52 -07:00
Ryan Richard
fb8083d024 bump some direct deps 2022-04-19 11:09:24 -07:00
hectorj2f
a3f7afaec4 oidc: add code challenge supported methods
Signed-off-by: hectorj2f <hectorf@vmware.com>
2022-04-19 01:21:39 +02:00
Margo Crawford
f5cf3276d5 Merge pull request #1123 from vmware-tanzu/macos-untrusted-certificate-errors 2022-04-14 20:15:31 -07:00
Margo Crawford
d5337c9c19 Error format of untrusted certificate errors should depend on OS
Go 1.18.1 started using MacOS' x509 verification APIs on Macs
rather than Go's own. The error messages are different.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-04-14 17:37:36 -07:00
Mo Khan
c624846eaa Merge pull request #1122 from vmware-tanzu/impersonator-only-http2
the http2RoundTripper should only use http2
2022-04-14 16:55:50 -04:00
Margo Crawford
03f19da21c the http2RoundTripper should only use http2
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-04-14 10:51:25 -07:00
Mo Khan
8fe635e7ce Merge pull request #1096 from vmware-tanzu/dependabot/docker/distroless/static-2556293
Bump distroless/static from `80c956f` to `2556293`
2022-04-14 12:53:59 -04:00
dependabot[bot]
2fa81546f3 Bump distroless/static from 80c956f to 2556293
Bumps distroless/static from `80c956f` to `2556293`.

---
updated-dependencies:
- dependency-name: distroless/static
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-14 14:51:17 +00:00
Mo Khan
43485563ff Merge pull request #1120 from vmware-tanzu/dependabot/docker/hack/google.com/api-project-999119582588/go-boringcrypto/golang-1.18.1b7
Bump google.com/api-project-999119582588/go-boringcrypto/golang from 1.17.8b7 to 1.18.1b7 in /hack
2022-04-14 10:26:04 -04:00
dependabot[bot]
5621c1161a Bump google.com/api-project-999119582588/go-boringcrypto/golang in /hack
Bumps google.com/api-project-999119582588/go-boringcrypto/golang from 1.17.8b7 to 1.18.1b7.

---
updated-dependencies:
- dependency-name: google.com/api-project-999119582588/go-boringcrypto/golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-14 13:26:21 +00:00
Mo Khan
79fd8e2901 Merge pull request #1119 from enj/enj/i/fips_log_errs
Only emit FIPS startup log when running a server component
2022-04-14 09:19:40 -04:00
Monis Khan
e0886c6948 Only emit FIPS startup log when running a server component
Signed-off-by: Monis Khan <mok@vmware.com>
2022-04-13 18:31:02 -04:00
Mo Khan
f5cc2f20f7 Merge pull request #1118 from enj/enj/i/go1.18_linter_fix
Bump to go1.18.1 and fix linter errors
2022-04-13 18:15:20 -04:00
Monis Khan
8fd77b72df Bump to go1.18.1 and fix linter errors
Signed-off-by: Monis Khan <mok@vmware.com>
2022-04-13 16:43:06 -04:00
Mo Khan
8ecf18521c Merge pull request #1112 from vmware-tanzu/fips-website-docs
document how to use the fips dockerfile on our website
2022-04-13 16:41:25 -04:00
Margo Crawford
96c705bf94 document how to use the fips dockerfile on our website
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-04-13 12:45:58 -07:00
Mo Khan
d0d20e00e4 Merge pull request #1117 from vmware-tanzu/prefix_tokens
Add custom prefix to downstream access and refresh tokens and authcodes
2022-04-13 15:34:42 -04:00
Ryan Richard
53348b8464 Add custom prefix to downstream access and refresh tokens and authcodes 2022-04-13 10:13:27 -07:00
Ryan Richard
13daf59217 Merge pull request #1108 from vicmarbev/main
Use vmware-tanzu/carvel instead of the deprecated k14s/tap to install deps with brew
2022-04-13 08:43:39 -07:00
Ryan Richard
9ebf3a5b92 Merge branch 'main' into main 2022-04-13 08:41:04 -07:00
Mo Khan
6af1aaeb20 Merge pull request #1114 from enj/enj/i/fips_init_log
Use klog to make sure FIPS init log is emitted
2022-04-12 16:23:38 -04:00
Monis Khan
6b4fbb6e0e Use klog to make sure FIPS init log is emitted
We cannot use plog until the log level config has been setup, but
that occurs after this init function has run.

Signed-off-by: Monis Khan <mok@vmware.com>
2022-04-12 14:36:06 -04:00
Mo Khan
edf4ffb018 Merge pull request #1101 from vmware-tanzu/dependabot/docker/hack/distroless/static-2556293
Bump distroless/static from `80c956f` to `2556293` in /hack
2022-04-11 12:37:25 -04:00
dependabot[bot]
721526b7e7 Bump distroless/static from 80c956f to 2556293 in /hack
Bumps distroless/static from `80c956f` to `2556293`.

---
updated-dependencies:
- dependency-name: distroless/static
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-07 14:13:12 +00:00
anjalitelang
91681b9368 Update ROADMAP.md
Edits to the wiki based on our current backlog 4/5/2022
2022-04-06 16:08:04 -04:00
Mo Khan
3c6f97a457 Target hack/Dockerfile_fips correctly 2022-04-06 15:32:08 -04:00
Mo Khan
12cbd744b7 Syntax highlighting for Dockerfile_fips 2022-04-06 15:31:07 -04:00
Ryan Richard
103538858f Merge pull request #1094 from vmware-tanzu/disable_http
Supervisor HTTP listener disabled by default and may only bind to loopback interfaces
2022-04-05 12:39:04 -07:00
Ryan Richard
bdabdf0f42 Update comment in FederationDomainTLSSpec 2022-04-05 09:53:22 -07:00
Ryan Richard
25d20d4081 Merge branch 'main' into disable_http 2022-04-05 09:00:26 -07:00
Víctor Martínez Bevià
dc24397df4 Use vmware-tanzu/carvel instead of the deprecated k14/tap to install deps with brew 2022-04-05 16:43:22 +02:00
Mo Khan
c0874706d9 Merge pull request #1106 from enj/enj/i/fips_followup
Add more details to FIPS comments
2022-04-01 13:16:50 -04:00
Monis Khan
07066e020d Explicitly set defaultServing ciphers in FIPS mode
This is a no-op today, but could change in the future when we add
support for FIPS in non-strict mode.

Signed-off-by: Monis Khan <mok@vmware.com>
2022-04-01 10:59:47 -04:00
Monis Khan
3f0753ec5a Remove duplication in secure TLS tests
Signed-off-by: Monis Khan <mok@vmware.com>
2022-04-01 10:56:38 -04:00
Monis Khan
15bc6a4a67 Add more details to FIPS comments
Signed-off-by: Monis Khan <mok@vmware.com>
2022-04-01 10:56:38 -04:00
Mo Khan
ce82d799c9 Run OSSF scorecard on release branches 2022-04-01 10:41:23 -04:00
Mo Khan
a453522d81 Add OSSF Scorecard GitHub Action 2022-04-01 10:30:01 -04:00
Ryan Richard
51c527a965 Change to camel-case for insecureAcceptExternalUnencryptedHttpRequests
- Use camel-case in the static configmap
- Parse the value into a boolean in the go struct instead of a string
- Add test for when unsupported value is used in the configmap
- Run the config_test.go tests in parallel
- Update some paragraphs in configure-supervisor.md for clarity
2022-03-31 16:23:45 -07:00
Ryan Richard
ae7aac020a Merge branch 'main' into disable_http 2022-03-30 11:30:32 -07:00
Mo Khan
17e8faa0fe Have dependabot keep the FIPS dockerfile updated 2022-03-30 13:55:19 -04:00
Mo Khan
6639ce2a1f Merge pull request #1061 from vmware-tanzu/fips-boringcrypto
FIPs compatibility
2022-03-30 13:43:23 -04:00
Margo Crawford
53597bb824 Introduce FIPS compatibility
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-03-29 16:58:41 -07:00
Ryan Richard
0e54ba1a20 Slightly fancier way to prevent old values.yaml names from being used 2022-03-29 14:24:40 -07:00
Ryan Richard
b07a4131e5 Merge branch 'main' into disable_http 2022-03-29 12:47:53 -07:00
Mo Khan
2cffea5880 Merge pull request #1099 from vmware-tanzu/remove_supervisorhttpaddress_var
Remove unused env.SupervisorHTTPAddress integration test var
2022-03-29 13:36:00 -04:00
Ryan Richard
5f34efc0b7 Empty commit to trigger CI 2022-03-29 09:39:18 -07:00
Ryan Richard
cf471d6422 Remove unused env.SupervisorHTTPAddress integration test var 2022-03-29 09:13:44 -07:00
Ryan Richard
3592f80457 Merge branch 'main' into disable_http 2022-03-28 17:03:59 -07:00
Ryan Richard
488f08dd6e Provide a way to override the new HTTP loopback-only validation
Add new deprecated_insecure_accept_external_unencrypted_http_requests
value in values.yaml. Allow it to be a boolean or a string to make it
easier to use (both --data-value and --data-value-yaml will work).

Also:
- Consider "ip6-localhost" and "ip6-loopback" to be loopback addresses
  for the validation
- Remove unused env.SupervisorHTTPAddress var
- Deprecate the `service_http_*` values in values.yaml by renaming them
  and causing a ytt render error when the old names are used
2022-03-28 17:03:23 -07:00
Mo Khan
cd25cb89c4 Merge pull request #1093 from enj/enj/d/ws1
Add Workspace ONE Access docs
2022-03-24 20:24:29 -04:00
Monis Khan
57fb085bef Add Workspace ONE Access docs
Signed-off-by: Monis Khan <mok@vmware.com>
2022-03-24 20:17:54 -04:00
Ryan Richard
8d12c1b674 HTTP listener: default disabled and may only bind to loopback interfaces 2022-03-24 15:46:10 -07:00
Mo Khan
9c5adad062 Merge pull request #1092 from vmware-tanzu/remove_oryx_direct_dep
Remove direct dependency on ory/x
2022-03-24 15:16:34 -04:00
Mo Khan
4649b8e0e4 Merge pull request #1085 from pnbrown/community-page-update
Update _index.html
2022-03-24 14:02:51 -04:00
Ryan Richard
48c5a625a5 Remove our direct dependency on ory/x
ory/x has new releases very often, sometimes multiple times per week,
causing a lot of noise from dependabot. We were barely using it
directly, so replace our direct usages with equivalent code.
2022-03-24 10:24:54 -07:00
Ryan Richard
42bd385cbd Merge pull request #1088 from vmware-tanzu/pty_int_test_flakes
WIP: Try to fix recent integration test flakes
2022-03-22 18:10:08 -07:00
Ryan Richard
bedf4e5a39 Try to avoid getting a second username prompt in a test in e2e_test.go 2022-03-22 14:23:50 -07:00
Ryan Richard
2715741c2c Increase a test timeout in e2e_test.go 2022-03-22 12:13:10 -07:00
Ryan Richard
d20b2056f2 Merge branch 'main' into pty_int_test_flakes 2022-03-22 11:14:19 -07:00
Margo Crawford
a9b054e2f4 Merge pull request #1087 from vmware-tanzu/update-install-linter-1.45.0
Update install-linter.sh to use v1.45.0
2022-03-22 10:57:34 -07:00
Margo Crawford
051a228a8c Update install-linter.sh to use v1.45.0
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-03-22 10:29:08 -07:00
Ryan Richard
d162e294ed Split up the context timeouts per test in e2e_test.go 2022-03-22 10:17:45 -07:00
Margo Crawford
636d2014a7 Merge pull request #1086 from pnbrown/patch-1
Update MAINTAINERS.md
2022-03-21 15:02:05 -07:00
Nigel Brown
f981f63b90 Update MAINTAINERS.md 2022-03-21 13:17:14 -05:00
Nigel Brown
b5be8c6c9b Update _index.html
Add current community meeting info
2022-03-21 13:08:54 -05:00
Ryan Richard
ff4ceb5d0b Merge pull request #1079 from vmware-tanzu/contributor_guide_updates2
Small updates to CONTRIBUTING.md
2022-03-21 10:45:17 -07:00
Ryan Richard
d24f82fff5 Merge branch 'main' into contributor_guide_updates2 2022-03-21 10:45:10 -07:00
Ryan Richard
0ac37fd169 Merge pull request #1059 from vmware-tanzu/2022-readme
Update main README.md for 2022
2022-03-21 10:44:41 -07:00
Ryan Richard
bcfddec0a2 Merge branch 'main' into 2022-readme 2022-03-21 10:44:32 -07:00
Ryan Richard
b1310877d8 Add docs for how to run specific integration test(s) to CONTRIBUTING.md 2022-03-21 09:33:26 -07:00
Ryan Richard
f64779cba7 small updates to CONTRIBUTING.md 2022-03-18 14:27:33 -07:00
anjalitelang
c710cfbc70 Update ROADMAP.md
Changed last updated field for March
2022-03-18 10:12:50 -04:00
anjalitelang
3052763020 Update ROADMAP.md
Updated roadmap with current priorities
2022-03-17 09:36:24 -04:00
Ryan Richard
8b80a01d0a Merge pull request #1065 from vmware-tanzu/kind-update
Use kubeadm.k8s.io/v1beta3 in addition to v1beta2 for kind config
2022-03-16 09:18:40 -07:00
Ryan Richard
e465056943 Use both kubeadm.k8s.io/v1beta2 and v1beta3 to allow old versions of K8s
You can use an older version of K8s on your development workstation
by temporarily editing kind-up.sh to add the `--image` flag. By defining
both v1beta2 and v1beta3 you should continue to be able to use old
versions of K8s in this way with Kind v0.12.0.
2022-03-15 15:09:39 -07:00
Ryan Richard
16c4c67af1 Use kubeadm.k8s.io/v1beta3 instead of v1beta2 for kind config
It appears that kind completely ignores kubeadm.k8s.io/v1beta2 config
starting in Kind v0.12.0.

You can observe the config being ignored or used by adding `-v 10` to
the command-line arguments of `kind create cluster` in kind-up.sh.
2022-03-15 09:37:27 -07:00
Mo Khan
c5dce9cab4 Merge pull request #1057 from enj/enj/i/turn_off_http
Rework or remove tests that rely on the http port
2022-03-10 20:06:34 -05:00
Monis Khan
8fac6cb9a4 Rework or remove tests that rely on the http port
Signed-off-by: Monis Khan <mok@vmware.com>
2022-03-10 19:43:12 -05:00
Ryan Richard
9805f6d6b2 Update main README.md for 2022 2022-03-10 14:23:27 -08:00
Mo Khan
61c8d54527 Fix typo in concierge deploy step 2022-03-10 09:08:40 -05:00
Ryan Richard
7c1f7447c5 Merge pull request #1054 from vmware-tanzu/update-linter
Update to github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.2
2022-03-08 13:52:14 -08:00
Ryan Richard
1c2dd12f32 Merge branch 'main' into update-linter 2022-03-08 12:57:22 -08:00
Ryan Richard
e312ac6c46 Merge pull request #1053 from vmware-tanzu/upgrade-controllergen
Regenerate code after updating controller-gen to v0.8.0
2022-03-08 12:56:11 -08:00
Ryan Richard
fffcb7f5b4 Update to github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.2
- Two of the linters changed their names
- Updated code and nolint comments to make all linters pass with 1.44.2
- Added a new hack/install-linter.sh script to help developers install
  the expected version of the linter for local development
2022-03-08 12:28:09 -08:00
Ryan Richard
0ec5b31c40 Regenerate code after updating controller-gen to v0.8.0
- Note that v0.8.0 no longer supports the "trivialVersions=true"
  command-line option, so remove that from update-codegen.sh.
  It doesn't seem to impact the output (our generated CRD yaml files).
2022-03-08 11:27:05 -08:00
Mo Khan
93aaa9e509 Merge pull request #1050 from vmware-tanzu/dependabot/docker/golang-1.17.8
Bump golang from 1.17.7 to 1.17.8
2022-03-07 10:41:29 -05:00
dependabot[bot]
8182a233d1 Bump golang from 1.17.7 to 1.17.8
Bumps golang from 1.17.7 to 1.17.8.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 01:20:25 +00:00
Mo Khan
853cc753b8 Merge pull request #1024 from anjaltelang/main
Blog changes for Group refresh
2022-03-04 13:28:18 -05:00
Pinny
cdfb3b75cb Updated versions in docs for v0.15.0 release 2022-03-04 17:36:24 +00:00
Pinny
89e68489ea Updated versions in docs for v0.14.0 release 2022-03-03 21:57:36 +00:00
Mo Khan
eec5f0fa26 Fix v0.15.0 release link 2022-03-03 15:28:01 -05:00
Ryan Richard
7e8eba3244 Update 2022-01-18-idp-refresh-tls-ciphers-for-compliance.md 2022-03-03 12:23:42 -08:00
Margo Crawford
b987783c62 Merge pull request #1047 from vmware-tanzu/docs-k8s-codegen-version
Update docs to reference the latest k8s codegen version
2022-03-03 11:14:33 -08:00
Margo Crawford
b8bdfa1b9a Update docs to reference the latest k8s codegen version
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-03-03 10:36:42 -08:00
Mo Khan
6347d7c0e2 Merge pull request #1044 from vmware-tanzu/upgrade-crd-ref-docs
Regenerate reference docs and escape pipe characters
2022-03-03 13:04:09 -05:00
Anjali Telang
27f04e9ab9 Blog changes for Group refresh
Signed-off-by: Anjali Telang <atelang@vmware.com>
2022-03-03 12:49:01 -05:00
anjalitelang
ab4a66131b Update ROADMAP.md
Updated roadmap for March
2022-03-03 11:51:24 -05:00
Margo Crawford
60d2b852ae Corresponds with making our CI use the head of the master branch of crd-ref-docs
This fixes #906

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-03-02 14:31:58 -08:00
Mo Khan
ec74158ebc Merge pull request #1043 from vmware-tanzu/active-directory-group-change-warning
Add group change warning test for Active Directory
2022-03-02 15:43:59 -05:00
Margo Crawford
f6ad5d5c45 Add group change warning test for Active Directory
Also refactor some of the AD test helper functions

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-03-02 11:54:36 -08:00
Mo Khan
dd4394a0d6 Merge pull request #1042 from enj/enj/i/group_warn_typo
Fix typo in group removed warning
2022-03-02 14:41:22 -05:00
Monis Khan
eae55a8595 Fix typo in group removed warning
Signed-off-by: Monis Khan <mok@vmware.com>
2022-03-02 12:58:30 -05:00
Ryan Richard
541811a7a6 Merge pull request #1028 from jvanzyl/main
Minimal changes to allow an alternate deployment mechanism
2022-03-02 09:23:16 -08:00
Ryan Richard
0a63784ca2 Merge branch 'main' into main 2022-03-02 08:41:06 -08:00
Mo Khan
be2aee957c Bump API docs to 1.23
Seems like this should be automated.
2022-03-02 09:04:41 -05:00
Margo Crawford
9a4a862808 Merge pull request #1039 from vmware-tanzu/group-change-warning
Group change warning
2022-03-01 14:38:35 -08:00
Margo Crawford
609b55a6d7 Pinniped Supervisor should issue a warning when groups change during refresh 2022-03-01 14:01:57 -08:00
Ryan Richard
d1f756c9ab Merge pull request #1040 from vmware-tanzu/codegen-21-22-23
Add generated code for Kube 1.21, 1.22, and 1.23
2022-03-01 12:53:54 -08:00
Ryan Richard
58f790c1c6 generate code for 1.17-1.20 using Go 1.17 2022-03-01 10:39:58 -08:00
Ryan Richard
956d046cf0 Merge branch 'main' into codegen-21-22-23 2022-03-01 10:02:05 -08:00
Ryan Richard
bf7457db59 expose env var for debug level of codegen 2022-03-01 10:01:49 -08:00
Mo Khan
0c866a6f98 Merge pull request #1041 from enj/enj/i/bump_0004
Bump kube to v0.23.4, rest to latest
2022-03-01 12:25:30 -05:00
Monis Khan
8179a7e802 Bump kube to v0.23.4, rest to latest
Signed-off-by: Monis Khan <mok@vmware.com>
2022-03-01 09:25:56 -05:00
Ryan Richard
f501c76acc Add generated code for Kube 1.21, 1.22, and 1.23
Also:
- Make our code generator script work with Go 1.17
- Make our update.sh script work on linux
- Update the patch versions of the old Kube versions that we were using
  to generate code (see kube-versions.txt)
- Use our container images from ghcr instead of
  projects.registry.vmware.com for codegen purposes
- Make it easier to debug in the future by passing "-v" to the Kube
  codegen scripts
- Updated copyright years to make commit checks pass
2022-02-28 17:58:48 -08:00
Mo Khan
04c6b3331b Merge pull request #1031 from vmware-tanzu/tolerate-control-plane
Add toleration for new "control-plane" node label for Concierge deploy
2022-02-26 12:56:14 -05:00
Jason van Zyl
0ea10c77c7 Consolidate declaration of variables 2022-02-25 11:26:53 -05:00
Jason van Zyl
782157e1df Remove debug output 2022-02-25 06:25:20 -05:00
Jason van Zyl
1e3f3555a4 Add line in help output for --alternate-deploy 2022-02-25 06:22:25 -05:00
Ryan Richard
8dc4a890ed Merge branch 'main' into tolerate-control-plane 2022-02-24 10:12:31 -08:00
Mo Khan
619b8c19ad Merge pull request #1032 from vmware-tanzu/increase-e2e-timeout
Increase a test timeout to account for slower test on EKS in CI
2022-02-23 11:36:39 -05:00
Ryan Richard
e1e3342b3d Increase a test timeout to account for slower test on EKS in CI
The test takes longer on EKS because it has to wait about 2 minutes for
the EKS load balancer to be ready during the test.
2022-02-22 11:46:15 -08:00
Ryan Richard
0651b9a912 Add toleration for new "control-plane" node label for Concierge deploy 2022-02-22 11:24:26 -08:00
Jason van Zyl
6491742c3a Minimal changes to allow an alternate deployment mechanism
The purpose of this change is to allow Helm to be used to deploy Pinniped
into the local KinD cluster for the local integration tests. That said,
the change allows any alternate deployment mechanism, I just happen
to be using it with Helm.

All default behavior is preserved. This won't change how anyone uses the
script today, it just allows me not to copy/paste the whole setup for the
integration tests.

Changes:

1) An option called `--alternate-deploy <path-to-deploy-script>` has been
added, that when enabled calls the specified script instead of using ytt
and kapp. The alternate deploy script is called with the app to deploy
and the tag of the docker image to use. We set the default value of
the alternate_deploy variable to undefined, and there is a check that
tests if the alternate deploy is defined. For the superivsor it looks
like this:

```
if [ "$alternate_deploy" != "undefined" ]; then
  log_note "The Pinniped Supervisor will be deployed with $alternate_deploy pinniped-supervisor $tag..."
  $alternate_deploy pinniped-supervisor $tag
else
  normal ytt/kapp deploy
fi
```

2) Additional log_note entries have been added to enumerate all values passed
into the ytt/kapp deploy. Used while I was trying to reach parity in the integration
tests, but I think they are useful for debugging.

3) The manifests produced by ytt and written to /tmp are now named individually.
This is so an easy comparison can be made between manifests produced by a ytt/kapp
run of integration tests and manifests produced by helm run of the integration tests.
If something is not working I have been comparing the manifests after these runs to
find differences.
2022-02-20 10:15:29 -05:00
Margo Crawford
339bb84765 Merge pull request #982 from vmware-tanzu/upstream-ldap-group-refresh-skip
Only run group refresh when the skipGroupRefresh boolean isn't set
2022-02-17 13:59:07 -08:00
Margo Crawford
b9582f864e Update comment for skipGroupRefresh 2022-02-17 12:50:28 -08:00
Margo Crawford
e2c6dcd6e6 Add integration test 2022-02-17 12:50:28 -08:00
Margo Crawford
fdac4d16f0 Only run group refresh when the skipGroupRefresh boolean isn't set
for AD and LDAP
2022-02-17 12:50:28 -08:00
Ryan Richard
67085e9dbb Merge pull request #973 from vmware-tanzu/proposal_process
Introduce a proposal process in the governance doc
2022-02-17 12:49:23 -08:00
Ryan Richard
dec89b5378 Merge branch 'main' into proposal_process 2022-02-17 12:48:58 -08:00
Margo Crawford
c7aaa69b4b Merge pull request #975 from vmware-tanzu/upstream-ldap-group-refresh
Inline upstream ldap group refresh
2022-02-17 12:47:22 -08:00
Margo Crawford
662f2cef9c Integration test for updating group search base
Also a small change to a comment
2022-02-17 11:29:59 -08:00
Margo Crawford
ca523b1f20 Always update groups even if it's nil
Also de-dup groups and various small formatting changes
2022-02-17 11:29:59 -08:00
Margo Crawford
c28602f275 Add unit tests for group parsing overrides 2022-02-17 11:29:59 -08:00
Margo Crawford
dd11c02b6a Add back entries because I think it's actually necessary 2022-02-17 11:29:59 -08:00
Margo Crawford
f890fad90c Rename a function, sort strings inside searchGroupsForUserDN 2022-02-17 11:29:59 -08:00
Margo Crawford
cd7538861a Add integration test where we don't get groups back 2022-02-17 11:29:59 -08:00
Margo Crawford
013b521838 Upstream ldap group refresh:
- Doing it inline on the refresh request
2022-02-17 11:29:59 -08:00
Ryan Richard
9526009f74 Fix spelling typo in proposals/README.md
Co-authored-by: Mo Khan <i@monis.app>
2022-02-17 10:59:23 -08:00
Ryan Richard
2f7713889a Remove an unnecessary step from the proposal lifecycle 2022-02-17 10:56:13 -08:00
Ryan Richard
60cc61cdaa Add the concept of a tracking issue to the proposal process 2022-02-17 10:42:10 -08:00
Ryan Richard
bc6827b2e1 Auto-format GOVERNANCE.md 2022-02-17 10:08:37 -08:00
Ryan Richard
9dbf7d6bf5 Merge branch 'main' into proposal_process 2022-02-17 10:07:37 -08:00
Ryan Richard
46dd73de70 Merge pull request #1006 from vmware-tanzu/fix_int_test_macos
Fix int test that was failing on MacOS, and some small doc changes
2022-02-16 12:56:30 -08:00
Ryan Richard
9a6136761d Merge branch 'main' into fix_int_test_macos 2022-02-16 12:01:47 -08:00
Ryan Richard
eaa3e9f612 Merge pull request #1013 from vmware-tanzu/cli_require_https_issuers
CLI requires HTTPS OIDC issuer, authorize, and token URLS
2022-02-16 11:22:26 -08:00
Ryan Richard
c09daa8513 Merge branch 'main' into fix_int_test_macos 2022-02-16 11:09:11 -08:00
Ryan Richard
e5a60a8c84 Update a comment 2022-02-16 11:09:05 -08:00
Ryan Richard
79467318f4 CLI requires HTTPS OIDC issuer, authorize, and token URLS 2022-02-16 10:41:51 -08:00
Mo Khan
cc50fc980c Merge pull request #1009 from enj/enj/i/chrome_beta_build_5
Enforce naming convention for browser based tests
2022-02-16 11:21:27 -05:00
Monis Khan
b8202d89d9 Enforce naming convention for browser based tests
This allows us to target browser based tests with the regex:

go test -v -race -count 1 -timeout 0 ./test/integration -run '/_Browser'

New tests that call browsertest.Open will automatically be forced to
follow this convention.

Signed-off-by: Monis Khan <mok@vmware.com>
2022-02-16 09:20:28 -05:00
Ryan Richard
f1f42052fb Merge branch 'main' into fix_int_test_macos 2022-02-15 16:45:59 -08:00
Ryan Richard
3f4e6cf367 Fix a typo in CONTRIBUTING.md from a recent commit: comma in wrong place 2022-02-15 16:45:49 -08:00
Ryan Richard
1aa17bd84d Check for darwin before relaxing stderr vs stdout assertion in e2e test 2022-02-15 13:45:04 -08:00
Mo Khan
c4ae5cfebb Merge pull request #1003 from enj/enj/d/dex_password
Update dex docs regarding password grant
2022-02-15 15:45:54 -05:00
Ryan Richard
b0c36c6633 Fix int test that was failing on MacOS, and some small doc changes 2022-02-15 11:19:49 -08:00
Ryan Richard
461c0ae56c Merge branch 'main' into proposal_process 2022-02-15 10:15:46 -08:00
Ryan Richard
42db13d044 Move the proposal process doc to the proposals directory's README.md 2022-02-15 10:14:59 -08:00
Ryan Richard
82cdc870a6 Merge pull request #996 from vmware-tanzu/gke_tutorial
Replace old tutorial with a new Supervisor + Concierge tutorial which uses GKE to demonstrate both
2022-02-15 09:37:29 -08:00
Ryan Richard
0175445ece Merge branch 'main' into gke_tutorial 2022-02-15 09:22:52 -08:00
Ryan Richard
f728ea743f Add --ignore-not-found to delete Supervisor app command 2022-02-15 09:04:47 -08:00
Ryan Richard
230e563ab7 Another draft of the new tutorial guide 2022-02-14 17:23:57 -08:00
Ryan Richard
26dcbd9ec1 Try using ``markdown instead of ``md for coloring 2022-02-14 13:45:30 -08:00
Monis Khan
a21a5bca1e Update dex docs regarding password grant
Signed-off-by: Monis Khan <mok@vmware.com>
2022-02-13 12:48:20 -05:00
Ryan Richard
05ec8cba8c Add a new subheading to the tutorial doc 2022-02-11 17:16:40 -08:00
Ryan Richard
e57a1a7891 Overwrite the old Supervisor+Concierge tutorial with the new one
And make it easier for web site readers to find by adding prominent
links to it from several places.
2022-02-11 17:03:13 -08:00
Mo Khan
11d9b4f21a Merge pull request #999 from vmware-tanzu/dependabot/docker/golang-1.17.7
Bump golang from 1.17.6 to 1.17.7
2022-02-10 21:55:27 -05:00
dependabot[bot]
93e4d5d956 Bump golang from 1.17.6 to 1.17.7
Bumps golang from 1.17.6 to 1.17.7.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-11 01:13:54 +00:00
Mo Khan
390af8f476 Merge pull request #997 from enj/enj/i/bump_0003
Bump Kube to v0.23.3 and rest to latest
2022-02-10 18:19:54 -05:00
Monis Khan
49e88dd74a Change some single quotes to double quotes in minified JS
Signed-off-by: Monis Khan <mok@vmware.com>
2022-02-10 16:15:26 -05:00
Monis Khan
4be2dd3b2a Bump Kube to v0.23.3 and rest to latest
Signed-off-by: Monis Khan <mok@vmware.com>
2022-02-10 16:15:26 -05:00
Mo Khan
2c0b5b733b Bump site latest_version to v0.14.0 2022-02-10 16:13:39 -05:00
Ryan Richard
c56ef5c40c First draft of a Supervisor on GKE + Concierge on GKE tutorial
Including ingress, DNS, cert-manager + letsencrypt for TLS certs,
Okta, multiple workload clusters, etc.
2022-02-09 17:13:40 -08:00
Mo Khan
e1080e1225 Allow dependabot to open more pull requests 2022-02-09 16:15:57 -05:00
Mo Khan
59be3008fd Merge pull request #985 from microwavables/update-docs
updated search functionality of docs on site
2022-02-09 12:01:59 -05:00
Nanci Lancaster
d728c89ba6 updated search functionality of docs on site
Signed-off-by: Nanci Lancaster <nancil@vmware.com>
2022-02-09 11:01:37 -05:00
Mo Khan
863aadd9ea Merge pull request #989 from vmware-tanzu/chrome_cors2
Followup for CORS request handling to CLI's localhost listener
2022-02-09 10:27:00 -05:00
Ryan Richard
5d79d4b9dc Fix form_post.js mistake from recent commit; Better CORS on callback 2022-02-08 17:30:48 -08:00
Ryan Richard
f6f188565b Merge pull request #987 from vmware-tanzu/chrome_cors
Add CORS request handling to CLI's localhost listener
2022-02-08 14:31:45 -08:00
Mo Khan
29368e8242 Make the linter happy 2022-02-08 16:31:04 -05:00
Ryan Richard
cd825c5e51 Use "-v6" for kubectl for an e2e test so we can get more failure output 2022-02-08 13:00:49 -08:00
Mo Khan
874b567974 Merge pull request #988 from enj/enj/t/e2e_hung
e2e_test: handle hung go routines and readers
2022-02-08 12:57:54 -05:00
Monis Khan
8ee461ae8a e2e_test: handle hung go routines and readers
Signed-off-by: Monis Khan <mok@vmware.com>
2022-02-08 11:40:10 -05:00
Mo Khan
1388183bf1 TestE2EFullIntegration: reduce timeout
This causes the test to timeout before concourse terminates the entire test run.
2022-02-07 20:53:03 -05:00
Ryan Richard
f1962ccf86 Merge branch 'main' into chrome_cors 2022-02-07 16:35:44 -08:00
Ryan Richard
0431a072ae Remove an unnecessary nolint comment 2022-02-07 16:26:39 -08:00
Ryan Richard
6781bfd7d8 Fix JS bug: form post UI shows manual copy/paste UI upon failed callback
When the POST to the CLI's localhost callback endpoint results in a
non-2XX status code, then treat that as a failed login attempt and
automatically show the manual copy/paste UI.
2022-02-07 16:21:23 -08:00
Ryan Richard
aa56f174db Capture and print the full kubectl output in an e2e test upon failure 2022-02-07 16:17:38 -08:00
Ryan Richard
3c7e387137 Keep the CLI localhost listener running after requests with wrong verb
Just in case some future browser change sends some new kind of request
to our CLI, just ignore them by returning StatusMethodNotAllowed and
continuing to listen.
2022-02-07 13:32:31 -08:00
Ryan Richard
2b93fdf357 Fix a bug in the e2e tests
When the test was going to fail, a goroutine would accidentally block
on writing to an unbuffered channel, and the spawnTestGoroutine helper
would wait for that goroutine to end on cleanup, causing the test to
hang forever while it was trying to fail.
2022-02-07 11:57:54 -08:00
Ryan Richard
7b97f1533e Add CORS request handling to CLI's localhost listener
This is to support the new changes in Google Chrome v98 which now
performs CORS preflight requests for the Javascript form submission
on the Supervisor's login page, even though the form is being submitted
to a localhost listener.
2022-02-04 16:57:37 -08:00
anjalitelang
7c246784dc Update ROADMAP.md
Updated roadmap to reflect changes planned for v0.14 release and beyond.
2022-02-03 08:57:47 -05:00
anjalitelang
0dd3b40694 Update ROADMAP.md 2022-01-31 12:13:18 -05:00
Ryan Richard
a2a05548f9 More updates to draft proposal process based on feedback 2022-01-27 14:56:10 -08:00
Ryan Richard
d4725423a9 More updates to draft proposal process based on feedback 2022-01-27 14:51:52 -08:00
Ryan Richard
e9e56689cf Update draft proposal process based on feedback 2022-01-25 11:22:19 -08:00
Ryan Richard
31bd50c011 first draft of proposal process 2022-01-24 15:17:09 -08:00
Margo Crawford
3b1153cd91 Update latest version to v0.13.0 2022-01-21 15:19:40 -08:00
anjalitelang
6590230bcd Merge pull request #954 from anjaltelang/main
Blog for v0.13.0
2022-01-21 15:17:18 -08:00
Pinny
4f06cd3c2e Update CLI docs for v0.13.0 release 2022-01-21 23:12:12 +00:00
Margo Crawford
dea9bf9b90 Merge pull request #970 from vmware-tanzu/kubectl-apply-resources
When instructing users how to install the concierge with kubectl apply,
2022-01-21 13:36:52 -08:00
Margo Crawford
726e88ea03 When instructing users how to install the concierge with kubectl apply,
reccommend using install-pinniped-concierge-crds.yaml, then
install-pinniped-concierge-resources.yaml.

Previously we recommended install-pinniped-concierge-crds (a subset),
then install-pinniped-concierge (everything concierge related, including
the crds). This works fine for install, but not uninstall. Instead we
should use a separate yaml file that contains everything in
install-pinniped-concierge but *not* in install-pinniped-concierge-crds.

We have been generating this file in CI since a5ced4286b6febc7474b7adee34eeb1b62ec82b7
but we haven't released since then so we haven't been able to recommend
its use.
2022-01-21 10:26:45 -08:00
Margo Crawford
70c99c6d44 Merge pull request #969 from vmware-tanzu/request-offline-access-in-docs
Request offline_access in the concierge with supervisor demo
2022-01-21 10:24:04 -08:00
Margo Crawford
62a8967db1 Request offline_access in the concierge with supervisor demo
It's a generic config and not OIDC provider specific
but since most providers require it it seems like the
best default.
2022-01-21 09:58:04 -08:00
Mo Khan
3fc73c21d2 Merge pull request #968 from enj/enj/i/bump_0002
Bump to Kube v0.23.2
2022-01-21 12:16:49 -05:00
Monis Khan
d55ae3f8bb Bump all deps to latest
Signed-off-by: Monis Khan <mok@vmware.com>
2022-01-21 11:25:56 -05:00
Ryan Richard
c8d4b73f94 Merge pull request #967 from vmware-tanzu/refresh-token-test-warnings
Fix new refresh token grace period test to have warnings
2022-01-21 04:20:46 -08:00
Margo Crawford
b30dad72ed Fix new refresh token grace period test to have warnings 2022-01-20 14:54:59 -08:00
Margo Crawford
31cdd808ac Merge pull request #951 from vmware-tanzu/short-session-warning
Supervisor should emit a warning when access token lifetime is too short
2022-01-20 14:44:32 -08:00
Ryan Richard
e85a6c09f6 Merge pull request #953 from vmware-tanzu/dependabot/go_modules/github.com/tdewolff/minify/v2-2.9.29
Bump github.com/tdewolff/minify/v2 from 2.9.26 to 2.9.29
2022-01-20 14:16:05 -08:00
Mo Khan
025ef6311b Merge pull request #943 from vmware-tanzu/dependabot/go_modules/github.com/ory/fosite-0.42.0
Bump github.com/ory/fosite from 0.41.0 to 0.42.0
2022-01-20 17:03:52 -05:00
Margo Crawford
842ef38868 Ensure warning is on stderr and not stdout. 2022-01-20 13:48:50 -08:00
Margo Crawford
acd23c4c37 Separate test for access token refresh 2022-01-20 13:48:50 -08:00
Margo Crawford
38d184fe81 Integration test + making sure we get the session correctly in token handler 2022-01-20 13:48:50 -08:00
Margo Crawford
b0ea7063c7 Supervisor should emit a warning when access token lifetime is too short 2022-01-20 13:48:50 -08:00
Ryan Richard
fe819e3512 Empty commit to trigger CI 2022-01-20 13:37:15 -08:00
Ryan Richard
42ca31055a Empty commit to trigger CI 2022-01-20 13:25:29 -08:00
Ryan Richard
652797ba0b Merge branch 'main' into dependabot/go_modules/github.com/tdewolff/minify/v2-2.9.29 2022-01-20 12:23:02 -08:00
Ryan Richard
89c40259f3 Use latest github.com/ory/x v0.0.336 2022-01-20 12:21:19 -08:00
Ryan Richard
520fcf195a Merge branch 'main' into dependabot/go_modules/github.com/ory/fosite-0.42.0 2022-01-20 12:16:54 -08:00
Ryan Richard
284ce00aef Merge pull request #957 from vmware-tanzu/dependabot/go_modules/github.com/ory/x-0.0.334
Bump github.com/ory/x from 0.0.331 to 0.0.334
2022-01-20 12:10:57 -08:00
Ryan Richard
db789dc2bf Merge branch 'main' into dependabot/go_modules/github.com/tdewolff/minify/v2-2.9.29 2022-01-20 12:10:24 -08:00
Ryan Richard
6ddc953989 Merge branch 'main' into dependabot/go_modules/github.com/ory/fosite-0.42.0 2022-01-20 12:10:01 -08:00
Ryan Richard
1f21e30bb2 Merge pull request #948 from vmware-tanzu/upstream-oidc-refresh-groups
Update group memberships during refresh for upstream OIDC providers
2022-01-20 12:07:42 -08:00
Margo Crawford
6c923d3bc6 Merge pull request #956 from vmware-tanzu/fix-scopes-access-token-refresh-test
Keep all scopes except offline_access in access token refresh integration test
2022-01-19 16:19:13 -08:00
dependabot[bot]
cd3d1333de Bump github.com/ory/x from 0.0.331 to 0.0.334
Bumps [github.com/ory/x](https://github.com/ory/x) from 0.0.331 to 0.0.334.
- [Release notes](https://github.com/ory/x/releases)
- [Commits](https://github.com/ory/x/compare/v0.0.331...v0.0.334)

---
updated-dependencies:
- dependency-name: github.com/ory/x
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-19 22:07:18 +00:00
Ryan Richard
dff53b8144 Changes for Fosite's new RevokeRefreshTokenMaybeGracePeriod() interface
Fosite v0.42.0 introduced a new RevokeRefreshTokenMaybeGracePeriod()
interface function. Updated our code to support this change. We didn't
support grace periods on refresh tokens before, so implemented it by
making the new RevokeRefreshTokenMaybeGracePeriod() method just call
the old RevokeRefreshToken() method, therefore keeping our old behavior.
2022-01-19 13:57:01 -08:00
Margo Crawford
513c943e87 Keep all scopes except offline_access in integration test 2022-01-19 13:29:26 -08:00
Ryan Richard
3b1cc30e8d Update unit test to match new JS minify output after minify upgrade 2022-01-19 13:29:07 -08:00
Ryan Richard
a4ca44ca14 Improve error handling when upstream groups is invalid during refresh 2022-01-19 12:57:47 -08:00
dependabot[bot]
4ce2f9db50 Bump github.com/tdewolff/minify/v2 from 2.9.26 to 2.9.29
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.26 to 2.9.29.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.26...v2.9.29)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-19 01:05:43 +00:00
Ryan Richard
78bdb1928a Merge branch 'main' into upstream-oidc-refresh-groups 2022-01-18 16:03:14 -08:00
dependabot[bot]
b2bdf01152 Bump github.com/ory/fosite from 0.41.0 to 0.42.0
Bumps [github.com/ory/fosite](https://github.com/ory/fosite) from 0.41.0 to 0.42.0.
- [Release notes](https://github.com/ory/fosite/releases)
- [Changelog](https://github.com/ory/fosite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ory/fosite/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: github.com/ory/fosite
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-18 23:53:34 +00:00
Mo Khan
956f6f1eab Merge pull request #945 from enj/enj/i/supervisor_ports
Allow configuration of supervisor endpoints
2022-01-18 18:52:32 -05:00
Monis Khan
1e1789f6d1 Allow configuration of supervisor endpoints
This change allows configuration of the http and https listeners
used by the supervisor.

TCP (IPv4 and IPv6 with any interface and port) and Unix domain
socket based listeners are supported.  Listeners may also be
disabled.

Binding the http listener to TCP addresses other than 127.0.0.1 or
::1 is deprecated.

The deployment now uses https health checks.  The supervisor is
always able to complete a TLS connection with the use of a bootstrap
certificate that is signed by an in-memory certificate authority.

To support sidecar containers used by service meshes, Unix domain
socket based listeners include ACLs that allow writes to the socket
file from any runAsUser specified in the pod's containers.

Signed-off-by: Monis Khan <mok@vmware.com>
2022-01-18 17:43:45 -05:00
Ryan Richard
70bd831099 Merge branch 'main' into upstream-oidc-refresh-groups 2022-01-18 14:36:18 -08:00
Ryan Richard
01a7978387 Merge pull request #940 from vmware-tanzu/ldap_and_activedirectory_status_conditions_bug
Fix bug where LDAP or AD status conditions were not updated correctly
2022-01-18 14:35:49 -08:00
Ryan Richard
1a2514f417 Merge branch 'main' into ldap_and_activedirectory_status_conditions_bug 2022-01-18 10:09:14 -08:00
Ryan Richard
6143d66504 Increase timeout on linter for when CI gets slow 2022-01-18 10:07:36 -08:00
Ryan Richard
1602fca5ed Increase timeout on linter for when CI gets slow 2022-01-18 10:06:53 -08:00
anjalitelang
ebcf71c30c Update ROADMAP.md
Proposed changes based on multiple tracks of work- Compliance, IDP features
2022-01-18 10:34:09 -05:00
Ryan Richard
88f3b29515 Merge branch 'main' into upstream-oidc-refresh-groups 2022-01-14 16:51:12 -08:00
Ryan Richard
75e4093067 Merge branch 'main' into ldap_and_activedirectory_status_conditions_bug 2022-01-14 16:50:34 -08:00
Ryan Richard
619b0ba052 Merge pull request #904 from vmware-tanzu/upstream_access_revocation_during_gc
Revoke upstream OIDC access tokens during downstream session garbage collection
2022-01-14 16:45:29 -08:00
Ryan Richard
548977f579 Update group memberships during refresh for upstream OIDC providers
Update the user's group memberships when possible. Note that we won't
always have enough information to be able to update it (see code
comments).
2022-01-14 16:38:21 -08:00
Ryan Richard
7551af3eb8 Fix code that did not auto-merge correctly in previous merge from main 2022-01-14 10:59:39 -08:00
Ryan Richard
814399324f Merge branch 'main' into upstream_access_revocation_during_gc 2022-01-14 10:49:22 -08:00
Margo Crawford
50e4871d65 Merge pull request #944 from vmware-tanzu/refresh-with-no-refresh-token
Access Token based OIDC refresh by checking the UserInfo endpoint
2022-01-14 10:23:41 -08:00
Ryan Richard
db0a765b98 Merge branch 'main' into ldap_and_activedirectory_status_conditions_bug 2022-01-14 10:06:16 -08:00
Ryan Richard
092a80f849 Refactor some variable names and update one comment
Change variable names to match previously renamed interface name.
2022-01-14 10:06:00 -08:00
Margo Crawford
5b161be334 Refactored oidcUpstreamRefresh
Various style changes, updated some comments and variable names and
extracted a helper function for validation.
2022-01-12 18:05:22 -08:00
Margo Crawford
62be761ef1 Perform access token based refresh by fetching the userinfo 2022-01-12 18:05:10 -08:00
Ryan Richard
651d392b00 Refuse logins when no upstream refresh token and no userinfo endpoint
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-01-12 18:03:25 -08:00
Margo Crawford
6f3977de9d Store access token when refresh not available for authcode flow.
Also refactor oidc downstreamsessiondata code to be shared between
callback handler and auth handler.

Signed-off-by: Ryan Richard <richardry@vmware.com>
2022-01-12 18:03:25 -08:00
Ryan Richard
91924ec685 Revert adding allowAccessTokenBasedRefresh flag to OIDCIdentityProvider
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-01-12 18:03:25 -08:00
Margo Crawford
683a2c5b23 WIP adding access token to storage upon login 2022-01-12 18:03:25 -08:00
Ryan Richard
1f146f905a Add struct field for storing upstream access token in downstream session 2022-01-12 18:03:25 -08:00
Mo Khan
82f54b5556 Merge pull request #917 from vmware-tanzu/oidc-refresh-user-info-checks
OIDC refresh user info checks
2022-01-12 20:27:00 -05:00
Margo Crawford
2b744b2eef Add back comment about deferring validation when id token subject is missing 2022-01-12 11:19:43 -08:00
Ryan Richard
438b58193d Empty commit to trigger CI 2022-01-10 13:47:13 -08:00
Margo Crawford
2958461970 Addressing PR feedback
store issuer and subject in storage for refresh
Clean up some constants

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-01-10 11:03:37 -08:00
Margo Crawford
f2d2144932 rename ValidateToken to ValidateTokenAndMergeWithUserInfo to better reflect what it's doing
Also changed a few comments and small things
2022-01-10 11:03:37 -08:00
Margo Crawford
c9cf13a01f Check for issuer if available
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-01-10 11:03:37 -08:00
Margo Crawford
0cd086cf9c Check username claim is unchanged for oidc.
Also add integration tests for claims changing.
2022-01-10 11:03:37 -08:00
Margo Crawford
b098435290 Refactor validatetoken to handle refresh case without id token
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-01-10 11:03:37 -08:00
Margo Crawford
74b007ff66 Validate that issuer url and urls returned from discovery are https
and that they have no query or fragment

Signed-off-by: Ryan Richard <richardry@vmware.com>
2022-01-10 11:03:37 -08:00
Margo Crawford
ed96b597c7 Check for subject matching with upstream refresh
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2022-01-10 11:03:37 -08:00
Ryan Richard
6b9fc7aa59 Merge branch 'main' into ldap_and_activedirectory_status_conditions_bug 2022-01-10 09:23:09 -08:00
Mo Khan
d438bfbc99 Merge pull request #939 from vmware-tanzu/dependabot/go_modules/github.com/ory/x-0.0.331
Bump github.com/ory/x from 0.0.330 to 0.0.331
2022-01-09 12:04:56 -05:00
Ryan Richard
7f99d78462 Fix bug where LDAP or AD status conditions were not updated correctly
When the LDAP and AD IDP watcher controllers encountered an update error
while trying to update the status conditions of the IDP resources, then
they would drop the computed desired new value of the condition on the
ground. Next time the controller ran it would not try to update the
condition again because it wants to use the cached settings and had
already forgotten the desired new value of the condition computed during
the previous run of the controller. This would leave the outdated value
of the condition on the IDP resource.

This bug would manifest in CI as random failures in which the expected
condition message and the actual condition message would refer to
different versions numbers of the bind secret. The actual condition
message would refer to an older version of the bind secret because the
update failed and then the new desired message got dropped on the
ground.

This commit changes the in-memory caching strategy to also cache the
computed condition messages, allowing the conditions to be updated
on the IDP resource during future calls to Sync() in the case of a
failed update.
2022-01-07 17:19:13 -08:00
dependabot[bot]
a7ff638f4c Bump github.com/ory/x from 0.0.330 to 0.0.331
Bumps [github.com/ory/x](https://github.com/ory/x) from 0.0.330 to 0.0.331.
- [Release notes](https://github.com/ory/x/releases)
- [Commits](https://github.com/ory/x/compare/v0.0.330...v0.0.331)

---
updated-dependencies:
- dependency-name: github.com/ory/x
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-07 13:45:37 +00:00
Mo Khan
287d5094ec Merge pull request #938 from vmware-tanzu/dependabot/docker/golang-1.17.6
Bump golang from 1.17.5 to 1.17.6
2022-01-07 08:13:16 -05:00
dependabot[bot]
f2b4d667d1 Bump golang from 1.17.5 to 1.17.6
Bumps golang from 1.17.5 to 1.17.6.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-07 01:04:10 +00:00
Mo Khan
fff27a4270 Merge pull request #935 from enj/enj/i/bump_0001
Bump all deps to latest
2022-01-03 19:48:08 -05:00
Monis Khan
f90f173826 Bump all deps to latest
Ran:

go get -u ./... && go mod tidy

Pinned all go.opentelemetry.io deps to match k/k.
This is needed to make the go get command work.

Signed-off-by: Monis Khan <mok@vmware.com>
2022-01-03 17:48:59 -05:00
Mo Khan
cc88d2a334 Merge pull request #931 from vmware-tanzu/dependabot/docker/distroless/static-80c956f
Bump distroless/static from `bca3c20` to `80c956f`
2022-01-03 10:49:08 -05:00
dependabot[bot]
a0ddf4a945 Bump distroless/static from bca3c20 to 80c956f
Bumps distroless/static from `bca3c20` to `80c956f`.

---
updated-dependencies:
- dependency-name: distroless/static
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-27 01:17:24 +00:00
Mo Khan
05277a5579 Merge pull request #925 from enj/enj/i/flexible_cli_redirect
pinniped CLI: allow all forms of http redirects
2021-12-17 15:51:44 -05:00
Monis Khan
c155c6e629 Clean up nits in AD code
- Make everything private
- Drop unused AuthTime field
- Use %q format string instead of "%s"
- Only rely on GetRawAttributeValues in AttributeUnchangedSinceLogin

Signed-off-by: Monis Khan <mok@vmware.com>
2021-12-17 08:53:44 -05:00
Monis Khan
a6085c9678 Drop unsafe unwrapper for exec.roundTripper
exec.roundTripper now implements utilnet.RoundTripperWrapper so this
unsafe hack is no longer needed.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-12-17 08:28:30 -05:00
Monis Khan
86f2bea8c5 pinniped CLI: allow all forms of http redirects
For password based login on the CLI (i.e. no browser), this change
relaxes the response code check to allow for any redirect code
handled by the Go standard library.  In the future, we can drop the
rewriteStatusSeeOtherToStatusFoundForBrowserless logic from the
server side code.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-12-17 08:28:29 -05:00
Mo Khan
adf04d29f7 Merge pull request #914 from enj/enj/i/bump_0.23.0
Update all deps to latest where possible, bump Kube deps to v0.23.1
2021-12-16 21:45:32 -05:00
Monis Khan
9599ffcfb9 Update all deps to latest where possible, bump Kube deps to v0.23.1
Highlights from this dep bump:

1. Made a copy of the v0.4.0 github.com/go-logr/stdr implementation
   for use in tests.  We must bump this dep as Kube code uses a
   newer version now.  We would have to rewrite hundreds of test log
   assertions without this copy.
2. Use github.com/felixge/httpsnoop to undo the changes made by
   ory/fosite#636 for CLI based login flows.  This is required for
   backwards compatibility with older versions of our CLI.  A
   separate change after this will update the CLI to be more
   flexible (it is purposefully not part of this change to confirm
   that we did not break anything).  For all browser login flows, we
   now redirect using http.StatusSeeOther instead of http.StatusFound.
3. Drop plog.RemoveKlogGlobalFlags as klog no longer mutates global
   process flags
4. Only bump github.com/ory/x to v0.0.297 instead of the latest
   v0.0.321 because v0.0.298+ pulls in a newer version of
   go.opentelemetry.io/otel/semconv which breaks k8s.io/apiserver.
   We should update k8s.io/apiserver to use the newer code.
5. Migrate all code from k8s.io/apimachinery/pkg/util/clock to
   k8s.io/utils/clock and k8s.io/utils/clock/testing
6. Delete testutil.NewDeleteOptionsRecorder and migrate to the new
   kubetesting.NewDeleteActionWithOptions
7. Updated ExpectedAuthorizeCodeSessionJSONFromFuzzing caused by
   fosite's new rotated_secrets OAuth client field.  This new field
   is currently not relevant to us as we have no private clients.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-12-16 21:15:27 -05:00
Mo Khan
69d5951296 Merge pull request #919 from microwavables/updating-community-details
Updated community and resources pages
2021-12-16 17:14:21 -05:00
Mo Khan
b148359337 Merge pull request #918 from vmware-tanzu/replace_reflections
Replace reflections in go.mod
2021-12-16 17:10:28 -05:00
Nanci Lancaster
e31a410096 Updated community and resources pages 2021-12-16 16:02:47 -06:00
Ryan Richard
6bf67f44ef replace reflections in go.mod 2021-12-16 11:15:24 -08:00
Mo Khan
fdc91ec56c Merge pull request #909 from vmware-tanzu/dependabot/docker/golang-1.17.5
Bump golang from 1.17.4 to 1.17.5
2021-12-10 12:41:02 -05:00
dependabot[bot]
884d18bade Bump golang from 1.17.4 to 1.17.5
Bumps golang from 1.17.4 to 1.17.5.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 17:03:50 +00:00
Mo Khan
ca2ee26c86 Merge pull request #884 from vmware-tanzu/upstream-ad-refresh
Upstream active directory refresh checks for password changes, deactivated and locked users
2021-12-09 20:51:46 -05:00
Margo Crawford
59d999956c Move ad specific stuff to controller
also make extra refresh attributes a separate field rather than part of
Extra

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-12-09 16:16:36 -08:00
Margo Crawford
acaad05341 Make pwdLastSet stuff more generic and not require parsing the timestamp
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-12-09 16:16:36 -08:00
Margo Crawford
65f3464995 Fix issue with very high integer value parsing, add unit tests
also add comment about urgent replication
2021-12-09 16:16:36 -08:00
Margo Crawford
ee4f725209 Incorporate PR feedback 2021-12-09 16:16:36 -08:00
Margo Crawford
ef5a04c7ce Check for locked users on ad upstream refresh
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-12-09 16:16:36 -08:00
Margo Crawford
f62e9a2d33 Active directory checks for deactivated user
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-12-09 16:16:36 -08:00
Margo Crawford
da9b4620b3 Active Directory checks whether password has changed recently during
upstream refresh

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-12-09 16:16:35 -08:00
Margo Crawford
8db0203839 Add test for upstream ldap idp not found, wrong idp uid, and malformed
fosite session storage
2021-12-09 16:16:35 -08:00
Ryan Richard
92bd3b49c8 Merge branch 'main' into upstream_access_revocation_during_gc 2021-12-09 14:16:52 -08:00
anjalitelang
4110297a8f Update ROADMAP.md
Updated roadmap to reflect current velocity
2021-12-09 16:59:09 -05:00
Ryan Richard
dbcb213691 Merge branch 'main' into upstream_access_revocation_during_gc 2021-12-08 14:29:59 -08:00
Ryan Richard
f410d2bd00 Add revocation of upstream access tokens to garbage collector
Also refactor the code that decides which types of revocation failures
are worth retrying. Be more selective by only retrying those types of
errors that are likely to be worth retrying.
2021-12-08 14:29:25 -08:00
Mo Khan
7a3b5e3571 Merge pull request #908 from vmware-tanzu/microwavables-main
Added GOVERNANCE.md file to repo
2021-12-08 14:38:21 -05:00
Nanci Lancaster
505bc47ae1 Added GOVERNANCE.md file to repo
Signed-off-by: Nanci Lancaster <nancil@vmware.com>
2021-12-08 14:29:16 -05:00
Ryan Richard
c9c218fdf0 Merge branch 'main' into upstream_access_revocation_during_gc 2021-12-06 14:47:27 -08:00
Ryan Richard
46008a7235 Add struct field for storing upstream access token in downstream session 2021-12-06 14:43:39 -08:00
Mo Khan
2c5b74c960 Merge pull request #905 from vmware-tanzu/dependabot/docker/golang-1.17.4
Bump golang from 1.17.3 to 1.17.4
2021-12-06 15:44:42 -05:00
dependabot[bot]
db68fc3a2b Bump golang from 1.17.3 to 1.17.4
Bumps golang from 1.17.3 to 1.17.4.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-06 01:14:25 +00:00
Ryan Richard
29490ee665 ran go mod tidy 2021-12-03 16:40:01 -08:00
Ryan Richard
b981055d31 Support revocation of access tokens in UpstreamOIDCIdentityProviderI
- Rename the RevokeRefreshToken() function to RevokeToken() and make it
  take the token type (refresh or access) as a new parameter.
- This is a prefactor getting ready to support revocation of upstream
  access tokens in the garbage collection handler.
2021-12-03 13:44:24 -08:00
Ryan Richard
edd3547977 Merge pull request #903 from vmware-tanzu/code-walkthrough-doc
Add first draft of code walk-through doc
2021-12-03 12:19:29 -08:00
Ryan Richard
aa361a70a7 clarifications to code walkthrough doc 2021-12-03 10:50:02 -08:00
Ryan Richard
7b6bdd8129 fix link to blog and add another in doc 2021-12-03 10:32:16 -08:00
Ryan Richard
4aed3385b6 Merge branch 'main' into code-walkthrough-doc 2021-12-03 09:17:35 -08:00
Ryan Richard
2736c3603a fix typo in doc 2021-12-03 09:17:17 -08:00
Ryan Richard
3ea90467b7 add first draft of code walk-through doc 2021-12-02 17:18:50 -08:00
anjalitelang
683027468e Update ROADMAP.md 2021-12-02 12:00:54 -05:00
Mo Khan
269cae3a9f Merge pull request #895 from enj/enj/f/warning_rt
phttp: add generic support for RFC 2616 14.46 warnings headers
2021-11-30 16:15:39 -05:00
Monis Khan
9d4a932656 phttp: add generic support for RFC 2616 14.46 warnings headers
Signed-off-by: Monis Khan <mok@vmware.com>
2021-11-30 15:11:59 -05:00
Mo Khan
1611cf681a Merge pull request #876 from vmware-tanzu/upstream_refresh_revocation_during_gc
Revoke upstream OIDC refresh tokens during downstream session garbage collection
2021-11-23 20:15:37 -05:00
Mo Khan
78474cfae9 Merge branch 'main' into upstream_refresh_revocation_during_gc 2021-11-23 19:29:13 -05:00
Mo Khan
aaf847040f Merge pull request #893 from vmware-tanzu/fix_unit_test
Attempt to fix a unit test that always failed on my laptop
2021-11-23 19:25:16 -05:00
Ryan Richard
e44540043d Attempt to fix a unit test that always failed on my laptop
Try to make the GCP plugin config less sensitive to the setup of the
computer on which it runs.
2021-11-23 15:47:19 -08:00
Ryan Richard
69be273e01 Merge branch 'main' into upstream_refresh_revocation_during_gc 2021-11-23 14:55:44 -08:00
Mo Khan
5a1de2f54c Merge pull request #888 from vmware-tanzu/customize_ports
Make Concierge server port numbers configurable
2021-11-23 17:51:04 -05:00
Ryan Richard
91eed1ab24 Merge branch 'main' into upstream_refresh_revocation_during_gc 2021-11-23 12:11:39 -08:00
Ryan Richard
3ca8c49334 Improve garbage collector log format and some comments 2021-11-23 12:11:17 -08:00
Mo Khan
f28b33bbf0 Merge branch 'main' into customize_ports 2021-11-23 08:30:48 -05:00
Mo Khan
537f85205d Merge pull request #889 from enj/enj/i/strict_tls_acceptance
tls: fix integration tests for long lived environments
2021-11-18 16:37:15 -05:00
Ryan Richard
b8a93b6b90 Merge branch 'main' into customize_ports 2021-11-18 09:31:18 -08:00
Monis Khan
764a1ad7e4 tls: fix integration tests for long lived environments
This change updates the new TLS integration tests to:

1. Only create the supervisor default TLS serving cert if needed
2. Port forward the node port supervisor service since that is
   available in all environments

Signed-off-by: Monis Khan <mok@vmware.com>
2021-11-18 03:55:56 -05:00
Mo Khan
6a68c6532c Merge pull request #873 from enj/enj/i/strict_tls
Force the use of secure TLS config
2021-11-17 19:17:13 -05:00
Ryan Richard
3b3641568a GC retries failed upstream revocations for a while, but not forever 2021-11-17 15:58:44 -08:00
Monis Khan
cd686ffdf3 Force the use of secure TLS config
This change updates the TLS config used by all pinniped components.
There are no configuration knobs associated with this change.  Thus
this change tightens our static defaults.

There are four TLS config levels:

1. Secure (TLS 1.3 only)
2. Default (TLS 1.2+ best ciphers that are well supported)
3. Default LDAP (TLS 1.2+ with less good ciphers)
4. Legacy (currently unused, TLS 1.2+ with all non-broken ciphers)

Highlights per component:

1. pinniped CLI
   - uses "secure" config against KAS
   - uses "default" for all other connections
2. concierge
   - uses "secure" config as an aggregated API server
   - uses "default" config as a impersonation proxy API server
   - uses "secure" config against KAS
   - uses "default" config for JWT authenticater (mostly, see code)
   - no changes to webhook authenticater (see code)
3. supervisor
   - uses "default" config as a server
   - uses "secure" config against KAS
   - uses "default" config against OIDC IDPs
   - uses "default LDAP" config against LDAP IDPs

Signed-off-by: Monis Khan <mok@vmware.com>
2021-11-17 16:55:35 -05:00
Ryan Richard
ca2cc40769 Add impersonationProxyServerPort to the Concierge's static ConfigMap
- Used to determine on which port the impersonation proxy will bind
- Defaults to 8444, which is the old hard-coded port value
- Allow the port number to be configured to any value within the
  range 1024 to 65535
- This commit does not include adding new config knobs to the ytt
  values file, so while it is possible to change this port without
  needing to recompile, it is not convenient
2021-11-17 13:27:59 -08:00
Ryan Richard
2383a88612 Add aggregatedAPIServerPort to the Concierge's static ConfigMap
- Allow the port number to be configured to any value within the
  range 1024 to 65535
- This commit does not include adding new config knobs to the ytt
  values file, so while it is possible to change this port without
  needing to recompile, it is not convenient
2021-11-16 16:43:51 -08:00
Ryan Richard
48518e9513 Add trace logging to help observe upstream OIDC refresh token revocation 2021-11-11 12:24:05 -08:00
Ryan Richard
de79f15068 Merge branch 'main' into upstream_refresh_revocation_during_gc 2021-11-10 15:35:42 -08:00
Ryan Richard
2388e25235 Revoke upstream OIDC refresh tokens during GC 2021-11-10 15:34:19 -08:00
Mo Khan
c570f08b2b Merge pull request #885 from vmware-tanzu/dependabot/docker/golang-1.17.3
Bump golang from 1.17.2 to 1.17.3
2021-11-05 21:45:56 -04:00
dependabot[bot]
2aeb464b43 Bump golang from 1.17.2 to 1.17.3
Bumps golang from 1.17.2 to 1.17.3.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-06 00:55:39 +00:00
Mo Khan
5a3f83f90f Merge pull request #877 from vmware-tanzu/upstream-ldap-refresh
Upstream ldap refresh
2021-11-05 18:08:45 -04:00
Margo Crawford
cb60a44f8a extract ldap refresh search into helper function
also added an integration test for refresh failing after updating the username attribute
2021-11-05 14:22:43 -07:00
Margo Crawford
b5b8cab717 Refactors:
- pull construction of authenticators.Response into searchAndBindUser
- remove information about the identity provider in the error that gets
  returned to users. Put it in debug instead, where it may show up in
  logs.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-11-05 14:22:43 -07:00
Margo Crawford
c84329d7a4 Fix broken ldap_client_test 2021-11-05 14:22:43 -07:00
Margo Crawford
f988879b6e Addressing code review changes
- changed to use custom authenticators.Response rather than the k8s one
  that doesn't include space for a DN
- Added more checking for correct idp type in token handler
- small style changes

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-11-05 14:22:43 -07:00
Margo Crawford
84edfcb541 Refactor out a function, add tests for getting the wrong idp uid 2021-11-05 14:22:43 -07:00
Margo Crawford
722b5dcc1b Test for change to stored username or subject.
All of this is still done staticly.
2021-11-05 14:22:43 -07:00
Margo Crawford
8396937503 Updates to tests and some error assertions 2021-11-05 14:22:43 -07:00
Margo Crawford
2c4dc2951d resolved a couple of testing related todos 2021-11-05 14:22:43 -07:00
Margo Crawford
7a58086040 Check that username and subject remain the same for ldap refresh 2021-11-05 14:22:43 -07:00
Margo Crawford
19281313dd Basic upstream LDAP/AD refresh
This stores the user DN in the session data upon login and checks that
the entry still exists upon refresh. It doesn't check anything
else about the entry yet.
2021-11-05 14:22:42 -07:00
Mo Khan
71f7ea686d Fix typo in community meeting time 2021-11-04 12:02:46 -04:00
Mo Khan
d5d957f6ee Fix CONTRIBUTING zoom link 2021-11-04 11:53:14 -04:00
Mo Khan
e371c34237 Fix README zoom link 2021-11-04 11:52:28 -04:00
Mo Khan
b5be763631 Fix typo in community meeting time 2021-11-04 08:38:33 -04:00
Mo Khan
f03e5f4fef Merge pull request #883 from enj/enj/i/dockerfile_tweaks
Dockerfile: build all files and trim file system paths
2021-11-03 14:45:23 -04:00
Monis Khan
a042f74a88 Dockerfile: build all files and trim file system paths
Use "..." instead of "main.go" as the build target since we may have
extra files in the future.

https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies

-trimpath
	remove all file system paths from the resulting executable.
	Instead of absolute file system paths, the recorded file names
	will begin with either "go" (for the standard library),
	or a module path@version (when using modules),
	or a plain import path (when using GOPATH).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-11-03 10:26:13 -04:00
Mo Khan
aae586b4ef Merge pull request #879 from vmware-tanzu/dependabot/docker/distroless/static-bca3c20
Bump distroless/static from `07869ab` to `bca3c20`
2021-11-02 09:54:48 -04:00
dependabot[bot]
1c3545e234 Bump distroless/static from 07869ab to bca3c20
Bumps distroless/static from `07869ab` to `bca3c20`.

---
updated-dependencies:
- dependency-name: distroless/static
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-28 01:02:33 +00:00
anjalitelang
c494f65b84 Update ROADMAP.md
Updating roadmap to reflect dates when we will have Upstream Refresh released
2021-10-27 10:43:31 -04:00
Margo Crawford
6c47c3327a Add hint to hack/prepare-for-integration-tests.sh
I keep forgetting the name of the --get-active-directory-vars flag.
2021-10-26 16:25:34 -07:00
Mo Khan
3f698d24e5 Merge pull request #878 from enj/enj/i/cli_link
Change default install hint to use get.pinniped.dev/cli
2021-10-26 17:42:53 -04:00
Monis Khan
2ba5d51120 Change default install hint to use get.pinniped.dev/cli
This avoids a hard link against a docs page that may change over
time.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-10-26 17:14:13 -04:00
Margo Crawford
c3060e3474 Merge pull request #872 from anjaltelang/main
Architecture should be on top on the documentation webpage
2021-10-26 13:41:17 -07:00
Anjali Telang
59256264ec Changing the architecture.md weight back to 100
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-10-26 16:34:32 -04:00
Mo Khan
3aa14accd7 Merge pull request #875 from siddhant94/add-install-hint-kubeconfig
Add --install-hint flag to `get kubeconfig` command
2021-10-26 15:38:39 -04:00
Anjali Telang
f93cdcb9c5 Merge remote-tracking branch 'upstream/main' into main 2021-10-26 15:29:56 -04:00
vagrant
1b6b4106db Add --install-hint flag to get kubeconfig command
This populates the installHint attribute in the exec section of the
generated kubeconfig.

For more details, see installHint documentation:
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#configuration

Reviewed-by: Monis Khan <mok@vmware.com>
2021-10-26 14:26:47 -04:00
Mo Khan
f25d2870ce Merge pull request #874 from enj/enj/i/distroless_nonroot
Use 65532 instead of 1001 as non-root user
2021-10-25 16:54:47 -04:00
Monis Khan
7921a58988 Use 65532 instead of 1001 as non-root user
Signed-off-by: Monis Khan <mok@vmware.com>
2021-10-25 16:21:54 -04:00
Mo Khan
7d30bfc22c Start using CodeQL 2021-10-25 16:05:12 -04:00
Mo Khan
bdb199c53a Merge pull request #858 from vmware-tanzu/upstream_refresh
For OIDCIdenitityProviders perform an upstream refresh during downstream refresh
2021-10-25 12:32:35 -04:00
Monis Khan
1e17418585 TestSupervisorUpstreamOIDCDiscovery: include AdditionalAuthorizeParametersValid condition
Signed-off-by: Monis Khan <mok@vmware.com>
2021-10-25 10:21:51 -04:00
Ryan Richard
d0ced1fd74 WIP towards revoking upstream refresh tokens during GC
- Discover the revocation endpoint of the upstream provider in
  oidc_upstream_watcher.go and save it into the cache for future use
  by the garbage collector controller
- Adds RevokeRefreshToken to UpstreamOIDCIdentityProviderI
- Implements the production version of RevokeRefreshToken
- Implements test doubles for RevokeRefreshToken for future use in
  garbage collector's unit tests
- Prefactors the crud and session storage types for future use in the
  garbage collector controller
- See remaining TODOs in garbage_collector.go
2021-10-22 14:32:26 -07:00
Ryan Richard
303b1f07d3 Fix mistake in previous commit 2021-10-22 14:06:31 -07:00
Ryan Richard
e0db59fd09 More small updates based on PR feedback 2021-10-22 10:23:21 -07:00
Ryan Richard
867853016f Merge branch 'main' into upstream_refresh 2021-10-22 09:23:52 -07:00
anjalitelang
be6c335bb8 Update ROADMAP.md
Minor changes
2021-10-21 10:16:54 -04:00
anjalitelang
b3a1dcd634 Update ROADMAP.md
Updated roadmap to reflect current focus of Pinniped project
2021-10-21 10:10:19 -04:00
Ryan Richard
dec43289f6 Lots of small updates based on PR feedback 2021-10-20 15:53:25 -07:00
Ryan Richard
7ec0304472 Add offline_access scope for integration tests when using Dex 2021-10-19 12:25:51 -07:00
Anjali Telang
a22507f835 Architecture should be on top of the docs page
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-10-19 13:46:30 -04:00
Ryan Richard
d3ade82f3f Update docs 2021-10-19 09:48:40 -07:00
Ryan Richard
c43e019d3a Change default of additionalScopes and disallow "hd" in additionalAuthorizeParameters 2021-10-18 16:41:31 -07:00
Ryan Richard
d68bebeb49 Merge branch 'main' into upstream_refresh 2021-10-18 15:35:46 -07:00
Ryan Richard
c51d7c08b9 Add a comment that might be useful some day 2021-10-18 15:35:22 -07:00
Ryan Richard
ddb23bd2ed Add upstream refresh related config to OIDCIdentityProvider CRD
Also update related docs.
2021-10-14 15:49:44 -07:00
Ryan Richard
9e05d175a7 Add integration test: upstream refresh failure during downstream refresh 2021-10-13 15:12:19 -07:00
Ryan Richard
a34dae549b When performing an upstream refresh, use the configured http client
Otherwise, the CA and proxy settings will not be used for the call
to the upstream token endpoint while performing the refresh. This
mistake was exposed by the TestSupervisorLogin integration test, so
it has test coverage.
2021-10-13 14:05:00 -07:00
Ryan Richard
79ca1d7fb0 Perform an upstream refresh during downstream refresh for OIDC upstreams
- If the upstream refresh fails, then fail the downstream refresh
- If the upstream refresh returns an ID token, then validate it (we
  use its claims in the future, but not in this commit)
- If the upstream refresh returns a new refresh token, then save it
  into the user's session in storage
- Pass the provider cache into the token handler so it can use the
  cached providers to perform upstream refreshes
- Handle unexpected errors in the token handler where the user's session
  does not contain the expected data. These should not be possible
  in practice unless someone is manually editing the storage, but
  handle them anyway just to be safe.
- Refactor to share the refresh code between the CLI and the token
  endpoint by moving it into the UpstreamOIDCIdentityProviderI
  interface, since the token endpoint needed it to be part of that
  interface anyway
2021-10-13 12:31:20 -07:00
Mo Khan
bc6da55e96 Merge pull request #860 from vmware-tanzu/dependabot/docker/golang-1.17.2
Bump golang from 1.17.1 to 1.17.2
2021-10-11 13:23:37 -04:00
Margo Crawford
1bd346cbeb Require refresh tokens for upstream OIDC and save more session data
- Requiring refresh tokens to be returned from upstream OIDC idps
- Storing refresh tokens (for oidc) and idp information (for all idps) in custom session data during authentication
- Don't pass access=offline all the time
2021-10-08 15:48:21 -07:00
dependabot[bot]
d1d954bb3b Bump golang from 1.17.1 to 1.17.2
Bumps golang from 1.17.1 to 1.17.2.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-08 01:03:52 +00:00
Margo Crawford
43244b6599 Do not pass through downstream prompt param
- throw an error when prompt=none because the spec says we can't ignore
  it
- ignore the other prompt params

Signed-off-by: Ryan Richard <richardry@vmware.com>
2021-10-06 16:30:30 -07:00
Ryan Richard
c6f1d29538 Use PinnipedSession type instead of fosite's DefaultSesssion type
This will allow us to store custom data inside the fosite session
storage for all downstream OIDC sessions.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-10-06 15:28:13 -07:00
Margo Crawford
a2cafb251a Merge pull request #857 from vmware-tanzu/impersonation-proxy-supported-clusters
Change description of impersonation proxy strategy in supported clusters
2021-10-06 11:40:24 -07:00
Margo Crawford
e0b62a46bb Merge branch 'main' into impersonation-proxy-supported-clusters 2021-10-06 11:36:45 -07:00
Margo Crawford
4aa66b9667 Update site/content/docs/reference/supported-clusters.md
Co-authored-by: Mo Khan <i@monis.app>
2021-10-06 11:23:29 -07:00
Margo Crawford
11797db866 Change description of impersonation proxy strategy in supported clusters.
This was wrong, since you don't need a LoadBalancer to run the
impersonation proxy if you specify spec.service.type = "None" or
"ClusterIP" on the CredentialIssuer.
2021-10-06 11:08:17 -07:00
Mo Khan
c2c966b761 Merge pull request #856 from enj/enj/i/impersonation_proxy_signer_expiration
Do not rotate impersonation proxy signer CA unless necessary
2021-10-06 13:51:52 -04:00
Monis Khan
4bf715758f Do not rotate impersonation proxy signer CA unless necessary
This change fixes a copy paste error that led to the impersonation
proxy signer CA being rotated based on the configuration of the
rotation of the aggregated API serving certificate.  This would lead
to occasional "Unauthorized" flakes in our CI environments that
rotate the serving certificate at a frequent interval.

Updated the certs_expirer controller logs to be more detailed.

Updated CA common names to be more specific (this does not update
any previously generated CAs).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-10-06 12:03:49 -04:00
anjalitelang
946419fc18 Update ROADMAP.md
Updated Roadmap to reflect the work on Supervisor token refresh for OIDC and LDAP/AD. Also changed ordering on Multiple IDP Support as we are seeing more user interest for this feature.
2021-10-05 19:31:33 -04:00
Mo Khan
2b9a869633 Merge pull request #851 from vmware-tanzu/dependabot/docker/distroless/static-7cb5539
Bump distroless/static from `be5d77c` to `7cb5539`
2021-10-01 08:26:29 -04:00
dependabot[bot]
19cecc3235 Bump distroless/static from be5d77c to 7cb5539
Bumps distroless/static from `be5d77c` to `7cb5539`.

---
updated-dependencies:
- dependency-name: distroless/static
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-30 17:09:57 +00:00
Mo Khan
6e41c10584 Merge pull request #854 from enj/enj/i/do_not_truncate_x509
Do not truncate x509 errors
2021-09-30 12:44:19 -04:00
Monis Khan
266d64f7d1 Do not truncate x509 errors
Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-29 09:38:22 -04:00
Mo Khan
725b35196f Merge pull request #853 from enj/enj/i/oidc_log_claims
upstreamoidc: log claim keys at debug level
2021-09-28 20:11:05 -04:00
Monis Khan
03bbc54023 upstreamoidc: log claim keys at debug level
At debug level:

upstreamoidc.go:213] "claims from ID token and userinfo"
providerName="oidc"
keys=[at_hash aud email email_verified exp iat iss sub]

At all level:

upstreamoidc.go:207] "claims from ID token and userinfo"
providerName="oidc"
claims="{\"at_hash\":\"C55S-BgnHTmr2_TNf...hYmVhYWESBWxvY2Fs\"}"

Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-28 12:58:00 -04:00
Mo Khan
ad8610fa03 Merge pull request #852 from enj/enj/i/user_info_cleanup
upstreamoidc: directly detect user info support
2021-09-28 12:56:26 -04:00
Monis Khan
e86488615a upstreamoidc: directly detect user info support
Avoid reliance on an error string from the Core OS OIDC lib.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-28 11:29:38 -04:00
Mo Khan
ee0e2402b1 Merge pull request #845 from vmware-tanzu/crd_printcolumns
Update the AdditionalPrinterColumns of the CRDs, and add a test for it
2021-09-21 23:19:07 -04:00
Ryan Richard
ddf5e566b0 Update a comment 2021-09-21 14:07:08 -07:00
Ryan Richard
bb08e7635b Merge branch 'main' into crd_printcolumns 2021-09-21 14:05:30 -07:00
Mo Khan
3bde085c57 Merge pull request #846 from enj/enj/i/faster_kube_cert
kubecertagent: attempt to load signer as long as agent labels match
2021-09-21 17:03:23 -04:00
Monis Khan
0d6bf9db3e kubecertagent: attempt to load signer as long as agent labels match
This change updates the kube cert agent to a middle ground behavior
that balances leader election gating with how quickly we load the
signer.

If the agent labels have not changed, we will attempt to load the
signer even if we cannot roll out the latest version of the kube
cert agent deployment.

This gives us the best behavior - we do not have controllers
fighting over the state of the deployment and we still get the
signer loaded quickly.

We will have a minute of downtime when the kube cert agent deployment
changes because the new pods will have to wait to become a leader
and for the new deployment to rollout the new pods.  We would need
to have a per pod deployment if we want to avoid that downtime (but
this would come at the cost of startup time and would require
coordination with the kubelet in regards to pod readiness).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-21 16:20:56 -04:00
Ryan Richard
f700246bfa Allow focused integration tests to be run from the GoLand UI again
This was broken recently by the improvements in #808.
2021-09-21 12:04:45 -07:00
Ryan Richard
fca183b203 Show DefaultStrategy as a new printer column for CredentialIssuer 2021-09-21 12:01:30 -07:00
Ryan Richard
1b2a116518 Merge branch 'main' into crd_printcolumns 2021-09-21 09:36:46 -07:00
Mo Khan
9851035e40 Merge pull request #847 from enj/enj/i/tcr_log
token credential request: fix trace log kind
2021-09-21 12:36:16 -04:00
Mo Khan
aa5ff162b4 Merge pull request #849 from enj/enj/i/clock_skew
certauthority: tolerate larger clock skew between API server and pinniped
2021-09-21 12:18:49 -04:00
Mo Khan
933697f045 Merge pull request #848 from vmware-tanzu/tests_use_certificatesv1
Tests use CertificatesV1 when available, otherwise use CertificatesV1beta1
2021-09-21 12:13:22 -04:00
Monis Khan
91c8f747f4 certauthority: tolerate larger clock skew between API server and pinniped
This change updates our certificate code to use the same 5 minute
backdate that is used by the Kubernetes controller manager.  This
helps to account for clock skews between the API servers and the
kubelets that are running the pinniped pods.  While this backdating
reflects a large percentage of the lifetime of our short lived
certificates (100% for the 5 minute client certificates), even a 10
minute irrevocable client certificate is within our limits.  When
we move to the CSR based short lived certificates, they will always
have at least a 15 minute lifetime (5 minute backdating plus 10 minute
minimum valid duration).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-21 09:32:24 -04:00
Ryan Richard
4e98c1bbdb Tests use CertificatesV1 when available, otherwise use CertificatesV1beta1
CertificatesV1beta1 was removed in Kube 1.22, so the tests cannot
blindly rely on it anymore. Use CertificatesV1 whenever the server
reports that is available, and otherwise use the old
CertificatesV1beta1.

Note that CertificatesV1 was introduced in Kube 1.19.
2021-09-20 17:14:58 -07:00
Ryan Richard
0a31f45812 Update the AdditionalPrinterColumns of the CRDs, and add a test for it 2021-09-20 12:47:39 -07:00
Monis Khan
e65817ad5b token credential request: fix trace log kind
Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-20 15:34:05 -04:00
Mo Khan
43ba6ba686 Merge pull request #842 from enj/enj/t/kube_cert_flake
kubecertagent: fix flakey tests
2021-09-16 16:38:07 -04:00
Monis Khan
09467d3e24 kubecertagent: fix flakey tests
This commit makes the following changes to the kube cert agent tests:

1. Informers are synced on start using the controllerinit code
2. Deployment client and informer are synced per controller sync loop
3. Controller sync loop exits after two consistent errors
4. Use assert instead of require to avoid ending the test early

Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-16 14:48:04 -04:00
Ryan Richard
95b9782549 Update config.yaml 2021-09-16 11:43:40 -07:00
anjalitelang
454b792afb Update ROADMAP.md
Changing the roadmap based on current priorities.
2021-09-16 08:46:03 -04:00
Ryan Richard
cb4085bfd9 Merge pull request #840 from vmware-tanzu/mod_tidy
ran `go mod tidy`
2021-09-15 14:47:22 -07:00
Ryan Richard
9b0dc92025 Merge branch 'main' into mod_tidy 2021-09-15 14:47:12 -07:00
Ryan Richard
7859a7b5c2 Merge pull request #839 from vmware-tanzu/deployment_selectors
Improve the selectors of Deployments and Services
2021-09-15 14:46:31 -07:00
Ryan Richard
bdcf468e52 Add log statement for when kube cert agent key has been loaded
Because it makes things easier to debug on a real cluster
2021-09-15 14:02:46 -07:00
Monis Khan
efaca05999 prevent kapp from altering the selector of our services
This makes it so that our service selector will match exactly the
YAML we specify instead of including an extra "kapp.k14s.io/app" key.
This will take us closer to the standard kubectl behavior which is
desirable since we want to avoid future bugs that only manifest when
kapp is not used.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-15 16:08:49 -04:00
Monis Khan
316e6171d4 Enable aggregator routing on kind clusters
This should make it easier for us to to notice if something is wrong
with our service (especially in any future kubectl tests we add).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-09-15 15:09:15 -04:00
Ryan Richard
04544b3d3c Update TestKubeCertAgent to use new "v3" label value 2021-09-15 11:09:07 -07:00
Ryan Richard
85102b0118 ran go mod tidy 2021-09-15 09:21:46 -07:00
Ryan Richard
55de160551 Bump the version number of the kube cert agent label
Not required, but within the spirit of using the version number.
Since the existing kube cert agent deployment will get deleted anyway
during an upgrade, it shouldn't hurt to change the version number.
New installations will get the new version number on the new kube cert
agent deployment.
2021-09-14 15:27:15 -07:00
Ryan Richard
cec9f3c4d7 Improve the selectors of Deployments and Services
Fixes #801. The solution is complicated by the fact that the Selector
field of Deployments is immutable. It would have been easy to just
make the Selectors of the main Concierge Deployment, the Kube cert agent
Deployment, and the various Services use more specific labels, but
that would break upgrades. Instead, we make the Pod template labels and
the Service selectors more specific, because those not immutable, and
then handle the Deployment selectors in a special way.

For the main Concierge and Supervisor Deployments, we cannot change
their selectors, so they remain "app: app_name", and we make other
changes to ensure that only the intended pods are selected. We keep the
original "app" label on those pods and remove the "app" label from the
pods of the Kube cert agent Deployment. By removing it from the Kube
cert agent pods, there is no longer any chance that they will
accidentally get selected by the main Concierge Deployment.

For the Kube cert agent Deployment, we can change the immutable selector
by deleting and recreating the Deployment. The new selector uses only
the unique label that has always been applied to the pods of that
deployment. Upon recreation, these pods no longer have the "app" label,
so they will not be selected by the main Concierge Deployment's
selector.

The selector of all Services have been updated to use new labels to
more specifically target the intended pods. For the Concierge Services,
this will prevent them from accidentally including the Kube cert agent
pods. For the Supervisor Services, we follow the same convention just
to be consistent and to help future-proof the Supervisor app in case it
ever has a second Deployment added to it.

The selector of the auto-created impersonation proxy Service was
also previously using the "app" label. There is no change to this
Service because that label will now select the correct pods, since
the Kube cert agent pods no longer have that label. It would be possible
to update that selector to use the new more specific label, but then we
would need to invent a way to pass that label into the controller, so
it seemed like more work than was justified.
2021-09-14 13:35:10 -07:00
Ryan Richard
16f562e81c Merge pull request #838 from vmware-tanzu/dependabot/docker/golang-1.17.1
Bump golang from 1.17.0 to 1.17.1
2021-09-13 14:30:15 -07:00
dependabot[bot]
92ccc0ec84 Bump golang from 1.17.0 to 1.17.1
Bumps golang from 1.17.0 to 1.17.1.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-13 01:13:32 +00:00
Margo Crawford
74175f2518 Merge pull request #836 from vmware-tanzu/search-base-caching
Make sure search base in the validatedSettings cache is properly updated when the bind secret changes
2021-09-10 11:42:03 -07:00
Margo Crawford
0a1ee9e37c Remove unused functions 2021-09-08 10:34:42 -07:00
Margo Crawford
05f5bac405 ValidatedSettings is all or nothing
If either the search base or the tls settings is invalid, just
recheck everything.
2021-09-07 13:09:35 -07:00
Margo Crawford
0195894a50 Test fix for ldap upstream watcher 2021-09-07 13:09:35 -07:00
Margo Crawford
27c1d2144a Make sure search base in the validatedSettings cache is properly updated when the bind secret changes 2021-09-07 13:09:35 -07:00
Matt Moyer
88aba645b8 Merge pull request #837 from mattmoyer/so-long-and-thanks-for-all-the-fish
So long and thanks for all the fish 🦭
2021-09-03 10:49:35 -07:00
Matt Moyer
402c213183 So long and thanks for all the fish 🦭
Today is my last day working full time on Pinniped (for now). This change removes me from the MAINTAINERS.md and the website.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-09-03 12:38:53 -05:00
Mo Khan
17acc7caa6 Merge pull request #834 from anjaltelang/main
Add release note reference in the v0.11.0 Blog Post
2021-09-02 19:16:08 -04:00
Matt Moyer
6b7a230ca5 Merge pull request #835 from mattmoyer/fix-readonly-fields
Fix broken "read only" fields added in v0.11.0.
2021-09-02 15:23:26 -07:00
Matt Moyer
c7a8c429ed Add a dry-run 'kubectl apply' in prepare-for-integration-tests.sh so we can be sure that our manifests pass API validation.
We had this for some components, but not the ones that mattered the most.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-09-02 16:55:28 -05:00
Matt Moyer
f0a1555aca Fix broken "read only" fields added in v0.11.0.
These fields were changed as a minor hardening attempt when we switched to Distroless, but I bungled the field names and we never noticed because Kapp doesn't apply API validations.

This change fixes the field names so they act as was originally intended. We should also follow up with a change that validates all of our installation manifest in CI.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-09-02 16:12:39 -05:00
Anjali Telang
ccd338fa50 Merge branch 'main' of github.com:anjaltelang/pinniped into main 2021-09-02 14:54:48 -04:00
Anjali Telang
4e7214c6b5 Rephrased again
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-09-02 14:54:14 -04:00
Anjali Telang
2297ee4b81 Merge branch 'main' of github.com:anjaltelang/pinniped into main 2021-09-02 14:52:01 -04:00
Anjali Telang
85daec4748 Rephrased
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-09-02 14:51:36 -04:00
Anjali Telang
cf014656af Add Reference to release notes in the v0.11.0 Blog post
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-09-02 14:44:53 -04:00
Matt Moyer
b3b3c2303f Merge pull request #831 from anjaltelang/main
Add community info and resolve some minor issues
2021-09-02 09:02:24 -07:00
Matt Moyer
0ff66c718b Merge pull request #832 from vmware-tanzu/dependabot/docker/distroless/static-be5d77c
Bump distroless/static from `c9f9b04` to `be5d77c`
2021-09-02 05:40:51 -07:00
dependabot[bot]
1bb8a43e04 Bump distroless/static from c9f9b04 to be5d77c
Bumps distroless/static from `c9f9b04` to `be5d77c`.

---
updated-dependencies:
- dependency-name: distroless/static
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-02 03:00:24 +00:00
anjalitelang
655bbce42a Update ROADMAP.md
Updated September roadmap to reflect work on Improving Security Posture. Added CLI SSO as Future roadmap item.
2021-09-01 21:35:47 -04:00
Mo Khan
9258745ec7 Fix roadmap table formatting
We seem to have missed a `|` at the start of the table.
2021-09-01 15:33:23 -04:00
Anjali Telang
fcffab9a4c Add community info and resolve some minor issues
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-09-01 13:23:26 -04:00
Ryan Richard
92f7f12bab Update latest release tag in site/config.yaml, used by docs 2021-08-31 16:47:40 -07:00
Ryan Richard
7c40185676 Merge pull request #825 from anjaltelang/main
Add Blog post for v0.11.0 release
2021-08-31 16:46:23 -07:00
Pinny
abf19f649d Update CLI docs for v0.11.0 release 2021-08-31 23:40:00 +00:00
Pinny
0a2a716796 Update CLI docs for v0.10.0 release 2021-08-31 23:21:54 +00:00
Anjali Telang
a27e398923 Changed date and cleaned up some more AD format
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-08-31 15:02:57 -04:00
Ryan Richard
b19af2e135 Merge pull request #829 from enj/enj/i/wait_shutdown
Ensure concierge and supervisor gracefully exit
2021-08-31 11:30:35 -07:00
Ryan Richard
883007aa1b Merge pull request #756 from vmware-tanzu/ad-identity-provider-docs
Document how to configure the ActiveDirectoryIdentityProvider
2021-08-31 10:48:25 -07:00
Anjali Telang
ba1470ea9d Add AD changes
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-08-30 21:04:48 -04:00
Monis Khan
0d285ce993 Ensure concierge and supervisor gracefully exit
Changes made to both components:

1. Logs are always flushed on process exit
2. Informer cache sync can no longer hang process start up forever

Changes made to concierge:

1. Add pre-shutdown hook that waits for controllers to exit cleanly
2. Informer caches are synced in post-start hook

Changes made to supervisor:

1. Add shutdown code that waits for controllers to exit cleanly
2. Add shutdown code that waits for active connections to become idle

Waiting for controllers to exit cleanly is critical as this allows
the leader election logic to release the lock on exit.  This reduces
the time needed for the next leader to be elected.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-30 20:29:52 -04:00
Matt Moyer
e43bd59688 Merge pull request #830 from mattmoyer/update-youtube-demo-link
Update YouTube demo link to our official page.
2021-08-30 14:30:15 -07:00
Matt Moyer
0c8d885c26 Update YouTube demo link to our official page.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-08-30 16:29:32 -05:00
Anjali Telang
23fb84029b changes made on ryan's review comments
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-08-28 15:59:04 -04:00
Mo Khan
d2dfe3634a Merge pull request #828 from enj/enj/i/supervisor_graceful_exit
supervisor: ensure graceful exit
2021-08-28 13:40:13 -04:00
Monis Khan
5489f68e2f supervisor: ensure graceful exit
The kubelet will send the SIGTERM signal when it wants a process to
exit.  After a grace period, it will send the SIGKILL signal to
force the process to terminate.  The concierge has always handled
both SIGINT and SIGTERM as indicators for it to gracefully exit
(i.e. stop watches, controllers, etc).  This change updates the
supervisor to do the same (previously it only handled SIGINT).  This
is required to allow the leader election lock release logic to run.
Otherwise it can take a few minutes for new pods to acquire the
lease since they believe it is already held.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-28 11:23:11 -04:00
Ryan Richard
4eb500cc41 Merge pull request #826 from vmware-tanzu/simplify_readme
Simplify the main README.md to reduce duplication with website
2021-08-27 16:40:53 -07:00
Ryan Richard
871a9fb0c6 Simplify the main README.md to reduce duplication with website 2021-08-27 15:52:51 -07:00
Anjali Telang
4cb0152ea1 Merge branch 'main' of github.com:anjaltelang/pinniped into main 2021-08-27 17:15:55 -04:00
Anjali Telang
42af8acd1e Fixed yaml format for Aud
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-08-27 17:14:53 -04:00
Anjali Telang
df014dadc3 Remove unnecessary space after image 2021-08-27 17:07:02 -04:00
Anjali Telang
bb657e7432 Blog for v0.11.0
Signed-off-by: Anjali Telang <atelang@vmware.com>
2021-08-27 17:00:34 -04:00
Mo Khan
d580695faa Merge pull request #824 from enj/enj/t/disruptive_hang
test/integration: use short timeouts with distinct requests to prevent hangs
2021-08-27 16:38:39 -04:00
Monis Khan
ba80b691e1 test/integration: use short timeouts with distinct requests to prevent hangs
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-27 16:10:36 -04:00
Mo Khan
41c017c9da Merge pull request #821 from enj/enj/t/increase_disruptive_test_timeout
test/integration: increase timeout on disruptive tests
2021-08-27 15:24:43 -04:00
Monis Khan
5078cdbc90 test/integration: increase timeout on disruptive tests
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-27 14:56:51 -04:00
Margo Crawford
e5718351ba Merge pull request #695 from vmware-tanzu/active-directory-identity-provider
Active directory identity provider
2021-08-27 08:39:12 -07:00
Mo Khan
36ff0d52da Merge pull request #818 from enj/enj/i/bump_go1.17
Bump to Go 1.17.0
2021-08-27 10:30:51 -04:00
Monis Khan
ad3086b8f1 Downgrade go mod compat to 1.16 for golangci-lint
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-27 10:03:48 -04:00
Monis Khan
6c29f347b4 go 1.17 bump: fix unit test failures
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-27 09:46:58 -04:00
Monis Khan
a86949d0be Use go 1.17 module lazy loading
See https://golang.org/doc/go1.17#go-command for details.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-27 09:46:58 -04:00
Monis Khan
44f03af4b9 Bump to Go 1.17.0
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-27 09:00:49 -04:00
Mo Khan
ce5cfde11e Merge pull request #816 from enj/enj/i/bump_1.22.1
Bump Kube to v0.22.1
2021-08-27 08:40:23 -04:00
Monis Khan
40d70bf1fc Bump Kube to v0.22.1
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-27 07:36:12 -04:00
Margo Crawford
19100d68ef Merge branch 'main' of github.com:vmware-tanzu/pinniped into active-directory-identity-provider 2021-08-26 20:42:16 -07:00
Mo Khan
1d44aa945d Merge pull request #814 from mayankbh/topic/bmayank/inherit-hostnetwork
Allow use of hostNetwork for kube-cert-agent
2021-08-26 21:13:29 -04:00
Mayank Bhatt
68547f767d Copy hostNetwork field for kube-cert-agent
For clusters where the control plane nodes aren't running a CNI, the
kube-cert-agent pods deployed by concierge cannot be scheduled as they
don't know to use `hostNetwork: true`. This change allows embedding the
host network setting in the Concierge configuration. (by copying it from
the kube-controller-manager pod spec when generating the kube-cert-agent
Deployment)

Also fixed a stray double comma in one of the nearby tests.
2021-08-26 17:09:59 -07:00
Margo Crawford
44e5e9d8c9 Add sentence about api docs 2021-08-26 17:02:56 -07:00
Margo Crawford
43694777d5 Change some comments on API docs, fix lint error by ignoring it 2021-08-26 16:55:43 -07:00
Ryan Richard
f579b1cb9f Merge pull request #812 from vmware-tanzu/resources_section_web_site
Add "Resources" section to pinniped.dev web site
2021-08-26 16:23:36 -07:00
Margo Crawford
2d32e0fa7d Merge branch 'main' of github.com:vmware-tanzu/pinniped into active-directory-identity-provider 2021-08-26 16:21:08 -07:00
Margo Crawford
6f221678df Change sAMAccountName env vars to userPrincipalName
and add E2E ActiveDirectory test
also fixed regexes in supervisor_login_test to be anchored to the
beginning and end
2021-08-26 16:18:05 -07:00
Ryan Richard
e24040b0a9 add link to CNCF presentation slides 2021-08-26 15:52:04 -07:00
Mo Khan
1d269d2f6d Merge pull request #815 from enj/enj/t/integration_parallel_disruptive
test/integration: mark certain tests as disruptive
2021-08-26 17:32:14 -04:00
Monis Khan
d4a7f0b3e1 test/integration: mark certain tests as disruptive
This prevents them from running with any other test, including other
parallel tests.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-26 15:11:47 -04:00
Mo Khan
d22099ac33 Merge pull request #808 from enj/enj/t/integration_parallel
test/integration: run parallel tests concurrently with serial tests
2021-08-26 14:34:18 -04:00
Monis Khan
e2cf9f6b74 leader election test: approximate that followers have observed change
Instead of blindly waiting long enough for a disruptive change to
have been observed by the old leader and followers, we instead rely
on the approximation that checkOnlyLeaderCanWrite provides - i.e.
only a single actor believes they are the leader.  This does not
account for clients that were in the followers list before and after
the disruptive change, but it serves as a reasonable approximation.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-26 12:59:52 -04:00
Monis Khan
74daa1da64 test/integration: run parallel tests concurrently with serial tests
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-26 12:59:52 -04:00
Ryan Richard
475da05185 Merge pull request #810 from vmware-tanzu/docs_gitops_example
Install docs use more GitOps-friendly style
2021-08-25 16:46:58 -07:00
Ryan Richard
86bfd4f5e4 Number each install step using "1." 2021-08-25 16:37:36 -07:00
Ryan Richard
d453bf3403 Add "Resources" section to pinniped.dev web site 2021-08-25 16:25:53 -07:00
Mo Khan
2b9b034bd2 Merge pull request #811 from vmware-tanzu/test_shell_container_image
Replace one-off usages of busybox and debian images in integration tests
2021-08-25 19:13:13 -04:00
Ryan Richard
d20cab10b9 Replace one-off usages of busybox and debian images in integration tests
Those images that are pulled from Dockerhub will cause pull failures
on some test clusters due to Dockerhub rate limiting.

Because we already have some images that we use for testing, and
because those images are already pre-loaded onto our CI clusters
to make the tests faster, use one of those images and always specify
PullIfNotPresent to avoid pulling the image again during the integration
test.
2021-08-25 15:12:07 -07:00
Ryan Richard
399737e7c6 Install docs use more GitOps-friendly style 2021-08-25 14:33:48 -07:00
Margo Crawford
1c5a2b8892 Add a couple more unit tests 2021-08-25 11:33:42 -07:00
Mo Khan
c17e7bec49 Merge pull request #800 from enj/enj/i/leader_election_release
leader election: fix small race duration lease release
2021-08-25 10:29:19 -04:00
Monis Khan
c71ffdcd1e leader election: use better duration defaults
OpenShift has good defaults for these duration fields that we can
use instead of coming up with them ourselves:

e14e06ba8d/pkg/config/leaderelection/leaderelection.go (L87-L109)

Copied here for easy future reference:

// We want to be able to tolerate 60s of kube-apiserver disruption without causing pod restarts.
// We want the graceful lease re-acquisition fairly quick to avoid waits on new deployments and other rollouts.
// We want a single set of guidance for nearly every lease in openshift.  If you're special, we'll let you know.
// 1. clock skew tolerance is leaseDuration-renewDeadline == 30s
// 2. kube-apiserver downtime tolerance is == 78s
//      lastRetry=floor(renewDeadline/retryPeriod)*retryPeriod == 104
//      downtimeTolerance = lastRetry-retryPeriod == 78s
// 3. worst non-graceful lease acquisition is leaseDuration+retryPeriod == 163s
// 4. worst graceful lease acquisition is retryPeriod == 26s
if ret.LeaseDuration.Duration == 0 {
	ret.LeaseDuration.Duration = 137 * time.Second
}

if ret.RenewDeadline.Duration == 0 {
	// this gives 107/26=4 retries and allows for 137-107=30 seconds of clock skew
	// if the kube-apiserver is unavailable for 60s starting just before t=26 (the first renew),
	// then we will retry on 26s intervals until t=104 (kube-apiserver came back up at 86), and there will
	// be 33 seconds of extra time before the lease is lost.
	ret.RenewDeadline.Duration = 107 * time.Second
}
if ret.RetryPeriod.Duration == 0 {
	ret.RetryPeriod.Duration = 26 * time.Second
}

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-24 16:21:53 -04:00
Margo Crawford
c590c8ff41 Merge branch 'main' of github.com:vmware-tanzu/pinniped into active-directory-identity-provider 2021-08-24 12:19:29 -07:00
Monis Khan
c0617ceda4 leader election: in-memory leader status is stopped before release
This change fixes a small race condition that occurred when the
current leader failed to renew its lease.  Before this change, the
leader would first release the lease via the Kube API and then would
update its in-memory status to reflect that change.  Now those
events occur in the reverse (i.e. correct) order.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-24 15:02:56 -04:00
Mo Khan
f7751d13fe Merge pull request #778 from vmware-tanzu/oidc_password_grant
Optionally allow OIDC password grant for CLI-based login experience
2021-08-24 13:02:07 -04:00
Mo Khan
3077034b2d Merge branch 'main' into oidc_password_grant 2021-08-24 12:23:52 -04:00
Mo Khan
89cef2ea6c Merge pull request #796 from enj/enj/i/leader_election_flake
leader election test: fix flake related to invalid assumption
2021-08-20 19:06:51 -04:00
Ryan Richard
211f4b23d1 Log auth endpoint errors with stack traces 2021-08-20 14:41:02 -07:00
Monis Khan
132ec0d2ad leader election test: fix flake related to invalid assumption
Even though a client may hold the leader election lock in the Kube
lease API, that does not mean it has had a chance to update its
internal state to reflect that.  Thus we retry the checks in
checkOnlyLeaderCanWrite a few times to allow the client to catch up.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-20 17:04:26 -04:00
Mo Khan
ae505d8009 Merge pull request #788 from enj/enj/i/leader_election
Add Leader Election Middleware
2021-08-20 12:58:27 -04:00
Monis Khan
c356710f1f Add leader election middleware
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-20 12:18:25 -04:00
Matt Moyer
b9d186e8a3 Merge pull request #786 from mattmoyer/cleanup-go-mod
Cleanup `go.mod` replace directives that are no longer needed.
2021-08-20 08:43:36 -07:00
Matt Moyer
03a8160a91 Remove replace directive for dgrijalva/jwt-go.
We no longer have a transitive dependency on this older repository, so we don't need the replace directive anymore.

There is a new fork of this that we should move to (https://github.com/golang-jwt/jwt), but we can't easily do that until a couple of our direct dependencies upgrade.

This is a revert of d162cb9adf.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-08-20 10:15:55 -05:00
Matt Moyer
f379eee7a3 Drop replace directive for oleiade/reflections.
This is reverting 8358c26107.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-08-20 10:15:55 -05:00
Matt Moyer
4f5312807b Undo dep hacks to work around gRPC example module.
This is essentially reverting 87c7e89b13.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-08-20 10:15:54 -05:00
Margo Crawford
cec3c2133a Update with new default values 2021-08-19 16:27:43 -07:00
Margo Crawford
05afae60c2 Review comments--
- Change list of attributeParsingOverrides to a map
- Add unit test for sAMAccountName as group name without the override
- Change some comments in the the type definition.
2021-08-19 14:21:18 -07:00
Ryan Richard
6239a567a8 remove one nolint:unparam comment 2021-08-19 10:57:00 -07:00
Ryan Richard
e4d418a076 Merge branch 'main' into oidc_password_grant 2021-08-19 10:55:54 -07:00
Ryan Richard
c4727d57c8 Merge pull request #789 from vmware-tanzu/remove_unparam_linter
Remove `unparam` linter
2021-08-19 10:55:04 -07:00
Ryan Richard
b4a39ba3c4 Remove unparam linter
We decided that this linter does not provide very useful feedback
for our project.
2021-08-19 10:20:24 -07:00
Ryan Richard
cf627a82cb Merge branch 'main' into oidc_password_grant 2021-08-19 10:00:11 -07:00
Ryan Richard
42d31a7085 Update login.md doc to mention OIDC CLI-based flow 2021-08-19 09:59:47 -07:00
anjalitelang
02b8ed7e0b Update ROADMAP.md
Removing features listed for July as they are shipped.
2021-08-19 12:19:31 -04:00
Margo Crawford
5e9087263d Increase timeout for activedirectoryidentityprovider to be loaded 2021-08-18 16:24:05 -07:00
Margo Crawford
a20aee5f18 Update test assertions to reflect userPrincipalName as username 2021-08-18 13:18:53 -07:00
Margo Crawford
1d18908055 Fix test error-- execcredential now has interactive:false
for activedirectoryidentityprovider test, which didn't exist on main
when #770 was merged to update the other tests to use 1.22.
2021-08-18 12:55:26 -07:00
Margo Crawford
1c5da35527 Merge remote-tracking branch 'origin' into active-directory-identity-provider 2021-08-18 12:44:12 -07:00
Ryan Richard
61c21d2977 Refactor some authorize and callback error handling, and add more tests 2021-08-18 12:06:46 -07:00
Margo Crawford
90e6298e29 Update text on CRD templates to reflect new defaults 2021-08-18 10:39:01 -07:00
Ryan Richard
04b8f0b455 Extract Supervisor authorize endpoint string constants into apis pkg 2021-08-18 10:20:33 -07:00
Margo Crawford
8657b0e3e7 Cleanup new group attribute behavior and add test coverage 2021-08-18 10:11:18 -07:00
Ryan Richard
0089540b07 Extract Supervisor IDP discovery endpoint string constants into apis pkg 2021-08-17 17:50:02 -07:00
Margo Crawford
26c47d564f Make new combined sAMAccountName@domain attribute the group name
Also change default username attribute to userPrincipalName
2021-08-17 16:53:26 -07:00
Ryan Richard
62c6d53a21 Merge branch 'main' into oidc_password_grant 2021-08-17 15:23:29 -07:00
Ryan Richard
96474b3d99 Extract Supervisor IDP discovery endpoint types into apis package 2021-08-17 15:23:03 -07:00
Ryan Richard
964d16110e Some refactors based on PR feedback from @enj 2021-08-17 13:14:09 -07:00
Matt Moyer
d57637ee56 Merge pull request #783 from enj/enj/t/ignore_test_pods
test/integration: ignore restarts associated with test pods
2021-08-17 11:00:19 -07:00
Mo Khan
8ce4bb6dc1 Merge pull request #784 from enj/enj/r/specific_private
dynamiccert: prevent misuse of NewServingCert
2021-08-17 13:56:23 -04:00
Ryan Richard
a7c88b599c Merge branch 'main' into oidc_password_grant 2021-08-17 10:45:00 -07:00
Monis Khan
e0901f4fe5 dynamiccert: prevent misuse of NewServingCert
The Kube API server code that we use will cast inputs in an attempt
to see if they implement optional interfaces.  This change adds a
simple wrapper struct to prevent such casts from causing us any
issues.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-17 12:58:32 -04:00
Monis Khan
cf25c308cd test/integration: ignore restarts associated with test pods
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-17 12:57:41 -04:00
Mo Khan
9d11be899c Merge pull request #785 from enj/enj/i/no_proxy_env
Provide good defaults for NO_PROXY
2021-08-17 12:55:12 -04:00
Monis Khan
66ddcf98d3 Provide good defaults for NO_PROXY
This change updates the default NO_PROXY for the supervisor to not
proxy requests to the Kubernetes API and other Kubernetes endpoints
such as Kubernetes services.

It also adds https_proxy and no_proxy settings for the concierge
with the same default.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-17 10:03:19 -04:00
Ryan Richard
3fb683f64e Update expected error message in e2e integration test 2021-08-16 15:40:34 -07:00
Ryan Richard
52409f86e8 Merge branch 'main' into oidc_password_grant 2021-08-16 15:17:55 -07:00
Ryan Richard
91c8a3ebed Extract private helper in auth_handler.go 2021-08-16 15:17:30 -07:00
Ryan Richard
52cb0bbc07 More unit tests and small error handling changes for OIDC password grant 2021-08-16 14:27:40 -07:00
Mo Khan
eb2a68fec0 Merge pull request #782 from vmware-tanzu/dependabot/go_modules/github.com/go-ldap/ldap/v3-3.4.1
Bump github.com/go-ldap/ldap/v3 from 3.3.0 to 3.4.1
2021-08-16 17:20:06 -04:00
dependabot[bot]
e05a46b7f5 Bump github.com/go-ldap/ldap/v3 from 3.3.0 to 3.4.1
Bumps [github.com/go-ldap/ldap/v3](https://github.com/go-ldap/ldap) from 3.3.0 to 3.4.1.
- [Release notes](https://github.com/go-ldap/ldap/releases)
- [Commits](https://github.com/go-ldap/ldap/compare/v3.3.0...v3.4.1)

---
updated-dependencies:
- dependency-name: github.com/go-ldap/ldap/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-16 20:46:25 +00:00
Mo Khan
46304c8137 Merge pull request #775 from enj/enj/i/dynamiccert_no_unload
impersonatorconfig: only unload dynamiccert when proxy is disabled
2021-08-16 16:36:03 -04:00
Monis Khan
7a812ac5ed impersonatorconfig: only unload dynamiccert when proxy is disabled
In the upstream dynamiccertificates package, we rely on two pieces
of code:

1. DynamicServingCertificateController.newTLSContent which calls
   - clientCA.CurrentCABundleContent
   - servingCert.CurrentCertKeyContent
2. unionCAContent.VerifyOptions which calls
   - unionCAContent.CurrentCABundleContent

This results in calls to our tlsServingCertDynamicCertProvider and
impersonationSigningCertProvider.  If we Unset these providers, we
subtly break these consumers.  At best this results in test slowness
and flakes while we wait for reconcile loops to converge.  At worst,
it results in actual errors during runtime.  For example, we
previously would Unset the impersonationSigningCertProvider on any
sync loop error (even a transient one caused by a network blip or
a conflict between writes from different replicas of the concierge).
This would cause us to transiently fail to issue new certificates
from the token credential require API.  It would also cause us to
transiently fail to authenticate previously issued client certs
(which results in occasional Unauthorized errors in CI).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-16 16:07:46 -04:00
Ryan Richard
71d6281e39 Merge branch 'main' into oidc_password_grant 2021-08-16 09:30:13 -07:00
Mo Khan
bb30569e41 Merge pull request #780 from enj/enj/i/browser_stderr
cli: prevent browser output from breaking ExecCredential output
2021-08-16 10:34:33 -04:00
Monis Khan
942c55cf51 cli: prevent browser output from breaking ExecCredential output
This change updates the pinniped CLI entrypoint to prevent browser
processes that we spawn from polluting our std out stream.

For example, chrome will print the following message to std out:

Opening in existing browser session.

Which leads to the following incomprehensible error message from
kubectl:

Unable to connect to the server: getting credentials:
decoding stdout: couldn't get version/kind; json parse error:
json: cannot unmarshal string into Go value of type struct
{ APIVersion string "json:\"apiVersion,omitempty\"";
  Kind string "json:\"kind,omitempty\"" }

This would only occur on the initial login when we opened the
browser.  Since credentials would be cached afterwards, kubectl
would work as expected for future invocations as no browser was
opened.

I could not think of a good way to actually test this change.  There
is a clear gap in our integration tests - we never actually launch a
browser in the exact same way a user does - we instead open a chrome
driver at the login URL as a subprocess of the integration test
binary and not the pinniped CLI.  Thus even if the chrome driver was
writing to std out, we would not notice any issues.

It is also unclear if there is a good way to prevent future related
bugs since std out is global to the process.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-16 09:13:57 -04:00
Ryan Richard
50085a505b First unit test for auth endpoint's password grant and related refactor 2021-08-12 17:53:14 -07:00
Ryan Richard
69964fc788 New unit tests updated for Kube 1.22 ExecCredential changes from main
After merging the new Kube 1.22 ExecCredential changes from main into
this feature branch, some of the new units test on this feature branch
needed to be update to account for the new ExecCredential "interactive"
field.
2021-08-12 13:35:56 -07:00
Ryan Richard
5b96d014b4 Merge branch 'main' into oidc_password_grant 2021-08-12 11:12:57 -07:00
Ryan Richard
84c3c3aa9c Optionally allow OIDC password grant for CLI-based login experience
- Add `AllowPasswordGrant` boolean field to OIDCIdentityProvider's spec
- The oidc upstream watcher controller copies the value of
  `AllowPasswordGrant` into the configuration of the cached provider
- Add password grant to the UpstreamOIDCIdentityProviderI interface
  which is implemented by the cached provider instance for use in the
  authorization endpoint
- Enhance the IDP discovery endpoint to return the supported "flows"
  for each IDP ("cli_password" and/or "browser_authcode")
- Enhance `pinniped get kubeconfig` to help the user choose the desired
  flow for the selected IDP, and to write the flow into the resulting
  kubeconfg
- Enhance `pinniped login oidc` to have a flow flag to tell it which
  client-side flow it should use for auth (CLI-based or browser-based)
- In the Dex config, allow the resource owner password grant, which Dex
  implements to also return ID tokens, for use in integration tests
- Enhance the authorize endpoint to perform password grant when
  requested by the incoming headers. This commit does not include unit
  tests for the enhancements to the authorize endpoint, which will come
  in the next commit
- Extract some shared helpers from the callback endpoint to share the
  code with the authorize endpoint
- Add new integration tests
2021-08-12 10:45:39 -07:00
anjalitelang
592563124b Update ROADMAP.md
Updated the roadmap to reflect the Non-Interactive Password based Login support we delivered in July for LDAP and TBD in Aug for OIDC
2021-08-12 11:08:27 -04:00
Mo Khan
c4d7e5c124 Merge pull request #770 from enj/enj/i/bump_1.22.0
Bump to Go 1.16.7 and Kube v0.22.0
2021-08-10 12:29:35 -04:00
Monis Khan
34fd0ea2e2 impersonation proxy: assert nested UID impersonation is disallowed
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-10 00:03:33 -04:00
Monis Khan
5678fc6196 login: update tests for new client exec code
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-09 19:16:55 -04:00
Monis Khan
4a17e1e736 impersonator: update tests for new Impersonate-Uid code
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-09 19:16:54 -04:00
Monis Khan
724acdca1d Update tests for new CSR duration code
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-09 19:16:50 -04:00
Monis Khan
a027f1ae2c jwtcachefiller: update to use CAContentProvider
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-09 19:16:25 -04:00
Monis Khan
d2891554a4 remove google.golang.org/grpc pin
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-09 19:16:14 -04:00
Monis Khan
25b4d82d87 Bump to Go 1.16.7 and Kube v0.22.0
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-09 15:32:13 -04:00
Mo Khan
01ddc7ac36 Merge pull request #738 from mattmoyer/distroless
Switch to a slimmer distroless base image
2021-08-09 15:31:17 -04:00
Matt Moyer
58bbffded4 Switch to a slimmer distroless base image.
At a high level, it switches us to a distroless base container image, but that also includes several related bits:

- Add a writable /tmp but make the rest of our filesystems read-only at runtime.

- Condense our main server binaries into a single pinniped-server binary. This saves a bunch of space in
  the image due to duplicated library code. The correct behavior is dispatched based on `os.Args[0]`, and
  the `pinniped-server` binary is symlinked to `pinniped-concierge` and `pinniped-supervisor`.

- Strip debug symbols from our binaries. These aren't really useful in a distroless image anyway and all the
  normal stuff you'd expect to work, such as stack traces, still does.

- Add a separate `pinniped-concierge-kube-cert-agent` binary with "sleep" and "print" functionality instead of
  using builtin /bin/sleep and /bin/cat for the kube-cert-agent. This is split from the main server binary
  because the loading/init time of the main server binary was too large for the tiny resource footprint we
  established in our kube-cert-agent PodSpec. Using a separate binary eliminates this issue and the extra
  binary adds only around 1.5MiB of image size.

- Switch the kube-cert-agent code to use a JSON `{"tls.crt": "<b64 cert>", "tls.key": "<b64 key>"}` format.
  This is more robust to unexpected input formatting than the old code, which simply concatenated the files
  with some extra newlines and split on whitespace.

- Update integration tests that made now-invalid assumptions about the `pinniped-server` image.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-08-09 15:05:13 -04:00
Matt Moyer
a464c81711 Bump latest version on website.
We accidentally missed this in the v0.10.0 release process. The new YAML field here should make it easier to automate this step, which seems like a really good idea.
2021-08-03 09:21:54 -05:00
Mo Khan
f18cbcd9a6 Merge pull request #763 from enj/enj/i/eks_slow_test
concierge_impersonation_proxy_test: run slowly for EKS
2021-08-01 18:21:54 -04:00
Monis Khan
ac7d65c4a8 concierge_impersonation_proxy_test: run slowly for EKS
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-01 18:19:53 -04:00
Matt Moyer
65fa47cbcd Link to the release from our v0.10.0 blog post.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-30 16:35:38 -05:00
Matt Moyer
a06b38d2cd Merge pull request #760 from mattmoyer/add-v0.10.0-blog-post
Add v0.10.0 blog post.
2021-07-30 16:21:36 -05:00
Matt Moyer
7773fb8afe Add v0.10.0 blog post.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-30 15:30:56 -05:00
Matt Moyer
f4badb3961 Merge pull request #758 from mattmoyer/use-plain-authcode-prompt
Fix broken TTY after manual auth code prompt.
2021-07-30 13:50:27 -05:00
Matt Moyer
1e32530d7b Fix broken TTY after manual auth code prompt.
This may be a temporary fix. It switches the manual auth code prompt to use `promptForValue()` instead of `promptForSecret()`. The `promptForSecret()` function no longer supports cancellation (the v0.9.2 behavior) and the method of cancelling in `promptForValue()` is now based on running the blocking read in a background goroutine, which is allowed to block forever or leak (which is not important for our CLI use case).

This means that the authorization code is now visible in the user's terminal, but this is really not a big deal because of PKCE and the limited lifetime of an auth code.

The main goroutine now correctly waits for the "manual prompt" goroutine to clean up, which now includes printing the extra newline that would normally have been entered by the user in the manual flow.

The text of the manual login prompt is updated to be more concise and less scary (don't use the word "fail").

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-30 12:45:44 -05:00
Matt Moyer
0ab8e14e4a Merge pull request #755 from mattmoyer/update-installation-docs
Update installation documentation
2021-07-29 17:54:23 -05:00
Mo Khan
f1109afa79 Merge pull request #757 from enj/enj/t/dns_hacks
concierge_impersonation_proxy_test: check all forms of DNS
2021-07-29 15:51:22 -04:00
Monis Khan
22be97eeda concierge_impersonation_proxy_test: check all forms of DNS
Signed-off-by: Monis Khan <mok@vmware.com>
2021-07-29 13:35:37 -04:00
Matt Moyer
d23f3c9428 Update ROADMAP.md 2021-07-29 10:22:43 -05:00
Matt Moyer
c3e037b24e Fix a broken link in .../docs/howto/configure-supervisor.md.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-29 09:56:00 -05:00
Matt Moyer
62afb34877 Fix command typo and expand description of values.yaml a bit.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-29 08:45:19 -05:00
Matt Moyer
fd5ed2e5da Rework "install" sections of our docs.
- Remove all the "latest" links and replace them with our new shortcode so they point at the latest release in a more explicit way.
  This also eliminates one of the sections in our Concierge and Supervisor install guides, since you're always installing a specific version.

- Provide instructions for installing with both kapp (one step) and kubectl (two steps for the Concierge).

- Minor wording changes. Mainly we are now a bit less verbose about reminding people they can choose a different version (once per page instead of in each step).

- When we give an example `kapp deploy` command, don't suggest `--yes` and `--diff-changes`.
  Users can still use these but it seems overly verbose for an example command.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-29 08:45:19 -05:00
Matt Moyer
ca82609d1a Create a site parameter and shortcode for "latestversion".
This gives us a single line of YAML to edit when we want to bump our docs to the latest version number.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-29 08:45:18 -05:00
Margo Crawford
a6dc5b912f Document how to configure the ActiveDirectoryIdentityProvider 2021-07-28 14:35:29 -07:00
Ryan Richard
d73093a694 Avoid failures due to impersonation Service having unrelated annotations 2021-07-28 14:19:14 -07:00
Matt Moyer
85560299e0 Merge pull request #754 from mattmoyer/fix-TestLegacyPodCleaner-flake
Relax the timeout for TestLegacyPodCleaner a bit.
2021-07-28 12:43:08 -06:00
Matt Moyer
b42b1c1110 Relax the timeout for TestLegacyPodCleaner a bit.
This test is asynchronously waiting for the controller to do something, and in some of our test environments it will take a bit longer than we'd previously allowed.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-28 13:08:57 -05:00
Matt Moyer
84733405d0 Merge pull request #753 from mattmoyer/fix-e2e-test-assertion
Fix backwards condition in E2E test assertion.
2021-07-28 12:07:00 -06:00
Matt Moyer
48c8fabb5c Fix backwards condition in E2E test assertion.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-28 12:40:07 -05:00
Matt Moyer
1f51159d22 Merge pull request #752 from mattmoyer/fix-impersonator-config-controller-informers
Add ClusterIP service to impersonator-config-controller informer.
2021-07-28 11:28:30 -06:00
Matt Moyer
5f679059d5 Add ClusterIP service to impersonator-config-controller informer.
Prior to this fix, this controller did not correctly react to changes to the ClusterIP service. It would still eventually react with a long delay due to our 5 minute resync interval.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-28 11:57:18 -05:00
Ryan Richard
8afbb4eb4f Merge pull request #744 from vmware-tanzu/dependabot/go_modules/github.com/tdewolff/minify/v2-2.9.20
Bump github.com/tdewolff/minify/v2 from 2.9.19 to 2.9.20
2021-07-28 09:08:22 -07:00
Ryan Richard
c9b4598fa0 Merge pull request #745 from vmware-tanzu/dependabot/go_modules/github.com/creack/pty-1.1.14
Bump github.com/creack/pty from 1.1.13 to 1.1.14
2021-07-28 09:08:03 -07:00
Mo Khan
ef33846d7d Merge pull request #747 from enj/enj/i/delete_race
certs_expirer: be specific about what secret to delete
2021-07-28 10:32:17 -04:00
Monis Khan
8b4ed86071 certs_expirer: be specific about what secret to delete
This change fixes a race that can occur because we have multiple
writers with no leader election lock.

1. TestAPIServingCertificateAutoCreationAndRotation/automatic
   expires the current serving certificate
2. CertsExpirerController 1 deletes expired serving certificate
3. CertsExpirerController 2 starts deletion of expired serving
   certificate but has not done so yet
4. CertsManagerController 1 creates new serving certificate
5. TestAPIServingCertificateAutoCreationAndRotation/automatic
   records the new serving certificate
6. CertsExpirerController 2 finishes deletion, and thus deletes the
   newly created serving certificate instead of the old one
7. CertsManagerController 2 creates new serving certificate
8. TestAPIServingCertificateAutoCreationAndRotation/automatic keeps
   running and eventually times out because it is expecting the
   serving certificate created by CertsManagerController 2 to match
   the value it recorded from CertsManagerController 1 (which will
   never happen since that certificate was incorrectly deleted).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-07-28 09:56:05 -04:00
Mo Khan
8b74dd824b Merge pull request #748 from mattmoyer/fix-css-text-wrapping
Fix form_post CSS styling in Firefox and Safari.
2021-07-28 09:55:39 -04:00
Matt Moyer
727035a2dc Fix form_post CSS styling in Firefox and Safari.
This functioned fine, but did not have the intended visual appearance when it came to how the text of the auth code wrapped inside the copy button in the manual flow.

The new styling behaves correctly on at least Chrome, Firefox, and Safari on macOS.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-28 08:09:20 -05:00
dependabot[bot]
fc82fde585 Bump github.com/tdewolff/minify/v2 from 2.9.19 to 2.9.20
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.19 to 2.9.20.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.19...v2.9.20)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-28 00:03:48 +00:00
dependabot[bot]
f352db8072 Bump github.com/creack/pty from 1.1.13 to 1.1.14
Bumps [github.com/creack/pty](https://github.com/creack/pty) from 1.1.13 to 1.1.14.
- [Release notes](https://github.com/creack/pty/releases)
- [Commits](https://github.com/creack/pty/compare/v1.1.13...v1.1.14)

---
updated-dependencies:
- dependency-name: github.com/creack/pty
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-28 00:03:39 +00:00
Margo Crawford
f075d95183 Merge branch 'main' of github.com:vmware-tanzu/pinniped into active-directory-identity-provider 2021-07-27 15:16:52 -07:00
Matt Moyer
22a66c1192 Merge pull request #746 from mattmoyer/fix-windows-build
Fix CLI compilation on Windows.
2021-07-27 16:15:01 -06:00
Margo Crawford
474266f918 Merge branch 'main' of github.com:vmware-tanzu/pinniped into active-directory-identity-provider 2021-07-27 15:06:58 -07:00
Matt Moyer
8e8af51955 Fix CLI compilation on Windows.
It turns out that `syscall.Stdin` is of type `int` on Linux and macOS, but not on Windows (it's `syscall.Handle`). This should now be portable and do all the require type casting on every platform.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-27 16:10:05 -05:00
Ryan Richard
d5759c9951 Merge pull request #739 from vmware-tanzu/merge_impersonator_service_annotations
Carefully merge desired annotations into impersonation proxy Service
2021-07-27 12:40:31 -07:00
Ryan Richard
bf99348faf Merge branch 'main' into merge_impersonator_service_annotations 2021-07-27 12:40:02 -07:00
Mo Khan
2789af79f6 Merge pull request #742 from enj/enj/i/bump_1.21.3
Bump to Go 1.16.6 and Kube v0.21.3
2021-07-27 15:34:37 -04:00
Ryan Richard
71cae75758 Merge branch 'main' into merge_impersonator_service_annotations 2021-07-27 11:57:16 -07:00
Ryan Richard
90db3ad51b Merge pull request #730 from vmware-tanzu/cli_username_password_env_vars
LDAP logins via CLI read from `PINNIPED_USERNAME` and `PINNIPED_PASSWORD` env vars
2021-07-27 11:56:40 -07:00
Monis Khan
32c9aa5087 Bump to Go 1.16.6 and Kube v0.21.3
Signed-off-by: Monis Khan <mok@vmware.com>
2021-07-27 14:18:08 -04:00
Margo Crawford
bbaa820278 parsing objectGUID as human-readable string version 2021-07-27 11:08:23 -07:00
Margo Crawford
287a5d225a Change SearchBaseFound condition success reason to be a string constant 2021-07-27 10:23:05 -07:00
Ryan Richard
f17f7c0c6a Small refactors in impersonator_config.go suggested by @mattmoyer 2021-07-26 17:46:06 -07:00
Ryan Richard
54c5bcc9a1 Merge branch 'main' into merge_impersonator_service_annotations 2021-07-26 17:25:52 -07:00
Ryan Richard
58ab57201f Suppress lint errors 2021-07-26 17:20:49 -07:00
Ryan Richard
f4829178b3 Use sentence case for headers in docs
Following some common developer style guides such as
Google
https://developers.google.com/style/capitalization#capitalization-in-titles-and-headings
and Microsoft
https://docs.microsoft.com/en-us/style-guide/scannable-content/headings#formatting-headings
2021-07-26 17:18:44 -07:00
Ryan Richard
295f013580 Merge branch 'main' into cli_username_password_env_vars 2021-07-26 17:04:46 -07:00
Margo Crawford
53b58f65b2 Add integration test for wrong password with ldap 2021-07-26 16:32:46 -07:00
Margo Crawford
cc3875f048 PR feedback 2021-07-26 16:03:12 -07:00
Ryan Richard
d8e1521457 Merge pull request #741 from vmware-tanzu/dockerignore
dockerignore gets same contents as gitignore
2021-07-26 12:47:26 -07:00
Ryan Richard
e150111b27 dockerignore gets same contents as gitignore 2021-07-26 11:28:25 -07:00
Ryan Richard
9e27c28b39 Fix TestImpersonationProxy integration test changes from previous commit
Forgot to account for our new booking annotation on the impersonator's
Service.
2021-07-23 14:23:24 -07:00
Margo Crawford
5d23068690 Removed a todo that was resolved 2021-07-23 13:01:41 -07:00
Margo Crawford
1050f39789 Integration test deactivated ad account 2021-07-23 13:01:41 -07:00
Margo Crawford
00978c15f7 Update wording for ActiveDirectoryIdentityProvider crd 2021-07-23 13:01:41 -07:00
Margo Crawford
8ea1bd3dfb Make prepare-for-integration-tests active directory setup accessible for anyone 2021-07-23 13:01:41 -07:00
Margo Crawford
91085e68f9 Refactoring defaulting logic 2021-07-23 13:01:41 -07:00
Margo Crawford
f99f7be836 Default values for ad usersearch and groupsearch 2021-07-23 13:01:41 -07:00
Margo Crawford
890d9c3216 resolve some todos about error handling search base discovery results 2021-07-23 13:01:41 -07:00
Margo Crawford
cb0ee07b51 Fetch AD search base from defaultNamingContext when not specified 2021-07-23 13:01:41 -07:00
Margo Crawford
8e1d70562d Remove shared variables from ldap upstream observer 2021-07-23 13:01:41 -07:00
Margo Crawford
5d8d7246c2 Refactor active directory and ldap controllers to share almost everything
Signed-off-by: Ryan Richard <richardry@vmware.com>
2021-07-23 13:01:41 -07:00
Ryan Richard
3b4f521596 Changed TestLDAPUpstream.TestUsernameAttributeName back to TestUserMailAttributeName
Also added TestUserSAMAccountNameValue

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-07-23 13:01:40 -07:00
Margo Crawford
e5c8cbb3a4 One line fix for lint error. Forgot a period in a comment.
Signed-off-by: Ryan Richard <richardry@vmware.com>
2021-07-23 13:01:40 -07:00
Margo Crawford
7696f4256d Move defaulting of ad username and uid attributes to controller
Now the controller uses upstreamldap so there is less duplication,
since they are very similar.

Signed-off-by: Ryan Richard <richardry@vmware.com>
2021-07-23 13:01:40 -07:00
Ryan Richard
aaa4861373 Custom API Group overlay for AD
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-07-23 13:01:40 -07:00
Margo Crawford
b3d0b28bd0 Integration test fixes, fixing objectGUID handling 2021-07-23 13:01:40 -07:00
Margo Crawford
5c283d941c Helper script for running active directory tests 2021-07-23 13:01:40 -07:00
Margo Crawford
94e90a5d26 groups related env variables for AD 2021-07-23 13:01:40 -07:00
Margo Crawford
be6f9f83ce RBAC rules for activedirectoryidentityprovider 2021-07-23 13:01:40 -07:00
Margo Crawford
3b8edb84a5 WIP on active directory integration test 2021-07-23 13:01:40 -07:00
Margo Crawford
8fb35c6569 Active Directory cli options 2021-07-23 13:01:40 -07:00
Margo Crawford
3899292e89 Advertise Active Directory idps 2021-07-23 13:01:40 -07:00
Margo Crawford
b06de69f6a ActiveDirectoryIdentityProvider
- Create CRD
- Create implementation of AD-specific user search defaults
2021-07-23 13:01:40 -07:00
Ryan Richard
ac4bc02817 Enhance integration test for CredentialIssuer spec annotations 2021-07-23 09:46:40 -07:00
Ryan Richard
708164b878 Carefully merge desired annotations into impersonation proxy Service
Don't overwrite annotations that might have come from a human user or
from some other non-Pinniped controller.
2021-07-22 17:09:50 -07:00
Ryan Richard
e30cf6e51a Merge branch 'main' into cli_username_password_env_vars 2021-07-22 09:29:03 -07:00
Matt Moyer
ee30b78117 Update ROADMAP.md
Bump "Wider Concierge cluster support" to August.
2021-07-22 10:30:45 -05:00
Ryan Richard
64aba7e703 Add new howto guide login.md 2021-07-21 12:10:47 -07:00
Matt Moyer
c6c3a80a86 Merge pull request #733 from mattmoyer/switch-tools-images
Switch to GHCR tools images for local tests, with `imagePullPolicy: IfNotPresent`.
2021-07-21 11:47:37 -06:00
Margo Crawford
a7af63ca3a Merge pull request #729 from rdimitrov/dimitrovr/add-dex-docs
Add documentation for configuring Supervisor with Dex and Github
2021-07-21 08:48:49 -07:00
Matt Moyer
ae72d30cec Switch to GHCR tools images for local tests, with imagePullPolicy: IfNotPresent.
This is more consistent with our CI environment.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-21 09:21:05 -05:00
Nanci Lancaster
fec59eb1bf Merge pull request #731 from microwavables/main
Removed Andrew Keesler, Pablo Schumaker from site, moved them to emeritus status on maintainers file,
2021-07-20 15:37:04 -07:00
Radoslav Dimitrov
f6273b0604 Update the Prerequisites section and add a note about the groups scope
Add Dex to the prerequisites and add a note that to query for the groups
scope the user must set the organizations Dex should search against.
Otherwise the groups claim would be empty. This is because of the format
group claims are represented, i.e. "org:team".

Signed-off-by: Radoslav Dimitrov <dimitrovr@vmware.com>
2021-07-20 13:49:45 +03:00
Ryan Richard
deb699a84a e2e test: PINNIPED_USERNAME/PINNIPED_PASSWORD env vars during LDAP login 2021-07-19 17:08:52 -07:00
Ryan Richard
cac45fd999 LDAP logins read from PINNIPED_USERNAME and PINNIPED_PASSWORD env vars
For CLI-based auth, such as with LDAP upstream identity providers, the
user may use these environment variables to avoid getting interactively
prompted for username and password.
2021-07-19 16:20:59 -07:00
Radoslav Dimitrov
0bdd1bc68f Add documentation for configuring Supervisor with Dex and Github
The following guide describes the process of configuring Supervisor
with Dex and identify users through their Github account. Issue #415

Signed-off-by: Radoslav Dimitrov <dimitrovr@vmware.com>
2021-07-19 16:00:43 +03:00
Mo Khan
4605846499 Merge pull request #724 from vmware-tanzu/fix_git_sha_in_version_info
Copy .git dir during Docker build; used to bake git sha into binary
2021-07-16 14:34:33 -04:00
Ryan Richard
4670890a82 Add .git dir to Docker; used to bake git sha into binary 2021-07-16 09:51:46 -07:00
Margo Crawford
d204b46c18 Merge pull request #721 from vmware-tanzu/resolve-load-balancer-dns
wait for lb dns to resolve in the impersonation proxy integration test
2021-07-15 17:02:08 -07:00
Ryan Richard
b3208f0ca6 wait for lb dns to resolve in the impersonation proxy integration test
this will hopefully fix some flakes where aws provisioned a host for the
load balancer but the tests weren't able to resolve it.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-07-15 16:39:15 -07:00
Ryan Richard
be7bf9c193 Merge pull request #718 from vmware-tanzu/workaround_for_flaky_unit_test
TestAgentController unit test is flaky, try to add workaround
2021-07-15 14:17:11 -07:00
Ryan Richard
2bba39d723 TestAgentController unit test is flaky, try to add workaround
TestAgentController really runs the controller and evaluates multiple
calls to the controller's Sync with real informers caching updates.
There is a large amount of non-determinism in this unit test, and it
does not always behave the same way. Because it makes assertions about
the specific errors that should be returned by Sync, it was not
accounting for some errors that are only returned by Sync once in a
while depending on the exact (unpredictable) order of operations.

This commit doesn't fix the non-determinism in the test, but rather
tries to work around it by also allowing other (undesired but
inevitable) error messages to appear in the list of actual error
messages returned by the calls to the Sync function.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-07-15 13:41:31 -07:00
anjalitelang
dc567d0d1f Update ROADMAP.md
Added https://github.com/vmware-tanzu/pinniped/issues/577 to Roadmap
2021-07-15 12:29:51 -04:00
Ryan Richard
143837c136 Merge pull request #714 from vmware-tanzu/ytt_install_doc_fix
ytt install docs suggest that you checkout the release tag
2021-07-14 12:52:23 -07:00
Ryan Richard
11eb18d348 ytt install docs suggest that you checkout the release tag
Previously, the ytt install docs suggested that you use ytt templates
from the HEAD of main with the container image from the latest public
release, which could result in a mismatch.
2021-07-14 10:59:51 -07:00
Ryan Richard
d5cf5b91d6 Merge pull request #711 from vmware-tanzu/e2e_test_clear_cookies
Clear the browser cookies between each TestE2EFullIntegration subtest
2021-07-13 16:43:57 -07:00
Ryan Richard
48b58e2fad Clear the browser cookies between each TestE2EFullIntegration test
It seems like page.ClearCookies() only clears cookies for the current
domain, so there doesn't seem to be a function to clear all browser
cookies. Instead, we'll just start a whole new browser each test.
They start fast enough that it shouldn't be a problem.
2021-07-13 16:20:02 -07:00
Ryan Richard
7ef3d42e01 Merge pull request #704 from mattmoyer/deflake-serving-certificate-rotation-test
Make TestAPIServingCertificateAutoCreationAndRotation less flaky.
2021-07-13 14:58:54 -07:00
Ryan Richard
33461ddc14 Merge branch 'main' into deflake-serving-certificate-rotation-test 2021-07-13 14:04:34 -07:00
Mo Khan
238c9e6743 Merge pull request #709 from vmware-tanzu/dependabot/go_modules/github.com/tdewolff/minify/v2-2.9.19
Bump github.com/tdewolff/minify/v2 from 2.9.18 to 2.9.19
2021-07-12 14:48:16 -04:00
dependabot[bot]
25cda4f3e6 Bump github.com/tdewolff/minify/v2 from 2.9.18 to 2.9.19
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.18 to 2.9.19.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.18...v2.9.19)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-12 01:20:59 +00:00
Matt Moyer
c71703e4db Merge pull request #707 from mattmoyer/fix-okta-cli-integration-test
Fix TestCLILoginOIDC when running against Okta, and lower CLI server shutdown timeout.
2021-07-09 14:30:19 -07:00
Matt Moyer
5527566a36 Fix TestCLILoginOIDC when running directly against Okta.
Our actual CLI code behaved correctly, but this test made some invalid assumptions about the "upstream" IDP we're testing. It assumed that the upstream didn't support `response_mode=form_post`, but Okta does. This means that when we end up on the localhost callback page, there are no URL query parameters.

Adjusting this regex makes the test pass as expected.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 16:29:42 -05:00
Matt Moyer
b6580b303a Reduce CLI callback shutdown timeout (5s -> 500ms).
I found that there are some situations with `response_mode=form_post` where Chrome will open additional speculative TCP connections. These connections will be idle so they block server shutdown until the (previously 5s) timeout. Lowering this to 500ms should be safe and makes any added latency at login much less noticeable.

More information about Chrome's TCP-level behavior here: https://bugs.chromium.org/p/chromium/issues/detail?id=116982#c5

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 16:29:29 -05:00
Matt Moyer
405a27ba90 Merge pull request #687 from mattmoyer/add-response-mode-form-post
Add support for "response_mode=form_post" in Supervisor and CLI.
2021-07-09 10:37:59 -07:00
Matt Moyer
43f66032a9 Extend TestE2EFullIntegration to test manual OIDC flow.
Using the same fake TTY trick we used to test LDAP login, this new subtest runs through the "manual"/"jump box" login flow. It runs the login with a `--skip-listen` flag set, causing the CLI to skip opening the localhost listener. We can then wait for the login URL to be printed, visit it with the browser and log in, and finally simulate "manually" copying the auth code from the browser and entering it into the waiting CLI prompt.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:45 -05:00
Matt Moyer
91a1fec5cf Add hidden --skip-listen flag for pinniped login oidc.
This flag is (for now) meant only to facilitate end-to-end testing, allowing us to force the "manual" login flow. If it ends up being useful we can un-hide it, but this seemed like the safest option to start with.

There is also a corresponding `--oidc-skip-listen` on the `pinniped get kubeconfig` command.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:44 -05:00
Matt Moyer
d0b37a7c90 Adjust TestFormPostHTML to work on Linux chromedriver.
For some reason our headless Chrome test setup behaves slightly differently on Linux and macOS hosts. On Linux, the emoji characters are not recognized as valid text, so they are URL encoded. This change updates the test to cope with both cases correctly.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:44 -05:00
Matt Moyer
5029495fdb Add manual paste flow to pinniped login oidc command.
This adds a new login flow that allows manually pasting the authorization code instead of receiving a browser-based callback.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:44 -05:00
Matt Moyer
ac6ff1a03c Deprecate oidcclient.WithBrowserOpen() option, add simpler oidcclient.WithSkipBrowserOpen().
This is a more restrictive library interface that more closely matches the use cases of our new form_post login flow.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:44 -05:00
Matt Moyer
95ee9f0b00 Add ctx params to promptForValue() and promptForSecret().
This allows the prompts to be cancelled, which we need to be able to do in the case where we prompt for a manually-pasted auth code but the automatic callback succeeds.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:44 -05:00
Matt Moyer
9fba8d2203 Adjust TestE2EFullIntegration for new form_post flow.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:44 -05:00
Matt Moyer
428f389c7d Add missing t.Helper() on RequireEventuallyf().
This gives us nicer test assertion failure messages.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:44 -05:00
Matt Moyer
71d4e05fb6 Add custom response_mode=form_post HTML template.
This is a new pacakge internal/oidc/provider/formposthtml containing a number of static files embedded using the relatively recent Go "//go:embed" functionality introduced in Go 1.16 (https://blog.golang.org/go1.16).

The Javascript and CSS files are minifiied and injected to make a single self-contained HTML response. There is a special Content-Security-Policy helper to calculate hash-based script-src and style-src rules.

This new code is covered by a new integration test that exercises the JS/HTML functionality in a real browser outside of the rest of the Supervisor.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
1904f8ddc3 In browsertest.Open(), capture console INFO logs.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
6b801056b5 Add testlib.RandBytes() helper.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
674cd4a88c Adjust our securityheader pkg to support form_post.
Our Supervisor callback handler now needs to load JS and CSS from the provider endpoint, and this JS needs to make a `fetch()` call across origins (to post the form to the CLI callback). This requires a custom Content-Security-Policy compared to other pages we render.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
7217cf4892 In form_post mode, expect params via POST'ed form.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
40c931bdc5 When supported, use "response_mode=form_post" in client.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
2823d4d1e3 Add "response_modes_supported" to Supervisor discovery response.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
6d83ecb420 Unit test response_mode=form_post in internal/oidc/callback.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:43 -05:00
Matt Moyer
c27eb17f23 Add "response_mode=form_post" to CLI client.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 12:08:42 -05:00
Matt Moyer
58363bca2c Merge pull request #705 from mattmoyer/deflake-impersonation-websocket-test
Make TestImpersonationProxy less flaky.
2021-07-09 10:06:14 -07:00
Matt Moyer
3bf39797bb Merge pull request #706 from mattmoyer/fix-api-doc-comment
Fix typo in generated API docs (s/mode/type/).
2021-07-09 10:05:05 -07:00
Matt Moyer
3a840cee76 Make TestAPIServingCertificateAutoCreationAndRotation less flaky.
This test would occasionally flake for me when running locally. This change moves more of the assertions into the "eventually" loop, so they can temporarily fail as long as they converge on the expected values.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 11:29:02 -05:00
Matt Moyer
04e9897d51 Make TestImpersonationProxy less flaky.
This test did not tolerate this connection failing, which can happen for any number of flaky networking-related reasons. This change moves the connection setup into an "eventually" retry loop so it's allowed to fail temporarily as long as it eventually connects.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 11:28:33 -05:00
Matt Moyer
ff9095f9c4 Fix typo in generated API docs (s/mode/type/).
This CredentialIssuer field is called `spec.impersonationProxy.service.type`, not `spec.impersonationProxy.service.mode`.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-09 11:28:02 -05:00
Matt Moyer
2e18c88e33 Merge pull request #684 from christianang/oidc-upstream-watcher-supports-proxy
Add IPv6 support to FederationDomain spec.issuer field.
2021-07-09 09:14:39 -07:00
Matt Moyer
9f91c6c884 Merge branch 'main' into oidc-upstream-watcher-supports-proxy 2021-07-09 07:24:52 -07:00
Ryan Richard
59fd1997f4 Merge pull request #703 from vmware-tanzu/ldap-client-int-tests-only-on-kind
Run the LDAP client's integration tests only on Kind
2021-07-08 12:55:03 -07:00
Ryan Richard
74f3ce5dcd Merge branch 'main' into ldap-client-int-tests-only-on-kind 2021-07-08 12:54:56 -07:00
Ryan Richard
d403c8b44b Merge pull request #702 from vmware-tanzu/supervisor-https-proxy-fix-timeout
Fix broken upstream OIDC discovery timeout added in previous commit
2021-07-08 12:54:39 -07:00
Ryan Richard
e130da6daa Add unit test assertion for new OIDC client request timeout 2021-07-08 11:47:49 -07:00
Ryan Richard
2f7dbed321 Try increasing the "eventually" timeouts in one integration test
There were 10 second timeouts in
`TestAPIServingCertificateAutoCreationAndRotation` which fail often
on CI. Maybe increasing the timeouts will help?
2021-07-08 11:17:22 -07:00
Ryan Richard
709c10227f Run the LDAP client's integration tests only on Kind
TestSimultaneousLDAPRequestsOnSingleProvider proved to be unreliable
on AKS due to some kind of kubectl port-forward issue, so only
run the LDAP client's integration tests on Kind. They are testing
the integration between the client code and the OpenLDAP test server,
not testing anything about Kubernetes, so running only on Kind should
give us sufficient test coverage.
2021-07-08 11:10:53 -07:00
Ryan Richard
f0d120a6ca Fix broken upstream OIDC discovery timeout added in previous commit
After noticing that the upstream OIDC discovery calls can hang
indefinitely, I had tried to impose a one minute timeout on them
by giving them a timeout context. However, I hadn't noticed that the
context also gets passed into the JWKS fetching object, which gets
added to our cache and used later. Therefore the timeout context
was added to the cache and timed out while sitting in the cache,
causing later JWKS fetchers to fail.

This commit is trying again to impose a reasonable timeout on these
discovery and JWKS calls, but this time by using http.Client's Timeout
field, which is documented to be a timeout for *each* request/response
cycle, so hopefully this is a more appropriate way to impose a timeout
for this use case. The http.Client instance ends up in the cache on
the JWKS fetcher object, so the timeout should apply to each JWKS
request as well.

Requests that can hang forever are effectively a server-side resource
leak, which could theoretically be taken advantage of in a denial of
service attempt, so it would be nice to avoid having them.
2021-07-08 09:44:02 -07:00
Ryan Richard
1f5480cd5c Merge pull request #701 from vmware-tanzu/supervisor-https-proxy
Add `https_proxy` and `no_proxy` settings for the Supervisor
2021-07-07 14:57:38 -07:00
Ryan Richard
f1e63c55d4 Add https_proxy and no_proxy settings for the Supervisor
- Add new optional ytt params for the Supervisor deployment.
- When the Supervisor is making calls to an upstream OIDC provider,
  use these variables if they were provided.
- These settings are integration tested in the main CI pipeline by
  sometimes setting them on deployments in certain cases, and then
  letting the existing integration tests (e.g. TestE2EFullIntegration)
  provide the coverage, so there are no explicit changes to the
  integration tests themselves in this commit.
2021-07-07 12:50:13 -07:00
Matt Moyer
562951b77a Merge branch 'main' into oidc-upstream-watcher-supports-proxy 2021-07-06 11:30:09 -07:00
Matt Moyer
dbd2cb4563 Merge pull request #696 from vmware-tanzu/dependabot/go_modules/github.com/spf13/cobra-1.2.1
Bump github.com/spf13/cobra from 1.2.0 to 1.2.1
2021-07-06 07:04:02 -07:00
dependabot[bot]
1c746feafe Bump github.com/spf13/cobra from 1.2.0 to 1.2.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.2.0 to 1.2.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Changelog](https://github.com/spf13/cobra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/spf13/cobra/compare/v1.2.0...v1.2.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-05 01:28:57 +00:00
Ryan Richard
49683975ab Merge pull request #689 from vmware-tanzu/trivial_refactor
Extract some trivial helpers for identical code usages
2021-07-02 14:56:26 -07:00
Ryan Richard
4be26fc1a6 Merge branch 'main' into trivial_refactor 2021-07-02 13:48:27 -07:00
Matt Moyer
f590a3a88b Merge pull request #692 from vmware-tanzu/dependabot/go_modules/github.com/spf13/cobra-1.2.0
Bump github.com/spf13/cobra from 1.1.3 to 1.2.0
2021-07-02 07:24:55 -07:00
dependabot[bot]
e26486bd41 Bump github.com/spf13/cobra from 1.1.3 to 1.2.0
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.1.3 to 1.2.0.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Changelog](https://github.com/spf13/cobra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/spf13/cobra/compare/v1.1.3...v1.2.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-02 01:11:11 +00:00
Matt Moyer
5c2e890ecd Add "Extended IDP support" to the roadmap. 2021-07-01 10:48:13 -05:00
Matt Moyer
715cf7748a Add "Identity transforms" feature to roadmap. 2021-07-01 10:17:40 -05:00
Matt Moyer
e0456b4485 Update ROADMAP given current state of work 2021-07-01 10:05:30 -05:00
Ryan Richard
629bf61655 Extract some trivial helpers for identical code usages 2021-06-30 15:02:14 -07:00
Matt Moyer
738e6aa3cc Merge pull request #685 from vmware-tanzu/dependabot/go_modules/github.com/gofrs/flock-0.8.1
Bump github.com/gofrs/flock from 0.8.0 to 0.8.1
2021-06-30 10:53:39 -07:00
Guangyuan Wang
76dc39ac2d Use hostname instead of host and split on ":"
Co-authored-by: Christian Ang <angc@vmware.com>
Co-authored-by: Tyler Schultz <tschultz@vmware.com>
2021-06-28 23:03:05 +00:00
dependabot[bot]
43fee6bb94 Bump github.com/gofrs/flock from 0.8.0 to 0.8.1
Bumps [github.com/gofrs/flock](https://github.com/gofrs/flock) from 0.8.0 to 0.8.1.
- [Release notes](https://github.com/gofrs/flock/releases)
- [Commits](https://github.com/gofrs/flock/compare/v0.8.0...v0.8.1)

---
updated-dependencies:
- dependency-name: github.com/gofrs/flock
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-28 01:28:52 +00:00
Christian Ang
8026729c43 Use net.JoinHostPort instead of Sprintf
Co-authored-by: Guangyuan Wang <wguangyuan@vmware.com>
2021-06-24 23:19:11 +00:00
Guangyuan Wang
d19d63ad7d Set Proxy on oidc upstream watcher transport
- this allows the oidc upsream watcher to honor the
HTTP_PROXY,HTTPS_PROXY,NO_PROXY environment variables

Co-authored-by: Christian Ang <angc@vmware.com>
2021-06-24 22:35:16 +00:00
Mo Khan
a6141e911c Merge pull request #683 from enj/enj/i/credentialrequest_notafter
credentialrequest: use safer approximation for ExpirationTimestamp
2021-06-23 11:55:29 -04:00
Monis Khan
5ff2be973c credentialrequest: use safer approximation for ExpirationTimestamp
We want the value of time.Now() to be calculated before the call to
IssueClientCertPEM to prevent the ExpirationTimestamp from being
later than the notAfter timestamp on the issued certificate.

Signed-off-by: Monis Khan <mok@vmware.com>
2021-06-23 11:07:00 -04:00
Matt Moyer
73201ba575 Merge pull request #682 from vmware-tanzu/dependabot/docker/debian-10.10-slim
Bump debian from 10.9-slim to 10.10-slim
2021-06-22 19:39:13 -07:00
dependabot[bot]
125d891cd5 Bump debian from 10.9-slim to 10.10-slim
Bumps debian from 10.9-slim to 10.10-slim.

---
updated-dependencies:
- dependency-name: debian
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-23 01:02:44 +00:00
Matt Moyer
682a47f739 Merge pull request #680 from mattmoyer/update-k8s-1.21.2
Update to Kubernetes 1.21.2 runtime components.
2021-06-22 10:23:14 -07:00
Matt Moyer
594e47efdf Update to Kubernetes 1.21.2 runtime components.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-06-22 11:55:22 -05:00
Mo Khan
f09a45382e Merge pull request #681 from enj/enj/i/fix_bad_name
Fix bad test package name
2021-06-22 12:54:29 -04:00
Monis Khan
d78b845575 Fix bad test package name
Signed-off-by: Monis Khan <mok@vmware.com>
2021-06-22 11:23:19 -04:00
Mo Khan
1929b47dda Merge pull request #674 from mattmoyer/new-eventual-assertion-helpers
Improve our integration test "Eventually" assertions.
2021-06-22 11:15:06 -04:00
Matt Moyer
3efa7bdcc2 Improve our integration test "Eventually" assertions.
This fixes some rare test flakes caused by a data race inherent in the way we use `assert.Eventually()` with extra variables for followup assertions. This function is tricky to use correctly because it runs the passed function in a separate goroutine, and you have no guarantee that any shared variables are in a coherent state when the `assert.Eventually()` call returns. Even if you add manual mutexes, it's tricky to get the semantics right. This has been a recurring pain point and the cause of several test flakes.

This change introduces a new `library.RequireEventually()` that works by internally constructing a per-loop `*require.Assertions` and running everything on a single goroutine (using `wait.PollImmediate()`). This makes it very easy to write eventual assertions.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-06-17 16:56:03 -05:00
Matt Moyer
6a9eb87c35 Update ROADMAP.md 2021-06-17 10:17:04 -05:00
Matt Moyer
3eba3e07c6 Merge pull request #669 from vmware-tanzu/dependabot/go_modules/github.com/golang/mock-1.6.0
Bump github.com/golang/mock from 1.5.0 to 1.6.0
2021-06-15 18:49:23 -07:00
dependabot[bot]
9f06869f76 Bump github.com/golang/mock from 1.5.0 to 1.6.0
Bumps [github.com/golang/mock](https://github.com/golang/mock) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/golang/mock/releases)
- [Changelog](https://github.com/golang/mock/blob/master/.goreleaser.yml)
- [Commits](https://github.com/golang/mock/compare/v1.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: github.com/golang/mock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-16 01:22:04 +00:00
Matt Moyer
3f41261580 Merge pull request #673 from mattmoyer/refactor-static-client-struct-second-attempt
Use a custom type for our static CLI client.
2021-06-15 17:37:08 -07:00
Matt Moyer
551249fb69 Use a custom type for our static CLI client (smaller change).
Before this change, we used the `fosite.DefaultOpenIDConnectClient{}` struct, which implements the  `fosite.Client` and `fosite.OpenIDConnectClient` interfaces. For a future change, we also need to implement some additional optional interfaces, so we can no longer use the provided default types. Instead, we now use a custom `clientregistry.Client{}` struct, which implements all the requisite interfaces and can be extended to handle the new functionality (in a future change).

There is also a new `clientregistry.StaticRegistry{}` struct, which implements the `fosite.ClientManager` and looks up our single static client. We could potentially extend this in the future with a registry backed by Kubernetes API, for example.

This should be 100% refactor, with no user-observable change.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-06-15 15:31:48 -05:00
Mo Khan
1a610022cf Merge pull request #671 from enj/enj/i/eks_rbac
TestServiceAccountPermissions: handle extra permissions on EKS
2021-06-15 11:46:24 -04:00
Monis Khan
524ff21b7f TestServiceAccountPermissions: handle extra permissions on EKS
Signed-off-by: Monis Khan <mok@vmware.com>
2021-06-15 11:17:59 -04:00
Matt Moyer
913c140be8 Update the latest version number in the docs.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-06-15 09:46:51 -05:00
1637 changed files with 89291 additions and 7559 deletions

View File

@@ -1,12 +1,23 @@
./.*
./*.md
./*.yaml
./apis
./deploy
./Dockerfile
./generated/1.1*
./internal/mocks
./LICENSE
./site/
./test
**/*_test.go
# This is effectively a copy of the .gitignore file.
# The whole git repo, including the .git directory, should get copied into the Docker build context,
# to enable the use of hack/get-ldflags.sh inside the Dockerfile.
# When you change the .gitignore file, please consider also changing this file.
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# GoLand
.idea
# MacOS Desktop Services Store
.DS_Store

1
.gitattributes vendored
View File

@@ -1,2 +1,3 @@
*.go.tmpl linguist-language=Go
hack/Dockerfile_fips linguist-language=Dockerfile
generated/** linguist-generated

View File

@@ -1,5 +1,5 @@
---
name: Feature proposal
name: Feature request
about: Suggest a way to improve this project
title: ''
labels: ''
@@ -16,12 +16,15 @@ It is recommended that you include screenshots and logs to help everyone achieve
-->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Are you considering submitting a PR for this feature?**
@@ -32,4 +35,5 @@ A clear and concise description of any alternative solutions or features you've
- **How will this feature be documented?**
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -0,0 +1,34 @@
---
name: Proposal tracking
about: A tracking issue for a proposal document
title: '[Proposal] Your proposal title'
labels: 'proposal-tracking'
assignees: ''
---
<!--
Hey! Thanks for opening an issue!
This type of issue should only be opened if you intend to create a
formal proposal document. Please refer to the proposal process in
[proposals/README.md](proposals/README.md).
Please title this issue starting with `[Proposal]` followed by a
title for what you are going to propose. For example:
`[Proposal] Lunar landing module authentication via Pinniped`.
-->
### Proposal Tracking Issue
- Proposal: <!-- this starts empty, then please update to link to proposal PR, then also link to proposal doc file after it is merged -->
- Discussion Links: <!-- link to any mailing list threads, Slack conversations, community meetings, or other places where the proposal was discussed, if any -->
- <!-- A -->
- <!-- B -->
- Pull requests: <!-- link to all PRs related to this proposal such as updates to the proposal doc, implementation PRs, etc. - keep this list up to date -->
- <!-- #123: briefly describe this PR -->
- <!-- #456: briefly describe this PR -->

View File

@@ -3,6 +3,7 @@
version: 2
updates:
- package-ecosystem: "gomod"
open-pull-requests-limit: 100
directory: "/"
schedule:
interval: "daily"
@@ -11,3 +12,8 @@ updates:
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "docker"
directory: "/hack" # this should keep the FIPS dockerfile updated per https://github.com/dependabot/feedback/issues/145#issuecomment-414738498
schedule:
interval: "daily"

57
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: "CodeQL"
on:
push:
branches: [ main, release* ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main, release* ]
schedule:
- cron: '39 13 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'go', 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

55
.github/workflows/scorecards.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
name: Scorecards supply-chain security
on:
# Only the default branch is supported.
branch_protection_rule:
schedule:
- cron: '29 11 * * 3'
push:
branches: [ main, release* ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecards analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
actions: read
contents: read
steps:
- name: "Checkout code"
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # v3.0.0
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@c1aec4ac820532bab364f02a81873c555a0ba3a1 # v1.0.4
with:
results_file: results.sarif
results_format: sarif
# Read-only PAT token. To create it,
# follow the steps in https://github.com/ossf/scorecard-action#pat-token-creation.
repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
# Publish the results to enable scorecard badges. For more details, see
# https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories, `publish_results` will automatically be set to `false`,
# regardless of the value entered here.
publish_results: true
# Upload the results as artifacts (optional).
- name: "Upload artifact"
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # v1.0.26
with:
sarif_file: results.sarif

6
.gitignore vendored
View File

@@ -1,3 +1,6 @@
# When you change this file, please consider also changing the .dockerignore file.
# See comments at the top of .dockerignore for more information.
# Binaries for programs and plugins
*.exe
*.exe~
@@ -11,9 +14,6 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# GoLand
.idea

View File

@@ -34,7 +34,7 @@ linters:
- godot
- goheader
- goimports
- golint
- revive
- goprintffuncname
- gosec
- misspell
@@ -44,10 +44,9 @@ linters:
- nolintlint
- prealloc
- rowserrcheck
- scopelint
- exportloopref
- sqlclosecheck
- unconvert
- unparam
- whitespace
issues:

View File

@@ -11,6 +11,7 @@ repos:
- id: check-json
- id: end-of-file-fixer
- id: trailing-whitespace
exclude: 'securetls*' # prevent the linter from running in this file because it's not smart enough not to trim the nmap test output.
- id: check-merge-conflict
- id: check-added-large-files
- id: check-byte-order-marker

View File

@@ -10,15 +10,28 @@ Please see the [Code of Conduct](./CODE_OF_CONDUCT.md).
See [SCOPE.md](./SCOPE.md) for some guidelines about what we consider in and out of scope for Pinniped.
## Roadmap
The near-term and mid-term roadmap for the work planned for the project [maintainers](MAINTAINERS.md) is documented in [ROADMAP.md](ROADMAP.md).
## Community Meetings
Pinniped is better because of our contributors and maintainers. It is because of you that we can bring great software to the community. Please join us during our online community meetings, occuring every first and third Thursday of the month at 9AM PT / 12PM ET. Use [this Zoom Link](https://vmware.zoom.us/j/93798188973?pwd=T3pIMWxReEQvcWljNm1admRoZTFSZz09) to attend and add any agenda items you wish to discuss to [the notes document](https://hackmd.io/rd_kVJhjQfOvfAWzK8A3tQ?view). Join our [Google Group](https://groups.google.com/u/1/g/project-pinniped) to receive invites to this meeting.
Pinniped is better because of our contributors and [maintainers](MAINTAINERS.md). It is because of you that we can bring great
software to the community. Please join us during our online community meetings,
occurring every first and third Thursday of the month at 9 AM PT / 12 PM ET.
Use [this Zoom Link](https://go.pinniped.dev/community/zoom)
to attend and add any agenda items you wish to discuss
to [the notes document](https://hackmd.io/rd_kVJhjQfOvfAWzK8A3tQ?view).
Join our [Google Group](https://groups.google.com/g/project-pinniped) to receive invites to this meeting.
If the meeting day falls on a US holiday, please consider that occurrence of the meeting to be canceled.
## Discussion
Got a question, comment, or idea? Please don't hesitate to reach out via the GitHub [Discussions](https://github.com/vmware-tanzu/pinniped/discussions) tab at the top of this page or reach out in Kubernetes Slack Workspace within the [#pinniped channel](https://kubernetes.slack.com/archives/C01BW364RJA).
Got a question, comment, or idea? Please don't hesitate to reach out
via GitHub [Discussions](https://github.com/vmware-tanzu/pinniped/discussions),
GitHub [Issues](https://github.com/vmware-tanzu/pinniped/issues),
or in the Kubernetes Slack Workspace within the [#pinniped channel](https://kubernetes.slack.com/archives/C01BW364RJA).
## Issues
@@ -45,7 +58,7 @@ guidelines in the issue and pull request templates.
To suggest a feature, please first open an
[issue](https://github.com/vmware-tanzu/pinniped/issues/new?template=feature-proposal.md)
and tag it with `proposal`, or create a new [Discussion](https://github.com/vmware-tanzu/pinniped/discussions).
The project team will work with you on your feature request.
The project [maintainers](MAINTAINERS.md) will work with you on your feature request.
Once the feature request has been validated, a [pull request](https://github.com/vmware-tanzu/pinniped/compare)
can be opened to implement the feature.
@@ -53,25 +66,44 @@ can be opened to implement the feature.
For specifics on what to include in your feature request, please follow the
guidelines in the issue and pull request templates.
### Reporting security vulnerabilities
Please follow the procedure described in [SECURITY.md](SECURITY.md).
## CLA
We welcome contributions from everyone but we can only accept them if you sign
We welcome contributions from everyone, but we can only accept them if you sign
our Contributor License Agreement (CLA). If you would like to contribute and you
have not signed it, our CLA-bot will walk you through the process when you open
a Pull Request. For questions about the CLA process, see the
[FAQ](https://cla.vmware.com/faq) or submit a question through the GitHub issue
tracker.
## Learning about Pinniped
New to Pinniped?
- Start here to learn how to install and use Pinniped: [Learn to use Pinniped for federated authentication to Kubernetes clusters](https://pinniped.dev/docs/tutorials/concierge-and-supervisor-demo/)
- Start here to learn how to navigate the source code: [Code Walk-through](https://pinniped.dev/docs/reference/code-walkthrough/)
- Other more detailed documentation can be found at: [Pinniped Docs](https://pinniped.dev/docs/)
## Building
The [Dockerfile](Dockerfile) at the root of the repo can be used to build and
package the code. After making a change to the code, rebuild the docker image with the following command.
package the server-side code. After making a change to the code, rebuild the
docker image with the following command.
```bash
# From the root directory of the repo...
docker build .
```
The Pinniped CLI client can be built for local use with the following command.
```bash
# From the root directory of the repo...
go build -o pinniped ./cmd/pinniped
```
## Testing
### Running Lint
@@ -97,14 +129,15 @@ docker build .
- [`kind`](https://kind.sigs.k8s.io/docs/user/quick-start)
- [`kubectl`](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
- [`ytt`](https://carvel.dev/#getting-started)
- [`nmap`](https://nmap.org/download.html)
On macOS, these tools can be installed with [Homebrew](https://brew.sh/) (assuming you have Chrome installed already):
```bash
brew install kind k14s/tap/ytt k14s/tap/kapp kubectl chromedriver && brew cask install docker
brew install kind vmware-tanzu/carvel/ytt vmware-tanzu/carvel/kapp kubectl chromedriver nmap && brew cask install docker
```
1. Create a kind cluster, compile, create container images, and install Pinniped and supporting dependencies using:
1. Create a kind cluster, compile, create container images, and install Pinniped and supporting test dependencies using:
```bash
./hack/prepare-for-integration-tests.sh
@@ -113,9 +146,14 @@ docker build .
1. Run the Pinniped integration tests:
```bash
source /tmp/integration-test-env && go test -v -count 1 -timeout 0 ./test/integration
ulimit -n 512 && source /tmp/integration-test-env && go test -v -count 1 -timeout 0 ./test/integration
```
To run specific integration tests, add the `-run` flag to the above command to specify a regexp for the test names.
Use a leading `/` on the regexp because the Pinniped integration tests are automatically nested under several parent tests
(see [integration/main_test.go](https://github.com/vmware-tanzu/pinniped/blob/main/test/integration/main_test.go)).
For example, to run an integration test called `TestE2E`, add `-run /TestE2E` to the command shown above.
1. After making production code changes, recompile, redeploy, and run tests again by repeating the same
commands described above. If there are only test code changes, then simply run the tests again.

View File

@@ -1,9 +1,9 @@
# syntax = docker/dockerfile:1.0-experimental
# syntax=docker/dockerfile:1
# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
# Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
FROM golang:1.16.5 as build-env
FROM golang:1.18.1 as build-env
WORKDIR /work
COPY . .
@@ -16,32 +16,26 @@ RUN \
--mount=type=cache,target=/cache/gocache \
--mount=type=cache,target=/cache/gomodcache \
mkdir out && \
GOCACHE=/cache/gocache \
GOMODCACHE=/cache/gomodcache \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64 \
go build -v -ldflags "$(hack/get-ldflags.sh)" -o out \
./cmd/pinniped-concierge/... \
./cmd/pinniped-supervisor/... \
./cmd/local-user-authenticator/...
export GOCACHE=/cache/gocache GOMODCACHE=/cache/gomodcache CGO_ENABLED=0 GOOS=linux GOARCH=amd64 && \
go build -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-concierge-kube-cert-agent ./cmd/pinniped-concierge-kube-cert-agent/... && \
go build -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-server ./cmd/pinniped-server/... && \
ln -s /usr/local/bin/pinniped-server /usr/local/bin/pinniped-concierge && \
ln -s /usr/local/bin/pinniped-server /usr/local/bin/pinniped-supervisor && \
ln -s /usr/local/bin/pinniped-server /usr/local/bin/local-user-authenticator
# Use a Debian slim image to grab a reasonable default CA bundle.
FROM debian:10.9-slim AS get-ca-bundle-env
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/* /var/cache/debconf/*
# Use a distroless runtime image with CA certificates, timezone data, and not much else.
FROM gcr.io/distroless/static:nonroot@sha256:2556293984c5738fc75208cce52cf0a4762c709cf38e4bf8def65a61992da0ad
# Use a runtime image based on Debian slim.
FROM debian:10.9-slim
COPY --from=get-ca-bundle-env /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
# Copy the server binary from the build-env stage.
COPY --from=build-env /usr/local/bin /usr/local/bin
# Copy the binaries from the build-env stage.
COPY --from=build-env /work/out/ /usr/local/bin/
# Document the ports
EXPOSE 8080 8443
# Document the default server ports for the various server apps
EXPOSE 8443 8444 10250
# Run as non-root for security posture
USER 1001:1001
# Use the same non-root user as https://github.com/GoogleContainerTools/distroless/blob/fc3c4eaceb0518900f886aae90407c43be0a42d9/base/base.bzl#L9
# This is a workaround for https://github.com/GoogleContainerTools/distroless/issues/718
USER 65532:65532
# Set the entrypoint
ENTRYPOINT ["/usr/local/bin/pinniped-concierge"]
ENTRYPOINT ["/usr/local/bin/pinniped-server"]

68
GOVERNANCE.md Normal file
View File

@@ -0,0 +1,68 @@
# Pinniped Governance
This document defines the project governance for Pinniped.
# Overview
**Pinniped** is committed to building an open, inclusive, productive and self-governing open source community focused on
building authentication services for Kubernetes clusters. The community is governed by this document which defines how
all members should work together to achieve this goal.
# Code of Conduct
The Pinniped community abides by this
[code of conduct](https://github.com/vmware-tanzu/pinniped/blob/main/CODE_OF_CONDUCT.md).
# Community Roles
* **Users:** Members that engage with the Pinniped community via any medium (Slack, GitHub, mailing lists, etc.).
* **Contributors:** Do regular contributions to the Pinniped project (documentation, code reviews, responding to issues,
participating in proposal discussions, contributing code, etc.).
* **Maintainers:** Responsible for the overall health and direction of the project. They are the final reviewers of PRs
and responsible for Pinniped releases.
# Maintainers
New maintainers must be nominated by an existing maintainer and must be elected by a supermajority of existing
maintainers. Likewise, maintainers can be removed by a supermajority of the existing maintainers or can resign by
notifying one of the maintainers.
**Note:** If a maintainer leaves their employer they are still considered a maintainer of Pinniped, unless they
voluntarily resign. Employment is not taken into consideration when determining maintainer eligibility unless the
company itself violates our [Code of Conduct](https://github.com/vmware-tanzu/pinniped/blob/main/CODE_OF_CONDUCT.md).
# Decision Making
Ideally, all project decisions are resolved by consensus. If impossible, any maintainer may call a vote. Unless
otherwise specified in this document, any vote will be decided by a supermajority of maintainers.
## Supermajority
A supermajority is defined as two-thirds of members in the group. A supermajority of maintainers is required for certain
decisions as outlined in this document. A supermajority vote is equivalent to the number of votes in favor being at
least twice the number of votes against. A vote to abstain equals not voting at all. For example, if you have 5
maintainers who all cast non-abstaining votes, then a supermajority vote is at least 4 votes in favor. Voting on
decisions can happen on the mailing list, GitHub, Slack, email, or via a voting service, when appropriate. Maintainers
can either vote "agree, yes, +1", "disagree, no, -1", or "abstain". A vote passes when supermajority is met.
## Lazy Consensus
To maintain velocity in Pinniped, the concept of [Lazy Consensus](http://en.osswiki.info/concepts/lazy_consensus) is
practiced.
Other maintainers may chime in and request additional time for review, but should remain cognizant of blocking progress
and abstain from delaying progress unless absolutely needed. The expectation is that blocking progress is accompanied by
a guarantee to review and respond to the relevant action in short order.
Lazy consensus does not apply to the process of:
* Removal of maintainers from Pinniped
## Updating Governance
All substantive changes in Governance, including substantive changes to the proposal process, require a supermajority
agreement by all maintainers.
# Proposal Process
The proposal process is defined in [proposals/README.md](proposals/README.md).

View File

@@ -4,16 +4,21 @@ This is the current list of maintainers for the Pinniped project.
| Maintainer | GitHub ID | Affiliation |
| --------------- | --------- | ----------- |
| Andrew Keesler | [ankeesler](https://github.com/ankeesler) | [VMware](https://www.github.com/vmware/) |
| Margo Crawford | [margocrawf](https://github.com/margocrawf) | [VMware](https://www.github.com/vmware/) |
| Matt Moyer | [mattmoyer](https://github.com/mattmoyer) | [VMware](https://www.github.com/vmware/) |
| Mo Khan | [enj](https://github.com/enj) | [VMware](https://www.github.com/vmware/) |
| Pablo Schuhmacher | [pabloschuhmacher](https://github.com/pabloschuhmacher) | [VMware](https://www.github.com/vmware/) |
| Anjali Telang | [anjaltelang](https://github.com/anjaltelang) | [VMware](https://www.github.com/vmware/) |
| Ryan Richard | [cfryanr](https://github.com/cfryanr) | [VMware](https://www.github.com/vmware/) |
## Emeritus Maintainers
* Andrew Keesler, [ankeesler](https://github.com/ankeesler)
* Pablo Schuhmacher, [pabloschuhmacher](https://github.com/pabloschuhmacher)
* Matt Moyer, [mattmoyer](https://github.com/mattmoyer)
## Pinniped Contributors & Stakeholders
| Feature Area | Lead |
| ----------------------------- | :---------------------: |
| Technical Lead | Matt Moyer (mattmoyer) |
| Product Management | Pablo Schuhmacher (pabloschuhmacher) |
| Technical Lead | Mo Khan (enj) |
| Product Management | Anjali Telang (anjaltelang) |
| Community Management | Nigel Brown (pnbrown) |

View File

@@ -1,63 +1,51 @@
<img src="site/content/docs/img/pinniped_logo.svg" alt="Pinniped Logo" width="100%"/>
<a href="https://pinniped.dev" target="_blank">
<img src="site/content/docs/img/pinniped_logo.svg" alt="Pinniped Logo" width="100%"/>
</a>
## Overview
Pinniped provides identity services to Kubernetes.
Pinniped allows cluster administrators to easily plug in external identity
providers (IDPs) into Kubernetes clusters. This is achieved via a uniform
install procedure across all types and origins of Kubernetes clusters,
declarative configuration via Kubernetes APIs, enterprise-grade integrations
with IDPs, and distribution-specific integration strategies.
- Easily plug in external identity providers into Kubernetes clusters while offering a simple install and configuration experience. Leverage first class integration with Kubernetes and kubectl command-line.
- Give users a consistent, unified login experience across all your clusters, including on-premises and managed cloud environments.
- Securely integrate with an enterprise IDP using standard protocols or use secure, externally managed identities instead of relying on simple, shared credentials.
### Example use cases
* Your team uses a large enterprise IDP, and has many clusters that they
manage. Pinniped provides:
* Seamless and robust integration with the IDP
* Easy installation across clusters of any type and origin
* A simplified login flow across all clusters
* Your team shares a single cluster. Pinniped provides:
* Simple configuration to integrate an IDP
* Individual, revocable identities
### Architecture
The Pinniped Supervisor component offers identity federation to enable a user to
access multiple clusters with a single daily login to their external IDP. The
Pinniped Supervisor supports various external [IDP
types](https://github.com/vmware-tanzu/pinniped/tree/main/generated/1.20#k8s-api-idp-supervisor-pinniped-dev-v1alpha1).
The Pinniped Concierge component offers credential exchange to enable a user to
exchange an external credential for a short-lived, cluster-specific
credential. Pinniped supports various [authentication
methods](https://github.com/vmware-tanzu/pinniped/tree/main/generated/1.20#authenticationconciergepinnipeddevv1alpha1)
and implements different integration strategies for various Kubernetes
distributions to make authentication possible.
The Pinniped Concierge can be configured to hook into the Pinniped Supervisor's
federated credentials, or it can authenticate users directly via external IDP
credentials.
To learn more, see [architecture](https://pinniped.dev/docs/background/architecture/).
To learn more, please visit the Pinniped project's website, https://pinniped.dev.
## Getting started with Pinniped
Care to kick the tires? It's easy to [install and try Pinniped](https://pinniped.dev/docs/).
## Community meetings
Pinniped is better because of our contributors and maintainers. It is because of you that we can bring great software to the community. Please join us during our online community meetings, occurring every first and third Thursday of the month at 9 AM PT / 12 PM PT. Use [this Zoom Link](https://vmware.zoom.us/j/93798188973?pwd=T3pIMWxReEQvcWljNm1admRoZTFSZz09) to attend and add any agenda items you wish to discuss to [the notes document](https://hackmd.io/rd_kVJhjQfOvfAWzK8A3tQ?view). Join our [Google Group](https://groups.google.com/g/project-pinniped) to receive invites to this meeting.
If the meeting day falls on a US holiday, please consider that occurrence of the meeting to be canceled.
## Discussion
Got a question, comment, or idea? Please don't hesitate to reach out via the GitHub [Discussions](https://github.com/vmware-tanzu/pinniped/discussions) tab at the top of this page or reach out in Kubernetes Slack Workspace within the [#pinniped channel](https://kubernetes.slack.com/archives/C01BW364RJA).
Got a question, comment, or idea? Please don't hesitate to reach out
via GitHub [Discussions](https://github.com/vmware-tanzu/pinniped/discussions),
GitHub [Issues](https://github.com/vmware-tanzu/pinniped/issues),
or in the Kubernetes Slack Workspace within the [#pinniped channel](https://kubernetes.slack.com/archives/C01BW364RJA).
## Contributions
Contributions are welcome. Before contributing, please see the [contributing guide](CONTRIBUTING.md).
Want to get involved? Contributions are welcome.
Please see the [contributing guide](CONTRIBUTING.md) for more information about reporting bugs, requesting features,
building and testing the code, submitting PRs, and other contributor topics.
## Community meetings
Pinniped is better because of our contributors and [maintainers](MAINTAINERS.md). It is because of you that we can bring great
software to the community. Please join us during our online community meetings, occurring every first and third
Thursday of the month at 9 AM PT / 12 PM ET.
Use [this Zoom Link](https://go.pinniped.dev/community/zoom) to attend and add any agenda items you wish to
discuss to [the notes document](https://go.pinniped.dev/community/agenda).
Join our [Google Group](https://groups.google.com/g/project-pinniped) to receive invites to this meeting.
If the meeting day falls on a US holiday, please consider that occurrence of the meeting to be canceled.
## Adopters
Some organizations and products using Pinniped are featured in [ADOPTERS.md](ADOPTERS.md).
Add your own organization or product [here](https://github.com/vmware-tanzu/pinniped/discussions/152).
## Reporting security vulnerabilities
@@ -67,4 +55,4 @@ Please follow the procedure described in [SECURITY.md](SECURITY.md).
Pinniped is open source and licensed under Apache License Version 2.0. See [LICENSE](LICENSE).
Copyright 2020 the Pinniped contributors. All Rights Reserved.
Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.

View File

@@ -33,18 +33,34 @@ The following table includes the current roadmap for Pinniped. If you have any q
Last Updated: June 2021
Theme|Description|Timeline|
Last Updated: March 2022
|Theme|Description|Timeline|
|--|--|--|
|Remote OIDC login support|Add support for logging in from remote hosts without web browsers in the Pinniped CLI and Supervisor|Jun 2021|
|AD Support|Extends upstream IDP protocols|Jun 2021|
|Wider Concierge cluster support|Support for more cluster types in the Concierge|Jul 2021|
|Improving Security Posture|Support Audit logging of security events related to Authentication |May/June 2022|
|Improving Usability|Support for integrating with UI/Dashboards |May/June 2022|
|Improving Security Posture|TLS hardening contd|June/July 2022|
|Multiple IDP support|Support multiple IDPs configured on a single Supervisor|Exploring/Ongoing|
|Improving Security Posture|mTLS for Supervisor sessions |Exploring/Ongoing|
|Improving Security Posture|Key management/rotation for Pinniped components with minimal downtime |Exploring/Ongoing|
|Improving Security Posture|Support for Session Logout |Exploring/Ongoing|
|Improving Security Posture|Support for Idle Session/ Inactivity timeout|Exploring/Ongoing|
|Improving Security Posture|Support for Max Concurrent Sessions|Exploring/Ongoing|
|Improving Security Posture|Support for configurable Session Length |Exploring/Ongoing|
|Improving Security Posture|Reject use of username and groups with system: prefix |Exploring/Ongoing|
|Improving Security Posture|Support for using external KMS for Supervisor signing keys |Exploring/Ongoing|
|Improving Security Posture|Client side use of Secure Enclaves for Session data |Exploring/Ongoing|
|Improving Security Posture|Enforce the use of HTTP Strict Transport (HSTS) |Exploring/Ongoing|
|Improving Security Posture|Assert that Pinniped runs under the restricted PSP version2 levels |Exploring/Ongoing|
|Wider Concierge cluster support|Support for OpenShift cluster types in the Concierge|Exploring/Ongoing|
|Identity transforms|Support prefixing, filtering, or performing coarse-grained checks on upstream users and groups|Exploring/Ongoing|
|CLI SSO|Support Kerberos based authentication on CLI |Exploring/Ongoing|
|Extended IDP support|Support more types of identity providers on the Supervisor|Exploring/Ongoing|
|Improved Documentation|Reorganizing and improving Pinniped docs; new how-to guides and tutorials|Exploring/Ongoing|
|Improving Security Posture|Offer the best security posture for Kubernetes cluster authentication|Exploring/Ongoing|
|Improve our CI/CD systems|Upgrade tests; make Kind more efficient and reliable for CI ; Windows tests; performance tests; scale tests; soak tests|Exploring/Ongoing|
|CLI Improvements|Improving CLI UX for setting up Supervisor IDPs|Exploring/Ongoing|
|Telemetry|Adding some useful phone home metrics as well as some vanity metrics|Exploring/Ongoing|
|Observability|Expose Pinniped metrics through Prometheus Integration|Exploring/Ongoing|
|Device Code Flow|Add support for OAuth 2.0 Device Authorization Grant in the Pinniped CLI and Supervisor|Exploring/Ongoing|
|Supervisor with New Clients|Enable registering new clients with Supervisor|Exploring/Ongoing|

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -61,6 +61,8 @@ type JWTTokenClaims struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories=pinniped;pinniped-authenticator;pinniped-authenticators,scope=Cluster
// +kubebuilder:printcolumn:name="Issuer",type=string,JSONPath=`.spec.issuer`
// +kubebuilder:printcolumn:name="Audience",type=string,JSONPath=`.spec.audience`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:subresource:status
type JWTAuthenticator struct {
metav1.TypeMeta `json:",inline"`

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -33,6 +33,7 @@ type WebhookAuthenticatorSpec struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories=pinniped;pinniped-authenticator;pinniped-authenticators,scope=Cluster
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=`.spec.endpoint`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:subresource:status
type WebhookAuthenticator struct {
metav1.TypeMeta `json:",inline"`

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -96,7 +96,7 @@ type ImpersonationProxySpec struct {
// ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will
// be served using the external name of the LoadBalancer service or the cluster service DNS name.
//
// This field must be non-empty when spec.impersonationProxy.service.mode is "None".
// This field must be non-empty when spec.impersonationProxy.service.type is "None".
//
// +optional
ExternalEndpoint string `json:"externalEndpoint,omitempty"`
@@ -215,6 +215,9 @@ type ImpersonationProxyInfo struct {
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories=pinniped,scope=Cluster
// +kubebuilder:printcolumn:name="ProxyMode",type=string,JSONPath=`.spec.impersonationProxy.mode`
// +kubebuilder:printcolumn:name="DefaultStrategy",type=string,JSONPath=`.status.strategies[?(@.status == "Success")].type`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:subresource:status
type CredentialIssuer struct {
metav1.TypeMeta `json:",inline"`

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:deepcopy-gen=package

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package identity

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package identity

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package identity

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package validation

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:deepcopy-gen=package

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package login

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package login

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package login

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -31,8 +31,9 @@ type FederationDomainTLSSpec struct {
// SNI requests do not include port numbers, so all issuers with the same DNS hostname must use the same
// SecretName value even if they have different port numbers.
//
// SecretName is not required when you would like to use only the HTTP endpoints (e.g. when terminating TLS at an
// Ingress). It is also not required when you would like all requests to this OIDC Provider's HTTPS endpoints to
// SecretName is not required when you would like to use only the HTTP endpoints (e.g. when the HTTP listener is
// configured to listen on loopback interfaces or UNIX domain sockets for traffic from a service mesh sidecar).
// It is also not required when you would like all requests to this OIDC Provider's HTTPS endpoints to
// use the default TLS certificate, which is configured elsewhere.
//
// When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
@@ -109,6 +110,9 @@ type FederationDomainStatus struct {
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories=pinniped
// +kubebuilder:printcolumn:name="Issuer",type=string,JSONPath=`.spec.issuer`
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.status`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:subresource:status
type FederationDomain struct {
metav1.TypeMeta `json:",inline"`

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -34,6 +34,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&OIDCIdentityProviderList{},
&LDAPIdentityProvider{},
&LDAPIdentityProviderList{},
&ActiveDirectoryIdentityProvider{},
&ActiveDirectoryIdentityProviderList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

View File

@@ -0,0 +1,207 @@
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type ActiveDirectoryIdentityProviderPhase string
const (
// ActiveDirectoryPhasePending is the default phase for newly-created ActiveDirectoryIdentityProvider resources.
ActiveDirectoryPhasePending ActiveDirectoryIdentityProviderPhase = "Pending"
// ActiveDirectoryPhaseReady is the phase for an ActiveDirectoryIdentityProvider resource in a healthy state.
ActiveDirectoryPhaseReady ActiveDirectoryIdentityProviderPhase = "Ready"
// ActiveDirectoryPhaseError is the phase for an ActiveDirectoryIdentityProvider in an unhealthy state.
ActiveDirectoryPhaseError ActiveDirectoryIdentityProviderPhase = "Error"
)
// Status of an Active Directory identity provider.
type ActiveDirectoryIdentityProviderStatus struct {
// Phase summarizes the overall status of the ActiveDirectoryIdentityProvider.
// +kubebuilder:default=Pending
// +kubebuilder:validation:Enum=Pending;Ready;Error
Phase ActiveDirectoryIdentityProviderPhase `json:"phase,omitempty"`
// Represents the observations of an identity provider's current state.
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}
type ActiveDirectoryIdentityProviderBind struct {
// SecretName contains the name of a namespace-local Secret object that provides the username and
// password for an Active Directory bind user. This account will be used to perform LDAP searches. The Secret should be
// of type "kubernetes.io/basic-auth" which includes "username" and "password" keys. The username value
// should be the full dn (distinguished name) of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
// The password must be non-empty.
// +kubebuilder:validation:MinLength=1
SecretName string `json:"secretName"`
}
type ActiveDirectoryIdentityProviderUserSearchAttributes struct {
// Username specifies the name of the attribute in Active Directory entry whose value shall become the username
// of the user after a successful authentication.
// Optional, when empty this defaults to "userPrincipalName".
// +optional
Username string `json:"username,omitempty"`
// UID specifies the name of the attribute in the ActiveDirectory entry which whose value shall be used to uniquely
// identify the user within this ActiveDirectory provider after a successful authentication.
// Optional, when empty this defaults to "objectGUID".
// +optional
UID string `json:"uid,omitempty"`
}
type ActiveDirectoryIdentityProviderGroupSearchAttributes struct {
// GroupName specifies the name of the attribute in the Active Directory entries whose value shall become a group name
// in the user's list of groups after a successful authentication.
// The value of this field is case-sensitive and must match the case of the attribute name returned by the ActiveDirectory
// server in the user's entry. E.g. "cn" for common name. Distinguished names can be used by specifying lower-case "dn".
// Optional. When not specified, this defaults to a custom field that looks like "sAMAccountName@domain",
// where domain is constructed from the domain components of the group DN.
// +optional
GroupName string `json:"groupName,omitempty"`
}
type ActiveDirectoryIdentityProviderUserSearch struct {
// Base is the dn (distinguished name) that should be used as the search base when searching for users.
// E.g. "ou=users,dc=example,dc=com".
// Optional, when not specified it will be based on the result of a query for the defaultNamingContext
// (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
// The default behavior searches your entire domain for users.
// It may make sense to specify a subtree as a search base if you wish to exclude some users
// or to make searches faster.
// +optional
Base string `json:"base,omitempty"`
// Filter is the search filter which should be applied when searching for users. The pattern "{}" must occur
// in the filter at least once and will be dynamically replaced by the username for which the search is being run.
// E.g. "mail={}" or "&(objectClass=person)(uid={})". For more information about LDAP filters, see
// https://ldap.com/ldap-filters.
// Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used.
// Optional. When not specified, the default will be
// '(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))'
// This means that the user is a person, is not a computer, the sAMAccountType is for a normal user account,
// and is not shown in advanced view only
// (which would likely mean its a system created service account with advanced permissions).
// Also, either the sAMAccountName, the userPrincipalName, or the mail attribute matches the input username.
// +optional
Filter string `json:"filter,omitempty"`
// Attributes specifies how the user's information should be read from the ActiveDirectory entry which was found as
// the result of the user search.
// +optional
Attributes ActiveDirectoryIdentityProviderUserSearchAttributes `json:"attributes,omitempty"`
}
type ActiveDirectoryIdentityProviderGroupSearch struct {
// Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g.
// "ou=groups,dc=example,dc=com".
// Optional, when not specified it will be based on the result of a query for the defaultNamingContext
// (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
// The default behavior searches your entire domain for groups.
// It may make sense to specify a subtree as a search base if you wish to exclude some groups
// for security reasons or to make searches faster.
// +optional
Base string `json:"base,omitempty"`
// Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user.
// The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the
// dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or
// "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see
// https://ldap.com/ldap-filters.
// Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used.
// Optional. When not specified, the default will act as if the filter were specified as
// "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})".
// This searches nested groups by default.
// Note that nested group search can be slow for some Active Directory servers. To disable it,
// you can set the filter to
// "(&(objectClass=group)(member={})"
// +optional
Filter string `json:"filter,omitempty"`
// Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as
// the result of the group search.
// +optional
Attributes ActiveDirectoryIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
// The user's group membership is refreshed as they interact with the supervisor
// to obtain new credentials (as their old credentials expire). This allows group
// membership changes to be quickly reflected into Kubernetes clusters. Since
// group membership is often used to bind authorization policies, it is important
// to keep the groups observed in Kubernetes clusters in-sync with the identity
// provider.
//
// In some environments, frequent group membership queries may result in a
// significant performance impact on the identity provider and/or the supervisor.
// The best approach to handle performance impacts is to tweak the group query
// to be more performant, for example by disabling nested group search or by
// using a more targeted group search base.
//
// If the group search query cannot be made performant and you are willing to
// have group memberships remain static for approximately a day, then set
// skipGroupRefresh to true. This is an insecure configuration as authorization
// policies that are bound to group membership will not notice if a user has
// been removed from a particular group until their next login.
//
// This is an experimental feature that may be removed or significantly altered
// in the future. Consumers of this configuration should carefully read all
// release notes before upgrading to ensure that the meaning of this field has
// not changed.
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
}
// Spec for configuring an ActiveDirectory identity provider.
type ActiveDirectoryIdentityProviderSpec struct {
// Host is the hostname of this Active Directory identity provider, i.e., where to connect. For example: ldap.example.com:636.
// +kubebuilder:validation:MinLength=1
Host string `json:"host"`
// TLS contains the connection settings for how to establish the connection to the Host.
TLS *TLSSpec `json:"tls,omitempty"`
// Bind contains the configuration for how to provide access credentials during an initial bind to the ActiveDirectory server
// to be allowed to perform searches and binds to validate a user's credentials during a user's authentication attempt.
Bind ActiveDirectoryIdentityProviderBind `json:"bind,omitempty"`
// UserSearch contains the configuration for searching for a user by name in Active Directory.
UserSearch ActiveDirectoryIdentityProviderUserSearch `json:"userSearch,omitempty"`
// GroupSearch contains the configuration for searching for a user's group membership in ActiveDirectory.
GroupSearch ActiveDirectoryIdentityProviderGroupSearch `json:"groupSearch,omitempty"`
}
// ActiveDirectoryIdentityProvider describes the configuration of an upstream Microsoft Active Directory identity provider.
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.host`
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:subresource:status
type ActiveDirectoryIdentityProvider struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec for configuring the identity provider.
Spec ActiveDirectoryIdentityProviderSpec `json:"spec"`
// Status of the identity provider.
Status ActiveDirectoryIdentityProviderStatus `json:"status,omitempty"`
}
// List of ActiveDirectoryIdentityProvider objects.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ActiveDirectoryIdentityProviderList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ActiveDirectoryIdentityProvider `json:"items"`
}

View File

@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -119,6 +119,31 @@ type LDAPIdentityProviderGroupSearch struct {
// the result of the group search.
// +optional
Attributes LDAPIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
// The user's group membership is refreshed as they interact with the supervisor
// to obtain new credentials (as their old credentials expire). This allows group
// membership changes to be quickly reflected into Kubernetes clusters. Since
// group membership is often used to bind authorization policies, it is important
// to keep the groups observed in Kubernetes clusters in-sync with the identity
// provider.
//
// In some environments, frequent group membership queries may result in a
// significant performance impact on the identity provider and/or the supervisor.
// The best approach to handle performance impacts is to tweak the group query
// to be more performant, for example by disabling nested group search or by
// using a more targeted group search base.
//
// If the group search query cannot be made performant and you are willing to
// have group memberships remain static for approximately a day, then set
// skipGroupRefresh to true. This is an insecure configuration as authorization
// policies that are bound to group membership will not notice if a user has
// been removed from a particular group until their next login.
//
// This is an experimental feature that may be removed or significantly altered
// in the future. Consumers of this configuration should carefully read all
// release notes before upgrading to ensure that the meaning of this field has
// not changed.
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
}
// Spec for configuring an LDAP identity provider.

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -20,7 +20,7 @@ const (
PhaseError OIDCIdentityProviderPhase = "Error"
)
// Status of an OIDC identity provider.
// OIDCIdentityProviderStatus is the status of an OIDC identity provider.
type OIDCIdentityProviderStatus struct {
// Phase summarizes the overall status of the OIDCIdentityProvider.
// +kubebuilder:default=Pending
@@ -38,21 +38,104 @@ type OIDCIdentityProviderStatus struct {
// OIDCAuthorizationConfig provides information about how to form the OAuth2 authorization
// request parameters.
type OIDCAuthorizationConfig struct {
// AdditionalScopes are the scopes in addition to "openid" that will be requested as part of the authorization
// request flow with an OIDC identity provider. By default only the "openid" scope will be requested.
// additionalScopes are the additional scopes that will be requested from your OIDC provider in the authorization
// request during an OIDC Authorization Code Flow and in the token request during a Resource Owner Password Credentials
// Grant. Note that the "openid" scope will always be requested regardless of the value in this setting, since it is
// always required according to the OIDC spec. By default, when this field is not set, the Supervisor will request
// the following scopes: "openid", "offline_access", "email", and "profile". See
// https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims for a description of the "profile" and "email"
// scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess for a description of the
// "offline_access" scope. This default value may change in future versions of Pinniped as the standard evolves,
// or as common patterns used by providers who implement the standard in the ecosystem evolve.
// By setting this list to anything other than an empty list, you are overriding the
// default value, so you may wish to include some of "offline_access", "email", and "profile" in your override list.
// If you do not want any of these scopes to be requested, you may set this list to contain only "openid".
// Some OIDC providers may also require a scope to get access to the user's group membership, in which case you
// may wish to include it in this list. Sometimes the scope to request the user's group membership is called
// "groups", but unfortunately this is not specified in the OIDC standard.
// Generally speaking, you should include any scopes required to cause the appropriate claims to be the returned by
// your OIDC provider in the ID token or userinfo endpoint results for those claims which you would like to use in
// the oidcClaims settings to determine the usernames and group memberships of your Kubernetes users. See
// your OIDC provider's documentation for more information about what scopes are available to request claims.
// Additionally, the Pinniped Supervisor requires that your OIDC provider returns refresh tokens to the Supervisor
// from these authorization flows. For most OIDC providers, the scope required to receive refresh tokens will be
// "offline_access". See the documentation of your OIDC provider's authorization and token endpoints for its
// requirements for what to include in the request in order to receive a refresh token in the response, if anything.
// Note that it may be safe to send "offline_access" even to providers which do not require it, since the provider
// may ignore scopes that it does not understand or require (see
// https://datatracker.ietf.org/doc/html/rfc6749#section-3.3). In the unusual case that you must avoid sending the
// "offline_access" scope, then you must override the default value of this setting. This is required if your OIDC
// provider will reject the request when it includes "offline_access" (e.g. GitLab's OIDC provider).
// +optional
AdditionalScopes []string `json:"additionalScopes,omitempty"`
// additionalAuthorizeParameters are extra query parameters that should be included in the authorize request to your
// OIDC provider in the authorization request during an OIDC Authorization Code Flow. By default, no extra
// parameters are sent. The standard parameters that will be sent are "response_type", "scope", "client_id",
// "state", "nonce", "code_challenge", "code_challenge_method", and "redirect_uri". These parameters cannot be
// included in this setting. Additionally, the "hd" parameter cannot be included in this setting at this time.
// The "hd" parameter is used by Google's OIDC provider to provide a hint as to which "hosted domain" the user
// should use during login. However, Pinniped does not yet support validating the hosted domain in the resulting
// ID token, so it is not yet safe to use this feature of Google's OIDC provider with Pinniped.
// This setting does not influence the parameters sent to the token endpoint in the Resource Owner Password
// Credentials Grant. The Pinniped Supervisor requires that your OIDC provider returns refresh tokens to the
// Supervisor from the authorization flows. Some OIDC providers may require a certain value for the "prompt"
// parameter in order to properly request refresh tokens. See the documentation of your OIDC provider's
// authorization endpoint for its requirements for what to include in the request in order to receive a refresh
// token in the response, if anything. If your provider requires the prompt parameter to request a refresh token,
// then include it here. Also note that most providers also require a certain scope to be requested in order to
// receive refresh tokens. See the additionalScopes setting for more information about using scopes to request
// refresh tokens.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
AdditionalAuthorizeParameters []Parameter `json:"additionalAuthorizeParameters,omitempty"`
// allowPasswordGrant, when true, will allow the use of OAuth 2.0's Resource Owner Password Credentials Grant
// (see https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to authenticate to the OIDC provider using a
// username and password without a web browser, in addition to the usual browser-based OIDC Authorization Code Flow.
// The Resource Owner Password Credentials Grant is not officially part of the OIDC specification, so it may not be
// supported by your OIDC provider. If your OIDC provider supports returning ID tokens from a Resource Owner Password
// Credentials Grant token request, then you can choose to set this field to true. This will allow end users to choose
// to present their username and password to the kubectl CLI (using the Pinniped plugin) to authenticate to the
// cluster, without using a web browser to log in as is customary in OIDC Authorization Code Flow. This may be
// convenient for users, especially for identities from your OIDC provider which are not intended to represent a human
// actor, such as service accounts performing actions in a CI/CD environment. Even if your OIDC provider supports it,
// you may wish to disable this behavior by setting this field to false when you prefer to only allow users of this
// OIDCIdentityProvider to log in via the browser-based OIDC Authorization Code Flow. Using the Resource Owner Password
// Credentials Grant means that the Pinniped CLI and Pinniped Supervisor will directly handle your end users' passwords
// (similar to LDAPIdentityProvider), and you will not be able to require multi-factor authentication or use the other
// web-based login features of your OIDC provider during Resource Owner Password Credentials Grant logins.
// allowPasswordGrant defaults to false.
// +optional
AllowPasswordGrant bool `json:"allowPasswordGrant,omitempty"`
}
// Parameter is a key/value pair which represents a parameter in an HTTP request.
type Parameter struct {
// The name of the parameter. Required.
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
// The value of the parameter.
// +optional
Value string `json:"value,omitempty"`
}
// OIDCClaims provides a mapping from upstream claims into identities.
type OIDCClaims struct {
// Groups provides the name of the token claim that will be used to ascertain the groups to which
// an identity belongs.
// Groups provides the name of the ID token claim or userinfo endpoint response claim that will be used to ascertain
// the groups to which an identity belongs. By default, the identities will not include any group memberships when
// this setting is not configured.
// +optional
Groups string `json:"groups"`
// Username provides the name of the token claim that will be used to ascertain an identity's
// username.
// Username provides the name of the ID token claim or userinfo endpoint response claim that will be used to
// ascertain an identity's username. When not set, the username will be an automatically constructed unique string
// which will include the issuer URL of your OIDC provider along with the value of the "sub" (subject) claim from
// the ID token.
// +optional
Username string `json:"username"`
}
@@ -67,7 +150,7 @@ type OIDCClient struct {
SecretName string `json:"secretName"`
}
// Spec for configuring an OIDC identity provider.
// OIDCIdentityProviderSpec is the spec for configuring an OIDC identity provider.
type OIDCIdentityProviderSpec struct {
// Issuer is the issuer URL of this OIDC identity provider, i.e., where to fetch
// /.well-known/openid-configuration.
@@ -113,7 +196,7 @@ type OIDCIdentityProvider struct {
Status OIDCIdentityProviderStatus `json:"status,omitempty"`
}
// List of OIDCIdentityProvider objects.
// OIDCIdentityProviderList lists OIDCIdentityProvider objects.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type OIDCIdentityProviderList struct {
metav1.TypeMeta `json:",inline"`

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -0,0 +1,66 @@
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
// IDPType are the strings that can be returned by the Supervisor identity provider discovery endpoint
// as the "type" of each returned identity provider.
type IDPType string
// IDPFlow are the strings that can be returned by the Supervisor identity provider discovery endpoint
// in the array of allowed client "flows" for each returned identity provider.
type IDPFlow string
const (
IDPTypeOIDC IDPType = "oidc"
IDPTypeLDAP IDPType = "ldap"
IDPTypeActiveDirectory IDPType = "activedirectory"
IDPFlowCLIPassword IDPFlow = "cli_password"
IDPFlowBrowserAuthcode IDPFlow = "browser_authcode"
)
// Equals is a convenience function for comparing an IDPType to a string.
func (r IDPType) Equals(s string) bool {
return string(r) == s
}
// String is a convenience function to convert an IDPType to a string.
func (r IDPType) String() string {
return string(r)
}
// Equals is a convenience function for comparing an IDPFlow to a string.
func (r IDPFlow) Equals(s string) bool {
return string(r) == s
}
// String is a convenience function to convert an IDPFlow to a string.
func (r IDPFlow) String() string {
return string(r)
}
// OIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
type OIDCDiscoveryResponse struct {
SupervisorDiscovery OIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
// OIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type OIDCDiscoveryResponseIDPEndpoint struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type IDPDiscoveryResponse struct {
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
}
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// identity provider discovery endpoint.
type PinnipedIDP struct {
Name string `json:"name"`
Type IDPType `json:"type"`
Flows []IDPFlow `json:"flows,omitempty"`
}

View File

@@ -0,0 +1,25 @@
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidc
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
const (
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizeUsernameHeaderName = "Pinniped-Username"
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the name of the desired identity provider.
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the type of the desired identity provider.
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
)

View File

@@ -0,0 +1,58 @@
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package main is the combined entrypoint for the Pinniped "kube-cert-agent" component.
package main
import (
"encoding/base64"
"encoding/json"
"io"
"io/ioutil"
"log"
"math"
"os"
"time"
// this side effect import ensures that we use fipsonly crypto in fips_strict mode.
_ "go.pinniped.dev/internal/crypto/ptls"
)
//nolint: gochecknoglobals // these are swapped during unit tests.
var (
getenv = os.Getenv
fail = log.Fatalf
sleep = time.Sleep
out = io.Writer(os.Stdout)
)
func main() {
if len(os.Args) < 2 {
fail("missing subcommand")
}
switch os.Args[1] {
case "sleep":
sleep(math.MaxInt64)
case "print":
certBytes, err := ioutil.ReadFile(getenv("CERT_PATH"))
if err != nil {
fail("could not read CERT_PATH: %v", err)
}
keyBytes, err := ioutil.ReadFile(getenv("KEY_PATH"))
if err != nil {
fail("could not read KEY_PATH: %v", err)
}
if err := json.NewEncoder(out).Encode(&struct {
Cert string `json:"tls.crt"`
Key string `json:"tls.key"`
}{
Cert: base64.StdEncoding.EncodeToString(certBytes),
Key: base64.StdEncoding.EncodeToString(keyBytes),
}); err != nil {
fail("failed to write output: %v", err)
}
default:
fail("invalid subcommand %q", os.Args[1])
}
}

View File

@@ -0,0 +1,128 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main
import (
"bytes"
"fmt"
"log"
"os"
"testing"
"time"
"github.com/stretchr/testify/require"
)
type errWriter struct{}
func (e errWriter) Write([]byte) (int, error) { return 0, fmt.Errorf("some write error") }
func TestEntrypoint(t *testing.T) {
for _, tt := range []struct {
name string
args []string
env map[string]string
failOutput bool
wantSleep time.Duration
wantLog string
wantOutJSON string
wantFail bool
}{
{
name: "missing args",
args: []string{},
wantLog: "missing subcommand\n",
wantFail: true,
},
{
name: "invalid subcommand",
args: []string{"/path/to/binary", "invalid"},
wantLog: "invalid subcommand \"invalid\"\n",
wantFail: true,
},
{
name: "valid sleep",
args: []string{"/path/to/binary", "sleep"},
wantSleep: 2562047*time.Hour + 47*time.Minute + 16*time.Second + 854775807*time.Nanosecond, // math.MaxInt64 nanoseconds, approximately 290 years
},
{
name: "missing cert file",
args: []string{"/path/to/binary", "print"},
env: map[string]string{
"CERT_PATH": "./does/not/exist",
"KEY_PATH": "./testdata/test.key",
},
wantFail: true,
wantLog: "could not read CERT_PATH: open ./does/not/exist: no such file or directory\n",
},
{
name: "missing key file",
args: []string{"/path/to/binary", "print"},
env: map[string]string{
"CERT_PATH": "./testdata/test.crt",
"KEY_PATH": "./does/not/exist",
},
wantFail: true,
wantLog: "could not read KEY_PATH: open ./does/not/exist: no such file or directory\n",
},
{
name: "fail to write output",
args: []string{"/path/to/binary", "print"},
env: map[string]string{
"CERT_PATH": "./testdata/test.crt",
"KEY_PATH": "./testdata/test.key",
},
failOutput: true,
wantFail: true,
wantLog: "failed to write output: some write error\n",
},
{
name: "successful print",
args: []string{"/path/to/binary", "print"},
env: map[string]string{
"CERT_PATH": "./testdata/test.crt",
"KEY_PATH": "./testdata/test.key",
},
wantOutJSON: `{
"tls.crt": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01EY3lOVEl4TURReE9Gb1hEVE13TURjeU16SXhNRFF4T0Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDNLCmhZdjJnSVExRHd6aDJjV01pZCtvZkFudkxJZlYyWHY2MXZUTEdwclVJK1hVcUI0L2d0ZjZYNlVObjBMZXR0Mm4KZDhwNHd5N2h3NzNoVS9nZ2R2bVdKdnFCclNqYzNKR2Z5K2tqNjZmS1hYK1BUbGJMN1Fid2lSdmNTcUlYSVdsVgpsSEh4RUNXckVEOGpDdWx3L05WcWZvb2svaDVpTlVDVDl5c3dTSnIvMGZJbWlWbm9UbElvRVlHMmVDTmVqWjVjCmczOXVEM1pUcWQ5WnhXd1NMTG5JKzJrcEpuWkJQY2QxWlE4QVFxekRnWnRZUkNxYWNuNWdja1FVS1pXS1FseG8KRWZ0NmcxWEhKb3VBV0FadzdoRXRrMHY4ckcwL2VLRjd3YW14Rmk2QkZWbGJqV0JzQjRUOXJBcGJkQldUS2VDSgpIdjhmdjVSTUZTenBUM3V6VE84Q0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFDaDVSaGJ4cUplK1ovZ2MxN2NaaEtObWRpd3UKSTJwTHAzUUJmd3ZOK1dibWFqencvN3JZaFkwZDhKWVZUSnpYU0NQV2k2VUFLeEF0WE9MRjhXSUlmOWkzOW42Ugp1S09CR1cxNEZ6ekd5UkppRDNxYUcvSlR2RVcrU0xod2w2OE5kcjVMSFNuYnVnQXFxMzFhYmNReTZabDl2NUE4CkpLQzk3TGovU244cmo3b3BLeTRXM29xN05DUXNBYjB6aDRJbGxSRjZVdlNuSnlTZnNnN3hkWEhIcHhZREh0T1MKWGNPdTV5U1VJWlRnRmU5UmZlVVpsR1o1eG4wY2tNbFE3cVcyV3gxcTBPVld3NXVzNE50a0dxS3JIRzRUbjFYNwp1d28vWXl0bjVzRHhyRHYxL29paTZBWk9Dc1RQcmU0b0Qzd3o0bm1WekNWSmNncnFINFEyNGhUOFdOZz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
"tls.key": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBdmNxRmkvYUFoRFVQRE9IWnhZeUozNmg4Q2U4c2g5WFplL3JXOU1zYW10UWo1ZFNvCkhqK0MxL3BmcFEyZlF0NjIzYWQzeW5qREx1SER2ZUZUK0NCMitaWW0rb0d0S056Y2taL0w2U1BycDhwZGY0OU8KVnN2dEJ2Q0pHOXhLb2hjaGFWV1VjZkVRSmFzUVB5TUs2WEQ4MVdwK2lpVCtIbUkxUUpQM0t6Qkltdi9SOGlhSgpXZWhPVWlnUmdiWjRJMTZObmx5RGYyNFBkbE9wMzFuRmJCSXN1Y2o3YVNrbWRrRTl4M1ZsRHdCQ3JNT0JtMWhFCktwcHlmbUJ5UkJRcGxZcENYR2dSKzNxRFZjY21pNEJZQm5EdUVTMlRTL3lzYlQ5NG9YdkJxYkVXTG9FVldWdU4KWUd3SGhQMnNDbHQwRlpNcDRJa2UveCsvbEV3VkxPbFBlN05NN3dJREFRQUJBb0lCQUZDMXRVRW1ITlVjTTBCSgpNM0Q5S1F6Qis2M0YxbXdWbHgxUU9PVjFFZVZSM2NvNU94MVI2UFNyOXN5Y0ZHUTlqZ3FJMHpwNVRKZTlUcDZMCkdraGtsZlBoMU1Xbks5bzZ3bG56V0tYV3JycDJKbmkrbXBQeXVPUEFtcTRNYW5pdjJYZVArMGJST3dxcHlvanYKQUE3eUM3TStUSDIyNlpKR05WczNFVjkrY3dIbWwweXV6QmZJSm4vcnYvdzJnK1dSS00vTUMwUzdrMmQ4YlJsQQpOeWNLVkdBR0JoS1RsdGpvVllPZWg2YUhFcFNqSzh6ZmFlUGpvNWRZSnZvVklsaTYwWUNnY0pPVS84alhUK05wCjFGbTd0UnZBdGozcFVwMFNxZGFmMlJVemg5amZKcDJWRkNIdVNKNlRQcUFyT3lRb2p0TWNUSEYwVGlXN3hySFAKeE9DUklBRUNnWUVBd0dCUFU3dmR0aE1KQmcrT1JVb0dRUWFJdFRlSnZRd0lxSnZiS0Qyb3NwNGpoUzFkR1pCdwpXMzBHS0VjL2dkOEpOdE9xOUJCbk1pY1BGN2hrdHV5K2JTUHY0MVhQdWQ2N3JTU083VHN3MjBDMTBnRlJxMDZCCnpJSldGQVVxSzNJa3ZWYzNWRG10U0xTRG94NFFaL0JkcWFNbFE1eTVKQ3NDNWtUaG1rWkZsTzhDZ1lFQS9JOVgKWUhpNlJpb01KRTFmcU9ISkw0RERqbGV6bWN1UnJEN2ZFNUluS2J0SloySmhHWU9YL0MwS1huSFRPV1RDRHh4TgpGQnZwdkQ2WHY1bzNQaEI5WjZrMmZxdko0R1M4dXJrRy9LVTR4Y0MrYmFrKzlhdmE4b2FpU3FHMTZ6RDlOSDJQCmpKNjBOcmJMbDFKMHBVOWZpd3VGVlVLSjRoRFpPZk45UnFZZHlBRUNnWUFWd284V2hKaUdnTTZ6ZmN6MDczT1gKcFZxUFRQSHFqVkxwWjMrNXBJZlJkR3ZHSTZSMVFNNUV1dmFZVmI3TVBPTTQ3V1pYNXdjVk9DL1AyZzZpVmxNUAoyMUhHSUMyMzg0YTlCZmFZeE9vNDBxLytTaUhudzZDUTlta3dLSWxsa3Fxdk5BOVJHcGtNTVViMmkyOEZvcjJsCmM0dkNneGE2RFpkdFhuczZUUnFQeHdLQmdDZlk1Y3hPdi9UNkJWaGs3TWJVZU0ySjMxREIvWkF5VWhWL0Jlc3MKa0FsQmgxOU1ZazJJT1o2TDdLcmlBcFYzbERhV0hJTWp0RWtEQnlZdnlxOThJbzBNWVpDeXdmTXBjYTEwSytvSQpsMkI3L0krSXVHcENaeFVFc081ZGZUcFNUR0RQdnFwTkQ5bmlGVlVXcVZpN29UTnE2ZXA5eVF0bDVTQURqcXhxCjRTQUJBb0dBSW0waFVnMXd0Y1M0NmNHTHk2UElrUE01dG9jVFNnaHR6NHZGc3VrL2k0UUE5R0JvQk8yZ0g2dHkKK2tKSG1lYVh0MmRtZ3lTcDBRQVdpdDVVbGNlRXVtQjBOWG5BZEpaUXhlR1NGU3lZa0RXaHdYZDh3RGNlS28vMQpMZkNVNkRrOElOL1NzcHBWVVdYUTJybE9SdnhsckhlQ2lvOG8wa1M5WWl1NTVXTVlnNGc9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg=="
}`,
},
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
var logBuf bytes.Buffer
testLog := log.New(&logBuf, "", 0)
exited := "exiting via fatal"
fail = func(format string, v ...interface{}) {
testLog.Printf(format, v...)
panic(exited)
}
var sawSleep time.Duration
sleep = func(d time.Duration) { sawSleep = d }
var sawOutput bytes.Buffer
out = &sawOutput
if tt.failOutput {
out = &errWriter{}
}
os.Args = tt.args
getenv = func(key string) string { return tt.env[key] }
if tt.wantFail {
require.PanicsWithValue(t, exited, main)
} else {
require.NotPanics(t, main)
}
require.Equal(t, tt.wantSleep.String(), sawSleep.String())
require.Equal(t, tt.wantLog, logBuf.String())
if tt.wantOutJSON == "" {
require.Empty(t, sawOutput.String())
} else {
require.JSONEq(t, tt.wantOutJSON, sawOutput.String())
}
})
}
}

View File

@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICyDCCAbCgAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTIwMDcyNTIxMDQxOFoXDTMwMDcyMzIxMDQxOFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3K
hYv2gIQ1Dwzh2cWMid+ofAnvLIfV2Xv61vTLGprUI+XUqB4/gtf6X6UNn0Lett2n
d8p4wy7hw73hU/ggdvmWJvqBrSjc3JGfy+kj66fKXX+PTlbL7QbwiRvcSqIXIWlV
lHHxECWrED8jCulw/NVqfook/h5iNUCT9yswSJr/0fImiVnoTlIoEYG2eCNejZ5c
g39uD3ZTqd9ZxWwSLLnI+2kpJnZBPcd1ZQ8AQqzDgZtYRCqacn5gckQUKZWKQlxo
Eft6g1XHJouAWAZw7hEtk0v8rG0/eKF7wamxFi6BFVlbjWBsB4T9rApbdBWTKeCJ
Hv8fv5RMFSzpT3uzTO8CAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACh5RhbxqJe+Z/gc17cZhKNmdiwu
I2pLp3QBfwvN+Wbmajzw/7rYhY0d8JYVTJzXSCPWi6UAKxAtXOLF8WIIf9i39n6R
uKOBGW14FzzGyRJiD3qaG/JTvEW+SLhwl68Ndr5LHSnbugAqq31abcQy6Zl9v5A8
JKC97Lj/Sn8rj7opKy4W3oq7NCQsAb0zh4IllRF6UvSnJySfsg7xdXHHpxYDHtOS
XcOu5ySUIZTgFe9RfeUZlGZ5xn0ckMlQ7qW2Wx1q0OVWw5us4NtkGqKrHG4Tn1X7
uwo/Yytn5sDxrDv1/oii6AZOCsTPre4oD3wz4nmVzCVJcgrqH4Q24hT8WNg=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvcqFi/aAhDUPDOHZxYyJ36h8Ce8sh9XZe/rW9MsamtQj5dSo
Hj+C1/pfpQ2fQt623ad3ynjDLuHDveFT+CB2+ZYm+oGtKNzckZ/L6SPrp8pdf49O
VsvtBvCJG9xKohchaVWUcfEQJasQPyMK6XD81Wp+iiT+HmI1QJP3KzBImv/R8iaJ
WehOUigRgbZ4I16NnlyDf24PdlOp31nFbBIsucj7aSkmdkE9x3VlDwBCrMOBm1hE
KppyfmByRBQplYpCXGgR+3qDVccmi4BYBnDuES2TS/ysbT94oXvBqbEWLoEVWVuN
YGwHhP2sClt0FZMp4Ike/x+/lEwVLOlPe7NM7wIDAQABAoIBAFC1tUEmHNUcM0BJ
M3D9KQzB+63F1mwVlx1QOOV1EeVR3co5Ox1R6PSr9sycFGQ9jgqI0zp5TJe9Tp6L
GkhklfPh1MWnK9o6wlnzWKXWrrp2Jni+mpPyuOPAmq4Maniv2XeP+0bROwqpyojv
AA7yC7M+TH226ZJGNVs3EV9+cwHml0yuzBfIJn/rv/w2g+WRKM/MC0S7k2d8bRlA
NycKVGAGBhKTltjoVYOeh6aHEpSjK8zfaePjo5dYJvoVIli60YCgcJOU/8jXT+Np
1Fm7tRvAtj3pUp0Sqdaf2RUzh9jfJp2VFCHuSJ6TPqArOyQojtMcTHF0TiW7xrHP
xOCRIAECgYEAwGBPU7vdthMJBg+ORUoGQQaItTeJvQwIqJvbKD2osp4jhS1dGZBw
W30GKEc/gd8JNtOq9BBnMicPF7hktuy+bSPv41XPud67rSSO7Tsw20C10gFRq06B
zIJWFAUqK3IkvVc3VDmtSLSDox4QZ/BdqaMlQ5y5JCsC5kThmkZFlO8CgYEA/I9X
YHi6RioMJE1fqOHJL4DDjlezmcuRrD7fE5InKbtJZ2JhGYOX/C0KXnHTOWTCDxxN
FBvpvD6Xv5o3PhB9Z6k2fqvJ4GS8urkG/KU4xcC+bak+9ava8oaiSqG16zD9NH2P
jJ60NrbLl1J0pU9fiwuFVUKJ4hDZOfN9RqYdyAECgYAVwo8WhJiGgM6zfcz073OX
pVqPTPHqjVLpZ3+5pIfRdGvGI6R1QM5EuvaYVb7MPOM47WZX5wcVOC/P2g6iVlMP
21HGIC2384a9BfaYxOo40q/+SiHnw6CQ9mkwKIllkqqvNA9RGpkMMUb2i28For2l
c4vCgxa6DZdtXns6TRqPxwKBgCfY5cxOv/T6BVhk7MbUeM2J31DB/ZAyUhV/Bess
kAlBh19MYk2IOZ6L7KriApV3lDaWHIMjtEkDByYvyq98Io0MYZCywfMpca10K+oI
l2B7/I+IuGpCZxUEsO5dfTpSTGDPvqpND9niFVUWqVi7oTNq6ep9yQtl5SADjqxq
4SABAoGAIm0hUg1wtcS46cGLy6PIkPM5tocTSghtz4vFsuk/i4QA9GBoBO2gH6ty
+kJHmeaXt2dmgySp0QAWit5UlceEumB0NXnAdJZQxeGSFSyYkDWhwXd8wDceKo/1
LfCU6Dk8IN/SsppVUWXQ2rlORvxlrHeCio8o0kS9Yiu55WMYg4g=
-----END RSA PRIVATE KEY-----

View File

@@ -1,35 +0,0 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main
import (
"os"
"time"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/client-go/pkg/version"
"k8s.io/client-go/rest"
"k8s.io/component-base/logs"
"k8s.io/klog/v2"
"go.pinniped.dev/internal/concierge/server"
)
func main() {
logs.InitLogs()
defer logs.FlushLogs()
// Dump out the time since compile (mostly useful for benchmarking our local development cycle latency).
var timeSinceCompile time.Duration
if buildDate, err := time.Parse(time.RFC3339, version.Get().BuildDate); err == nil {
timeSinceCompile = time.Since(buildDate).Round(time.Second)
}
klog.Infof("Running %s at %#v (%s since build)", rest.DefaultKubernetesUserAgent(), version.Get(), timeSinceCompile)
ctx := genericapiserver.SetupSignalContext()
if err := server.New(ctx, os.Args[1:], os.Stdout, os.Stderr).Run(); err != nil {
klog.Fatal(err)
}
}

View File

@@ -0,0 +1,43 @@
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package main is the combined entrypoint for all Pinniped server components.
//
// It dispatches to the appropriate Main() entrypoint based the name it is invoked as (os.Args[0]). In our server
// container image, this binary is symlinked to several names such as `/usr/local/bin/pinniped-concierge`.
package main
import (
"os"
"path/filepath"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
concierge "go.pinniped.dev/internal/concierge/server"
// this side effect import ensures that we use fipsonly crypto in fips_strict mode.
_ "go.pinniped.dev/internal/crypto/ptls"
lua "go.pinniped.dev/internal/localuserauthenticator"
supervisor "go.pinniped.dev/internal/supervisor/server"
)
//nolint: gochecknoglobals // these are swapped during unit tests.
var (
fail = klog.Fatalf
subcommands = map[string]func(){
"pinniped-concierge": concierge.Main,
"pinniped-supervisor": supervisor.Main,
"local-user-authenticator": lua.Main,
}
)
func main() {
if len(os.Args) == 0 {
fail("missing os.Args")
}
binary := filepath.Base(os.Args[0])
if subcommands[binary] == nil {
fail("must be invoked as one of %v, not %q", sets.StringKeySet(subcommands).List(), binary)
}
subcommands[binary]()
}

View File

@@ -0,0 +1,72 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main
import (
"bytes"
"log"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestEntrypoint(t *testing.T) {
for _, tt := range []struct {
name string
args []string
wantOutput string
wantFail bool
wantArgs []string
}{
{
name: "missing args",
args: []string{},
wantOutput: "missing os.Args\n",
wantFail: true,
},
{
name: "invalid subcommand",
args: []string{"/path/to/invalid", "some", "args"},
wantOutput: "must be invoked as one of [another-test-binary valid-test-binary], not \"invalid\"\n",
wantFail: true,
},
{
name: "valid",
args: []string{"/path/to/valid-test-binary", "foo", "bar"},
wantArgs: []string{"/path/to/valid-test-binary", "foo", "bar"},
},
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
var logBuf bytes.Buffer
testLog := log.New(&logBuf, "", 0)
exited := "exiting via fatal"
fail = func(format string, v ...interface{}) {
testLog.Printf(format, v...)
panic(exited)
}
// Make a test command that records os.Args when it's invoked.
var gotArgs []string
subcommands = map[string]func(){
"valid-test-binary": func() { gotArgs = os.Args },
"another-test-binary": func() {},
}
os.Args = tt.args
if tt.wantFail {
require.PanicsWithValue(t, exited, main)
} else {
require.NotPanics(t, main)
}
if tt.wantArgs != nil {
require.Equal(t, tt.wantArgs, gotArgs)
}
if tt.wantOutput != "" {
require.Equal(t, tt.wantOutput, logBuf.String())
}
})
}
}

View File

@@ -1,11 +1,10 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/json"
@@ -28,12 +27,13 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth" // Adds handlers for various dynamic auth plugins in client-go
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/transport"
conciergev1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
"go.pinniped.dev/internal/groupsuffix"
"go.pinniped.dev/internal/net/phttp"
)
type kubeconfigDeps struct {
@@ -61,12 +61,14 @@ type getKubeconfigOIDCParams struct {
listenPort uint16
scopes []string
skipBrowser bool
skipListen bool
sessionCachePath string
debugSessionCache bool
caBundle caBundleFlag
requestAudience string
upstreamIDPName string
upstreamIDPType string
upstreamIDPFlow string
}
type getKubeconfigConciergeParams struct {
@@ -94,23 +96,7 @@ type getKubeconfigParams struct {
generatedNameSuffix string
credentialCachePath string
credentialCachePathSet bool
}
type supervisorOIDCDiscoveryResponseWithV1Alpha1 struct {
SupervisorDiscovery SupervisorDiscoveryResponseV1Alpha1 `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
type SupervisorDiscoveryResponseV1Alpha1 struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
type supervisorIDPsDiscoveryResponseV1Alpha1 struct {
PinnipedIDPs []pinnipedIDPResponse `json:"pinniped_identity_providers"`
}
type pinnipedIDPResponse struct {
Name string `json:"name"`
Type string `json:"type"`
installHint string
}
func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
@@ -146,12 +132,14 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
f.Uint16Var(&flags.oidc.listenPort, "oidc-listen-port", 0, "TCP port for localhost listener (authorization code flow only)")
f.StringSliceVar(&flags.oidc.scopes, "oidc-scopes", []string{oidc.ScopeOfflineAccess, oidc.ScopeOpenID, "pinniped:request-audience"}, "OpenID Connect scopes to request during login")
f.BoolVar(&flags.oidc.skipBrowser, "oidc-skip-browser", false, "During OpenID Connect login, skip opening the browser (just print the URL)")
f.BoolVar(&flags.oidc.skipListen, "oidc-skip-listen", false, "During OpenID Connect login, skip starting a localhost callback listener (manual copy/paste flow only)")
f.StringVar(&flags.oidc.sessionCachePath, "oidc-session-cache", "", "Path to OpenID Connect session cache file")
f.Var(&flags.oidc.caBundle, "oidc-ca-bundle", "Path to TLS certificate authority bundle (PEM format, optional, can be repeated)")
f.BoolVar(&flags.oidc.debugSessionCache, "oidc-debug-session-cache", false, "Print debug logs related to the OpenID Connect session cache")
f.StringVar(&flags.oidc.requestAudience, "oidc-request-audience", "", "Request a token with an alternate audience using RFC8693 token exchange")
f.StringVar(&flags.oidc.upstreamIDPName, "upstream-identity-provider-name", "", "The name of the upstream identity provider used during login with a Supervisor")
f.StringVar(&flags.oidc.upstreamIDPType, "upstream-identity-provider-type", "", "The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap')")
f.StringVar(&flags.oidc.upstreamIDPType, "upstream-identity-provider-type", "", fmt.Sprintf("The type of the upstream identity provider used during login with a Supervisor (e.g. '%s', '%s', '%s')", idpdiscoveryv1alpha1.IDPTypeOIDC, idpdiscoveryv1alpha1.IDPTypeLDAP, idpdiscoveryv1alpha1.IDPTypeActiveDirectory))
f.StringVar(&flags.oidc.upstreamIDPFlow, "upstream-identity-provider-flow", "", fmt.Sprintf("The type of client flow to use with the upstream identity provider during login with a Supervisor (e.g. '%s', '%s')", idpdiscoveryv1alpha1.IDPFlowCLIPassword, idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode))
f.StringVar(&flags.kubeconfigPath, "kubeconfig", os.Getenv("KUBECONFIG"), "Path to kubeconfig file")
f.StringVar(&flags.kubeconfigContextOverride, "kubeconfig-context", "", "Kubeconfig context name (default: current active context)")
f.BoolVar(&flags.skipValidate, "skip-validation", false, "Skip final validation of the kubeconfig (default: false)")
@@ -159,8 +147,12 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
f.StringVarP(&flags.outputPath, "output", "o", "", "Output file path (default: stdout)")
f.StringVar(&flags.generatedNameSuffix, "generated-name-suffix", "-pinniped", "Suffix to append to generated cluster, context, user kubeconfig entries")
f.StringVar(&flags.credentialCachePath, "credential-cache", "", "Path to cluster-specific credentials cache")
f.StringVar(&flags.installHint, "install-hint", "The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli for more details", "This text is shown to the user when the pinniped CLI is not installed.")
mustMarkHidden(cmd, "oidc-debug-session-cache")
// --oidc-skip-listen is mainly needed for testing. We'll leave it hidden until we have a non-testing use case.
mustMarkHidden(cmd, "oidc-skip-listen")
mustMarkDeprecated(cmd, "concierge-namespace", "not needed anymore")
mustMarkHidden(cmd, "concierge-namespace")
@@ -179,7 +171,6 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
return cmd
}
//nolint:funlen
func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, flags getKubeconfigParams) error {
ctx, cancel := context.WithTimeout(ctx, flags.timeout)
defer cancel()
@@ -238,8 +229,10 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
cluster.CertificateAuthorityData = flags.concierge.caBundle
}
// If there is an issuer, and if both upstream flags are not already set, then try to discover Supervisor upstream IDP.
if len(flags.oidc.issuer) > 0 && (flags.oidc.upstreamIDPType == "" || flags.oidc.upstreamIDPName == "") {
// If there is an issuer, and if any upstream IDP flags are not already set, then try to discover Supervisor upstream IDP details.
// When all the upstream IDP flags are set by the user, then skip discovery and don't validate their input. Maybe they know something
// that we can't know, like the name of an IDP that they are going to define in the future.
if len(flags.oidc.issuer) > 0 && (flags.oidc.upstreamIDPType == "" || flags.oidc.upstreamIDPName == "" || flags.oidc.upstreamIDPFlow == "") {
if err := discoverSupervisorUpstreamIDP(ctx, &flags); err != nil {
return err
}
@@ -266,6 +259,7 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
ProvideClusterInfo: true,
}
execConfig.InstallHint = flags.installHint
var err error
execConfig.Command, err = deps.getPathToSelf()
if err != nil {
@@ -317,6 +311,9 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
if flags.oidc.skipBrowser {
execConfig.Args = append(execConfig.Args, "--skip-browser")
}
if flags.oidc.skipListen {
execConfig.Args = append(execConfig.Args, "--skip-listen")
}
if flags.oidc.listenPort != 0 {
execConfig.Args = append(execConfig.Args, "--listen-port="+strconv.Itoa(int(flags.oidc.listenPort)))
}
@@ -338,6 +335,9 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
if flags.oidc.upstreamIDPType != "" {
execConfig.Args = append(execConfig.Args, "--upstream-identity-provider-type="+flags.oidc.upstreamIDPType)
}
if flags.oidc.upstreamIDPFlow != "" {
execConfig.Args = append(execConfig.Args, "--upstream-identity-provider-flow="+flags.oidc.upstreamIDPFlow)
}
return execConfig, nil
}
@@ -662,17 +662,8 @@ func validateKubeconfig(ctx context.Context, flags getKubeconfigParams, kubeconf
return fmt.Errorf("invalid kubeconfig (no certificateAuthorityData)")
}
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
RootCAs: kubeconfigCA,
},
Proxy: http.ProxyFromEnvironment,
TLSHandshakeTimeout: 10 * time.Second,
},
Timeout: 10 * time.Second,
}
httpClient := phttp.Default(kubeconfigCA)
httpClient.Timeout = 10 * time.Second
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
@@ -723,7 +714,7 @@ func validateKubeconfig(ctx context.Context, flags getKubeconfigParams, kubeconf
func countCACerts(pemData []byte) int {
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(pemData)
return len(pool.Subjects())
return len(pool.Subjects()) // nolint: staticcheck // not system cert pool
}
func hasPendingStrategy(credentialIssuer *configv1alpha1.CredentialIssuer) bool {
@@ -750,40 +741,43 @@ func discoverSupervisorUpstreamIDP(ctx context.Context, flags *getKubeconfigPara
return nil
}
upstreamIDPs, err := discoverAllAvailableSupervisorUpstreamIDPs(ctx, pinnipedIDPsEndpoint, httpClient)
discoveredUpstreamIDPs, err := discoverAllAvailableSupervisorUpstreamIDPs(ctx, pinnipedIDPsEndpoint, httpClient)
if err != nil {
return err
}
if len(upstreamIDPs) == 1 {
flags.oidc.upstreamIDPName = upstreamIDPs[0].Name
flags.oidc.upstreamIDPType = upstreamIDPs[0].Type
} else if len(upstreamIDPs) > 1 {
idpName, idpType, err := selectUpstreamIDP(upstreamIDPs, flags.oidc.upstreamIDPName, flags.oidc.upstreamIDPType)
if err != nil {
return err
}
flags.oidc.upstreamIDPName = idpName
flags.oidc.upstreamIDPType = idpType
if len(discoveredUpstreamIDPs) == 0 {
// Discovered that the Supervisor does not have any upstream IDPs defined. Continue without putting one into the
// kubeconfig. This kubeconfig will only work if the user defines one (and only one) OIDC IDP in the Supervisor
// later and wants to use the default client flow for OIDC (browser-based auth).
return nil
}
selectedIDPName, selectedIDPType, discoveredIDPFlows, err := selectUpstreamIDPNameAndType(discoveredUpstreamIDPs, flags.oidc.upstreamIDPName, flags.oidc.upstreamIDPType)
if err != nil {
return err
}
selectedIDPFlow, err := selectUpstreamIDPFlow(discoveredIDPFlows, selectedIDPName, selectedIDPType, flags.oidc.upstreamIDPFlow)
if err != nil {
return err
}
flags.oidc.upstreamIDPName = selectedIDPName
flags.oidc.upstreamIDPType = selectedIDPType.String()
flags.oidc.upstreamIDPFlow = selectedIDPFlow.String()
return nil
}
func newDiscoveryHTTPClient(caBundleFlag caBundleFlag) (*http.Client, error) {
t := &http.Transport{
TLSClientConfig: &tls.Config{MinVersion: tls.VersionTLS12},
Proxy: http.ProxyFromEnvironment,
}
httpClient := &http.Client{Transport: t}
var rootCAs *x509.CertPool
if caBundleFlag != nil {
rootCAs := x509.NewCertPool()
ok := rootCAs.AppendCertsFromPEM(caBundleFlag)
if !ok {
rootCAs = x509.NewCertPool()
if ok := rootCAs.AppendCertsFromPEM(caBundleFlag); !ok {
return nil, fmt.Errorf("unable to fetch OIDC discovery data from issuer: could not parse CA bundle")
}
t.TLSClientConfig.RootCAs = rootCAs
}
httpClient.Transport = transport.DebugWrappers(httpClient.Transport)
return httpClient, nil
return phttp.Default(rootCAs), nil
}
func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpClient *http.Client) (string, error) {
@@ -792,7 +786,7 @@ func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpCl
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
}
var body supervisorOIDCDiscoveryResponseWithV1Alpha1
var body idpdiscoveryv1alpha1.OIDCDiscoveryResponse
err = discoveredProvider.Claims(&body)
if err != nil {
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
@@ -801,7 +795,7 @@ func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpCl
return body.SupervisorDiscovery.PinnipedIDPsEndpoint, nil
}
func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDPsEndpoint string, httpClient *http.Client) ([]pinnipedIDPResponse, error) {
func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDPsEndpoint string, httpClient *http.Client) ([]idpdiscoveryv1alpha1.PinnipedIDP, error) {
request, err := http.NewRequestWithContext(ctx, http.MethodGet, pinnipedIDPsEndpoint, nil)
if err != nil {
return nil, fmt.Errorf("while forming request to IDP discovery URL: %w", err)
@@ -823,7 +817,7 @@ func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDP
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not read response body: %w", err)
}
var body supervisorIDPsDiscoveryResponseV1Alpha1
var body idpdiscoveryv1alpha1.IDPDiscoveryResponse
err = json.Unmarshal(rawBody, &body)
if err != nil {
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not parse response JSON: %w", err)
@@ -832,53 +826,106 @@ func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDP
return body.PinnipedIDPs, nil
}
func selectUpstreamIDP(pinnipedIDPs []pinnipedIDPResponse, idpName, idpType string) (string, string, error) {
func selectUpstreamIDPNameAndType(pinnipedIDPs []idpdiscoveryv1alpha1.PinnipedIDP, specifiedIDPName, specifiedIDPType string) (string, idpdiscoveryv1alpha1.IDPType, []idpdiscoveryv1alpha1.IDPFlow, error) {
pinnipedIDPsString, _ := json.Marshal(pinnipedIDPs)
var discoveredFlows []idpdiscoveryv1alpha1.IDPFlow
switch {
case idpType != "":
discoveredName := ""
case specifiedIDPName != "" && specifiedIDPType != "":
// The user specified both name and type, so check to see if there exists an exact match.
for _, idp := range pinnipedIDPs {
if idp.Type == idpType {
if idp.Name == specifiedIDPName && idp.Type.Equals(specifiedIDPType) {
return specifiedIDPName, idp.Type, idp.Flows, nil
}
}
return "", "", nil, fmt.Errorf(
"no Supervisor upstream identity providers with name %q of type %q were found. "+
"Found these upstreams: %s", specifiedIDPName, specifiedIDPType, pinnipedIDPsString)
case specifiedIDPType != "":
// The user specified only a type, so check if there is only one of that type found.
discoveredName := ""
var discoveredType idpdiscoveryv1alpha1.IDPType
for _, idp := range pinnipedIDPs {
if idp.Type.Equals(specifiedIDPType) {
if discoveredName != "" {
return "", "", fmt.Errorf(
"multiple Supervisor upstream identity providers of type \"%s\" were found,"+
" so the --upstream-identity-provider-name flag must be specified. "+
return "", "", nil, fmt.Errorf(
"multiple Supervisor upstream identity providers of type %q were found, "+
"so the --upstream-identity-provider-name flag must be specified. "+
"Found these upstreams: %s",
idpType, pinnipedIDPsString)
specifiedIDPType, pinnipedIDPsString)
}
discoveredName = idp.Name
discoveredType = idp.Type
discoveredFlows = idp.Flows
}
}
if discoveredName == "" {
return "", "", fmt.Errorf(
"no Supervisor upstream identity providers of type \"%s\" were found."+
" Found these upstreams: %s", idpType, pinnipedIDPsString)
return "", "", nil, fmt.Errorf(
"no Supervisor upstream identity providers of type %q were found. "+
"Found these upstreams: %s", specifiedIDPType, pinnipedIDPsString)
}
return discoveredName, idpType, nil
case idpName != "":
discoveredType := ""
return discoveredName, discoveredType, discoveredFlows, nil
case specifiedIDPName != "":
// The user specified only a name, so check if there is only one of that name found.
var discoveredType idpdiscoveryv1alpha1.IDPType
for _, idp := range pinnipedIDPs {
if idp.Name == idpName {
if idp.Name == specifiedIDPName {
if discoveredType != "" {
return "", "", fmt.Errorf(
"multiple Supervisor upstream identity providers with name \"%s\" were found,"+
" so the --upstream-identity-provider-type flag must be specified. Found these upstreams: %s",
idpName, pinnipedIDPsString)
return "", "", nil, fmt.Errorf(
"multiple Supervisor upstream identity providers with name %q were found, "+
"so the --upstream-identity-provider-type flag must be specified. Found these upstreams: %s",
specifiedIDPName, pinnipedIDPsString)
}
discoveredType = idp.Type
discoveredFlows = idp.Flows
}
}
if discoveredType == "" {
return "", "", fmt.Errorf(
"no Supervisor upstream identity providers with name \"%s\" were found."+
" Found these upstreams: %s", idpName, pinnipedIDPsString)
return "", "", nil, fmt.Errorf(
"no Supervisor upstream identity providers with name %q were found. "+
"Found these upstreams: %s", specifiedIDPName, pinnipedIDPsString)
}
return idpName, discoveredType, nil
return specifiedIDPName, discoveredType, discoveredFlows, nil
case len(pinnipedIDPs) == 1:
// The user did not specify any name or type, but there is only one found, so select it.
return pinnipedIDPs[0].Name, pinnipedIDPs[0].Type, pinnipedIDPs[0].Flows, nil
default:
return "", "", fmt.Errorf(
"multiple Supervisor upstream identity providers were found,"+
" so the --upstream-identity-provider-name/--upstream-identity-provider-type flags must be specified."+
" Found these upstreams: %s",
// The user did not specify any name or type, and there is more than one found.
return "", "", nil, fmt.Errorf(
"multiple Supervisor upstream identity providers were found, "+
"so the --upstream-identity-provider-name/--upstream-identity-provider-type flags must be specified. "+
"Found these upstreams: %s",
pinnipedIDPsString)
}
}
func selectUpstreamIDPFlow(discoveredIDPFlows []idpdiscoveryv1alpha1.IDPFlow, selectedIDPName string, selectedIDPType idpdiscoveryv1alpha1.IDPType, specifiedFlow string) (idpdiscoveryv1alpha1.IDPFlow, error) {
switch {
case len(discoveredIDPFlows) == 0:
// No flows listed by discovery means that we are talking to an old Supervisor from before this feature existed.
// If the user specified a flow on the CLI flag then use it without validation, otherwise skip flow selection
// and return empty string.
return idpdiscoveryv1alpha1.IDPFlow(specifiedFlow), nil
case specifiedFlow != "":
// The user specified a flow, so validate that it is available for the selected IDP.
for _, flow := range discoveredIDPFlows {
if flow.Equals(specifiedFlow) {
// Found it, so use it as specified by the user.
return flow, nil
}
}
return "", fmt.Errorf(
"no client flow %q for Supervisor upstream identity provider %q of type %q were found. "+
"Found these flows: %v",
specifiedFlow, selectedIDPName, selectedIDPType, discoveredIDPFlows)
case len(discoveredIDPFlows) == 1:
// The user did not specify a flow, but there is only one found, so select it.
return discoveredIDPFlows[0], nil
default:
// The user did not specify a flow, and more than one was found.
return "", fmt.Errorf(
"multiple client flows for Supervisor upstream identity provider %q of type %q were found, "+
"so the --upstream-identity-provider-flow flag must be specified. "+
"Found these flows: %v",
selectedIDPName, selectedIDPType, discoveredIDPFlows)
}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
@@ -133,6 +133,7 @@ func TestGetKubeconfig(t *testing.T) {
--credential-cache string Path to cluster-specific credentials cache
--generated-name-suffix string Suffix to append to generated cluster, context, user kubeconfig entries (default "-pinniped")
-h, --help help for kubeconfig
--install-hint string This text is shown to the user when the pinniped CLI is not installed. (default "The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli for more details")
--kubeconfig string Path to kubeconfig file
--kubeconfig-context string Kubeconfig context name (default: current active context)
--no-concierge Generate a configuration which does not use the Concierge, but sends the credential to the cluster directly
@@ -149,8 +150,9 @@ func TestGetKubeconfig(t *testing.T) {
--static-token string Instead of doing an OIDC-based login, specify a static token
--static-token-env string Instead of doing an OIDC-based login, read a static token from the environment
--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')
--upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap', 'activedirectory')
`)
},
},
@@ -814,7 +816,7 @@ func TestGetKubeconfig(t *testing.T) {
},
},
{
name: "when IDP discovery document contains multiple pinniped_idps and no name or type flags are given",
name: "when IDP discovery document contains multiple IDPs and no name or type flags are given",
args: func(issuerCABundle string, issuerURL string) []string {
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
@@ -953,7 +955,7 @@ func TestGetKubeconfig(t *testing.T) {
},
wantError: true,
wantStderr: func(issuerCABundle string, issuerURL string) string {
return fmt.Sprintf("Error: while fetching OIDC discovery data from issuer: Get \"%s/.well-known/openid-configuration\": x509: certificate signed by unknown authority\n", issuerURL)
return fmt.Sprintf("Error: while fetching OIDC discovery data from issuer: Get \"%s/.well-known/openid-configuration\": %s\n", issuerURL, testutil.X509UntrustedCertError("Acme Co"))
},
},
{
@@ -1033,6 +1035,33 @@ func TestGetKubeconfig(t *testing.T) {
return `Error: while forming request to IDP discovery URL: parse "https%://illegal_url": first path segment in URL cannot contain colon` + "\n"
},
},
{
name: "supervisor upstream IDP discovery does not find matching IDP when name and type are both specified",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-name", "does-not-exist-idp",
"--upstream-identity-provider-type", "ldap",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-ldap-idp", "type": "ldap"},
{"name": "some-other-ldap-idp", "type": "ldap"}
]
}`),
wantError: true,
wantStderr: func(issuerCABundle string, issuerURL string) string {
return `Error: no Supervisor upstream identity providers with name "does-not-exist-idp" of type "ldap" were found.` +
` Found these upstreams: [{"name":"some-ldap-idp","type":"ldap"},{"name":"some-other-ldap-idp","type":"ldap"}]` + "\n"
},
},
{
name: "supervisor upstream IDP discovery fails to resolve ambiguity when type is specified but name is not",
args: func(issuerCABundle string, issuerURL string) []string {
@@ -1091,7 +1120,7 @@ func TestGetKubeconfig(t *testing.T) {
},
},
{
name: "supervisor upstream IDP discovery fails to find any matching idps when type is specified but name is not",
name: "supervisor upstream IDP discovery fails to find any matching IDPs when type is specified but name is not",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
@@ -1117,7 +1146,32 @@ func TestGetKubeconfig(t *testing.T) {
},
},
{
name: "supervisor upstream IDP discovery fails to find any matching idps when name is specified but type is not",
name: "supervisor upstream IDP discovery fails to find any matching IDPs when type is specified but name is not and there is only one IDP found",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-type", "ldap",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-oidc-idp", "type": "oidc"}
]
}`),
wantError: true,
wantStderr: func(issuerCABundle string, issuerURL string) string {
return `Error: no Supervisor upstream identity providers of type "ldap" were found.` +
` Found these upstreams: [{"name":"some-oidc-idp","type":"oidc"}]` + "\n"
},
},
{
name: "supervisor upstream IDP discovery fails to find any matching IDPs when name is specified but type is not",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
@@ -1142,6 +1196,80 @@ func TestGetKubeconfig(t *testing.T) {
` Found these upstreams: [{"name":"some-oidc-idp","type":"oidc"},{"name":"some-other-oidc-idp","type":"oidc"}]` + "\n"
},
},
{
name: "supervisor upstream IDP discovery fails to find any matching IDPs when name is specified but type is not and there is only one IDP found",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-name", "my-nonexistent-idp",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-oidc-idp", "type": "oidc"}
]
}`),
wantError: true,
wantStderr: func(issuerCABundle string, issuerURL string) string {
return `Error: no Supervisor upstream identity providers with name "my-nonexistent-idp" were found.` +
` Found these upstreams: [{"name":"some-oidc-idp","type":"oidc"}]` + "\n"
},
},
{
name: "supervisor upstream IDP discovery when flow is specified but it does not match any flow returned by discovery",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-flow", "my-nonexistent-flow",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-oidc-idp", "type": "oidc", "flows": ["non-matching-flow-1", "non-matching-flow-2"]}
]
}`),
wantError: true,
wantStderr: func(issuerCABundle string, issuerURL string) string {
return `Error: no client flow "my-nonexistent-flow" for Supervisor upstream identity provider "some-oidc-idp" of type "oidc" were found.` +
` Found these flows: [non-matching-flow-1 non-matching-flow-2]` + "\n"
},
},
{
name: "supervisor upstream IDP discovery when no flow is specified and more than one flow is returned by discovery",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-oidc-idp", "type": "oidc", "flows": ["flow1", "flow2"]}
]
}`),
wantError: true,
wantStderr: func(issuerCABundle string, issuerURL string) string {
return `Error: multiple client flows for Supervisor upstream identity provider "some-oidc-idp" of type "oidc" were found, so the --upstream-identity-provider-flow flag must be specified.` +
` Found these flows: [flow1 flow2]` + "\n"
},
},
{
name: "valid static token",
args: func(issuerCABundle string, issuerURL string) []string {
@@ -1199,6 +1327,8 @@ func TestGetKubeconfig(t *testing.T) {
- --token=test-token
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`)
},
@@ -1262,6 +1392,8 @@ func TestGetKubeconfig(t *testing.T) {
- --token-env=TEST_TOKEN
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`)
},
@@ -1330,6 +1462,8 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -1352,6 +1486,7 @@ func TestGetKubeconfig(t *testing.T) {
"--concierge-ca-bundle", testConciergeCABundlePath,
"--oidc-issuer", issuerURL,
"--oidc-skip-browser",
"--oidc-skip-listen",
"--oidc-listen-port", "1234",
"--oidc-ca-bundle", f.Name(),
"--oidc-session-cache", "/path/to/cache/dir/sessions.yaml",
@@ -1405,6 +1540,7 @@ func TestGetKubeconfig(t *testing.T) {
- --client-id=pinniped-cli
- --scopes=offline_access,openid,pinniped:request-audience
- --skip-browser
- --skip-listen
- --listen-port=1234
- --ca-bundle-data=%s
- --session-cache=/path/to/cache/dir/sessions.yaml
@@ -1412,6 +1548,8 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
base64.StdEncoding.EncodeToString(testConciergeCA.Bundle()),
@@ -1523,6 +1661,8 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
base64.StdEncoding.EncodeToString(testConciergeCA.Bundle()),
@@ -1533,7 +1673,7 @@ func TestGetKubeconfig(t *testing.T) {
},
},
{
name: "autodetect impersonation proxy with autodiscovered JWT authenticator",
name: "autodetect impersonation proxy with auto-discovered JWT authenticator",
args: func(issuerCABundle string, issuerURL string) []string {
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
@@ -1630,6 +1770,8 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -1707,6 +1849,8 @@ func TestGetKubeconfig(t *testing.T) {
- --upstream-identity-provider-type=ldap
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -1784,6 +1928,8 @@ func TestGetKubeconfig(t *testing.T) {
- --upstream-identity-provider-type=oidc
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -1857,6 +2003,8 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -1928,6 +2076,8 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -1956,7 +2106,7 @@ func TestGetKubeconfig(t *testing.T) {
}
}`, issuerURL)
},
idpsDiscoveryStatusCode: http.StatusBadRequest, // IDPs endpoint shouldn't be called by this test
idpsDiscoveryStatusCode: http.StatusBadRequest, // IDP discovery endpoint shouldn't be called by this test
wantLogs: func(issuerCABundle string, issuerURL string) []string {
return []string{
`"level"=0 "msg"="discovered CredentialIssuer" "name"="test-credential-issuer"`,
@@ -2006,6 +2156,8 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -2013,13 +2165,14 @@ func TestGetKubeconfig(t *testing.T) {
},
},
{
name: "when upstream idp related flags are sent, pass them through",
name: "when all upstream IDP related flags are sent, pass them through without performing IDP discovery",
args: func(issuerCABundle string, issuerURL string) []string {
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--upstream-identity-provider-name=some-oidc-idp",
"--upstream-identity-provider-type=oidc",
"--upstream-identity-provider-flow=foobar",
}
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
@@ -2028,7 +2181,7 @@ func TestGetKubeconfig(t *testing.T) {
jwtAuthenticator(issuerCABundle, issuerURL),
}
},
oidcDiscoveryStatusCode: http.StatusNotFound,
oidcDiscoveryStatusCode: http.StatusNotFound, // should not get called by the client in this case
wantLogs: func(issuerCABundle string, issuerURL string) []string {
return []string{
`"level"=0 "msg"="discovered CredentialIssuer" "name"="test-credential-issuer"`,
@@ -2078,8 +2231,11 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
- --upstream-identity-provider-name=some-oidc-idp
- --upstream-identity-provider-type=oidc
- --upstream-identity-provider-flow=foobar
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -2087,13 +2243,14 @@ func TestGetKubeconfig(t *testing.T) {
},
},
{
name: "when upstream IDP related flags are sent, pass them through even when IDP discovery shows a different IDP",
name: "when all upstream IDP related flags are sent, pass them through even when IDP discovery shows a different IDP",
args: func(issuerCABundle string, issuerURL string) []string {
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--upstream-identity-provider-name=some-oidc-idp",
"--upstream-identity-provider-type=oidc",
"--upstream-identity-provider-flow=foobar",
}
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
@@ -2157,8 +2314,11 @@ func TestGetKubeconfig(t *testing.T) {
- --request-audience=test-audience
- --upstream-identity-provider-name=some-oidc-idp
- --upstream-identity-provider-type=oidc
- --upstream-identity-provider-flow=foobar
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -2215,6 +2375,8 @@ func TestGetKubeconfig(t *testing.T) {
- --upstream-identity-provider-type=ldap
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -2274,6 +2436,8 @@ func TestGetKubeconfig(t *testing.T) {
- --upstream-identity-provider-type=ldap
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
@@ -2333,11 +2497,322 @@ func TestGetKubeconfig(t *testing.T) {
- --upstream-identity-provider-type=ldap
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
},
}, // TODO make sure there are active directory tests for various flows
{
name: "supervisor upstream IDP discovery when both name and type are specified but flow is not and a matching IDP is found",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-name", "some-ldap-idp",
"--upstream-identity-provider-type", "ldap",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-ldap-idp", "type": "ldap"},
{"name": "some-oidc-idp", "type": "oidc"},
{"name": "some-other-oidc-idp", "type": "oidc"}
]
}`),
wantStdout: func(issuerCABundle string, issuerURL string) string {
return here.Docf(`
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
server: https://fake-server-url-value
name: kind-cluster-pinniped
contexts:
- context:
cluster: kind-cluster-pinniped
user: kind-user-pinniped
name: kind-context-pinniped
current-context: kind-context-pinniped
kind: Config
preferences: {}
users:
- name: kind-user-pinniped
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- login
- oidc
- --issuer=%s
- --client-id=pinniped-cli
- --scopes=offline_access,openid,pinniped:request-audience
- --ca-bundle-data=%s
- --upstream-identity-provider-name=some-ldap-idp
- --upstream-identity-provider-type=ldap
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
},
},
{
name: "supervisor upstream IDP discovery when flow is specified and no flows were returned by discovery uses the specified flow",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-flow", "foobar",
"--upstream-identity-provider-type", "ldap",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-ldap-idp", "type": "ldap"},
{"name": "some-oidc-idp", "type": "oidc"},
{"name": "some-other-oidc-idp", "type": "oidc"}
]
}`),
wantStdout: func(issuerCABundle string, issuerURL string) string {
return here.Docf(`
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
server: https://fake-server-url-value
name: kind-cluster-pinniped
contexts:
- context:
cluster: kind-cluster-pinniped
user: kind-user-pinniped
name: kind-context-pinniped
current-context: kind-context-pinniped
kind: Config
preferences: {}
users:
- name: kind-user-pinniped
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- login
- oidc
- --issuer=%s
- --client-id=pinniped-cli
- --scopes=offline_access,openid,pinniped:request-audience
- --ca-bundle-data=%s
- --upstream-identity-provider-name=some-ldap-idp
- --upstream-identity-provider-type=ldap
- --upstream-identity-provider-flow=foobar
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
},
},
{
name: "supervisor upstream IDP discovery when flow is specified and it matches a flow returned by discovery uses the specified flow",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-flow", "cli_password",
"--upstream-identity-provider-type", "ldap",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-ldap-idp", "type": "ldap", "flows": ["some_flow", "cli_password", "some_other_flow"]}
]
}`),
wantStdout: func(issuerCABundle string, issuerURL string) string {
return here.Docf(`
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
server: https://fake-server-url-value
name: kind-cluster-pinniped
contexts:
- context:
cluster: kind-cluster-pinniped
user: kind-user-pinniped
name: kind-context-pinniped
current-context: kind-context-pinniped
kind: Config
preferences: {}
users:
- name: kind-user-pinniped
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- login
- oidc
- --issuer=%s
- --client-id=pinniped-cli
- --scopes=offline_access,openid,pinniped:request-audience
- --ca-bundle-data=%s
- --upstream-identity-provider-name=some-ldap-idp
- --upstream-identity-provider-type=ldap
- --upstream-identity-provider-flow=cli_password
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
},
},
{
name: "supervisor upstream IDP discovery when no flow is specified but there is only one flow returned by discovery uses the discovered flow",
args: func(issuerCABundle string, issuerURL string) []string {
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--skip-validation",
"--no-concierge",
"--oidc-issuer", issuerURL,
"--oidc-ca-bundle", f.Name(),
"--upstream-identity-provider-type", "ldap",
}
},
oidcDiscoveryResponse: happyOIDCDiscoveryResponse,
idpsDiscoveryResponse: here.Docf(`{
"pinniped_identity_providers": [
{"name": "some-ldap-idp", "type": "ldap", "flows": ["cli_password"]}
]
}`),
wantStdout: func(issuerCABundle string, issuerURL string) string {
return here.Docf(`
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
server: https://fake-server-url-value
name: kind-cluster-pinniped
contexts:
- context:
cluster: kind-cluster-pinniped
user: kind-user-pinniped
name: kind-context-pinniped
current-context: kind-context-pinniped
kind: Config
preferences: {}
users:
- name: kind-user-pinniped
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- login
- oidc
- --issuer=%s
- --client-id=pinniped-cli
- --scopes=offline_access,openid,pinniped:request-audience
- --ca-bundle-data=%s
- --upstream-identity-provider-name=some-ldap-idp
- --upstream-identity-provider-type=ldap
- --upstream-identity-provider-flow=cli_password
command: '.../path/to/pinniped'
env: []
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
for more details
provideClusterInfo: true
`,
issuerURL,
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
},
},
{
name: "user specified message for install-hint flag",
args: func(issuerCABundle string, issuerURL string) []string {
return []string{
"--kubeconfig", "./testdata/kubeconfig.yaml",
"--install-hint", "Test installHint message",
"--static-token", "test-token",
"--skip-validation",
}
},
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
return []runtime.Object{
credentialIssuer(),
&conciergev1alpha1.WebhookAuthenticator{ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"}},
}
},
wantLogs: func(issuerCABundle string, issuerURL string) []string {
return []string{
`"level"=0 "msg"="discovered CredentialIssuer" "name"="test-credential-issuer"`,
`"level"=0 "msg"="discovered Concierge operating in TokenCredentialRequest API mode"`,
`"level"=0 "msg"="discovered Concierge endpoint" "endpoint"="https://fake-server-url-value"`,
`"level"=0 "msg"="discovered Concierge certificate authority bundle" "roots"=0`,
`"level"=0 "msg"="discovered WebhookAuthenticator" "name"="test-authenticator"`,
}
},
wantStdout: func(issuerCABundle string, issuerURL string) string {
return here.Doc(`
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
server: https://fake-server-url-value
name: kind-cluster-pinniped
contexts:
- context:
cluster: kind-cluster-pinniped
user: kind-user-pinniped
name: kind-context-pinniped
current-context: kind-context-pinniped
kind: Config
preferences: {}
users:
- name: kind-user-pinniped
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- login
- static
- --enable-concierge
- --concierge-api-group-suffix=pinniped.dev
- --concierge-authenticator-name=test-authenticator
- --concierge-authenticator-type=webhook
- --concierge-endpoint=https://fake-server-url-value
- --concierge-ca-bundle-data=ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
- --token=test-token
command: '.../path/to/pinniped'
env: []
installHint: Test installHint message
provideClusterInfo: true
`)
},
},
}
for _, tt := range tests {
@@ -2375,7 +2850,7 @@ func TestGetKubeconfig(t *testing.T) {
})
issuerEndpointPtr = &issuerEndpoint
testLog := testlogger.New(t)
testLog := testlogger.NewLegacy(t) //nolint: staticcheck // old test with lots of log statements
cmd := kubeconfigCommand(kubeconfigDeps{
getPathToSelf: func() (string, error) {
if tt.getPathToSelfErr != nil {
@@ -2401,7 +2876,7 @@ func TestGetKubeconfig(t *testing.T) {
}
return fake, nil
},
log: testLog,
log: testLog.Logger,
})
require.NotNil(t, cmd)

View File

@@ -5,7 +5,6 @@ package cmd
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/json"
@@ -14,17 +13,19 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"time"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientauthv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
"k8s.io/client-go/transport"
"k8s.io/klog/v2/klogr"
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
"go.pinniped.dev/internal/execcredcache"
"go.pinniped.dev/internal/groupsuffix"
"go.pinniped.dev/internal/net/phttp"
"go.pinniped.dev/internal/plog"
"go.pinniped.dev/pkg/conciergeclient"
"go.pinniped.dev/pkg/oidcclient"
@@ -59,6 +60,7 @@ type oidcLoginFlags struct {
listenPort uint16
scopes []string
skipBrowser bool
skipListen bool
sessionCachePath string
caBundlePaths []string
caBundleData []string
@@ -73,6 +75,7 @@ type oidcLoginFlags struct {
credentialCachePath string
upstreamIdentityProviderName string
upstreamIdentityProviderType string
upstreamIdentityProviderFlow string
}
func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
@@ -91,6 +94,7 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
cmd.Flags().Uint16Var(&flags.listenPort, "listen-port", 0, "TCP port for localhost listener (authorization code flow only)")
cmd.Flags().StringSliceVar(&flags.scopes, "scopes", []string{oidc.ScopeOfflineAccess, oidc.ScopeOpenID, "pinniped:request-audience"}, "OIDC scopes to request during login")
cmd.Flags().BoolVar(&flags.skipBrowser, "skip-browser", false, "Skip opening the browser (just print the URL)")
cmd.Flags().BoolVar(&flags.skipListen, "skip-listen", false, "Skip starting a localhost callback listener (manual copy/paste flow only)")
cmd.Flags().StringVar(&flags.sessionCachePath, "session-cache", filepath.Join(mustGetConfigDir(), "sessions.yaml"), "Path to session cache file")
cmd.Flags().StringSliceVar(&flags.caBundlePaths, "ca-bundle", nil, "Path to TLS certificate authority bundle (PEM format, optional, can be repeated)")
cmd.Flags().StringSliceVar(&flags.caBundleData, "ca-bundle-data", nil, "Base64 encoded TLS certificate authority bundle (base64 encoded PEM format, optional, can be repeated)")
@@ -105,8 +109,11 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", groupsuffix.PinnipedDefaultSuffix, "Concierge API group suffix")
cmd.Flags().StringVar(&flags.credentialCachePath, "credential-cache", filepath.Join(mustGetConfigDir(), "credentials.yaml"), "Path to cluster-specific credentials cache (\"\" disables the cache)")
cmd.Flags().StringVar(&flags.upstreamIdentityProviderName, "upstream-identity-provider-name", "", "The name of the upstream identity provider used during login with a Supervisor")
cmd.Flags().StringVar(&flags.upstreamIdentityProviderType, "upstream-identity-provider-type", "oidc", "The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap')")
cmd.Flags().StringVar(&flags.upstreamIdentityProviderType, "upstream-identity-provider-type", idpdiscoveryv1alpha1.IDPTypeOIDC.String(), fmt.Sprintf("The type of the upstream identity provider used during login with a Supervisor (e.g. '%s', '%s', '%s')", idpdiscoveryv1alpha1.IDPTypeOIDC, idpdiscoveryv1alpha1.IDPTypeLDAP, idpdiscoveryv1alpha1.IDPTypeActiveDirectory))
cmd.Flags().StringVar(&flags.upstreamIdentityProviderFlow, "upstream-identity-provider-flow", "", fmt.Sprintf("The type of client flow to use with the upstream identity provider during login with a Supervisor (e.g. '%s', '%s')", idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode, idpdiscoveryv1alpha1.IDPFlowCLIPassword))
// --skip-listen is mainly needed for testing. We'll leave it hidden until we have a non-testing use case.
mustMarkHidden(cmd, "skip-listen")
mustMarkHidden(cmd, "debug-session-cache")
mustMarkRequired(cmd, "issuer")
cmd.RunE = func(cmd *cobra.Command, args []string) error { return runOIDCLogin(cmd, deps, flags) }
@@ -156,17 +163,14 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
flags.upstreamIdentityProviderName, flags.upstreamIdentityProviderType))
}
switch flags.upstreamIdentityProviderType {
case "oidc":
// this is the default, so don't need to do anything
case "ldap":
opts = append(opts, oidcclient.WithCLISendingCredentials())
default:
// Surprisingly cobra does not support this kind of flag validation. See https://github.com/spf13/pflag/issues/236
return fmt.Errorf(
"--upstream-identity-provider-type value not recognized: %s (supported values: oidc, ldap)",
flags.upstreamIdentityProviderType)
flowOpts, err := flowOptions(
idpdiscoveryv1alpha1.IDPType(flags.upstreamIdentityProviderType),
idpdiscoveryv1alpha1.IDPFlow(flags.upstreamIdentityProviderFlow),
)
if err != nil {
return err
}
opts = append(opts, flowOpts...)
var concierge *conciergeclient.Client
if flags.conciergeEnabled {
@@ -182,12 +186,14 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
}
}
// --skip-browser replaces the default "browser open" function with one that prints to stderr.
// --skip-browser skips opening the browser.
if flags.skipBrowser {
opts = append(opts, oidcclient.WithBrowserOpen(func(url string) error {
cmd.PrintErr("Please log in: ", url, "\n")
return nil
}))
opts = append(opts, oidcclient.WithSkipBrowserOpen())
}
// --skip-listen skips starting the localhost callback listener.
if flags.skipListen {
opts = append(opts, oidcclient.WithSkipListen())
}
if len(flags.caBundlePaths) > 0 || len(flags.caBundleData) > 0 {
@@ -245,6 +251,46 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
return json.NewEncoder(cmd.OutOrStdout()).Encode(cred)
}
func flowOptions(requestedIDPType idpdiscoveryv1alpha1.IDPType, requestedFlow idpdiscoveryv1alpha1.IDPFlow) ([]oidcclient.Option, error) {
useCLIFlow := []oidcclient.Option{oidcclient.WithCLISendingCredentials()}
switch requestedIDPType {
case idpdiscoveryv1alpha1.IDPTypeOIDC:
switch requestedFlow {
case idpdiscoveryv1alpha1.IDPFlowCLIPassword:
return useCLIFlow, nil
case idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode, "":
return nil, nil // browser authcode flow is the default Option, so don't need to return an Option here
default:
return nil, fmt.Errorf(
"--upstream-identity-provider-flow value not recognized for identity provider type %q: %s (supported values: %s)",
requestedIDPType, requestedFlow, strings.Join([]string{idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode.String(), idpdiscoveryv1alpha1.IDPFlowCLIPassword.String()}, ", "))
}
case idpdiscoveryv1alpha1.IDPTypeLDAP, idpdiscoveryv1alpha1.IDPTypeActiveDirectory:
switch requestedFlow {
case idpdiscoveryv1alpha1.IDPFlowCLIPassword, "":
return useCLIFlow, nil
case idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode:
fallthrough // not supported for LDAP providers, so fallthrough to error case
default:
return nil, fmt.Errorf(
"--upstream-identity-provider-flow value not recognized for identity provider type %q: %s (supported values: %s)",
requestedIDPType, requestedFlow, []string{idpdiscoveryv1alpha1.IDPFlowCLIPassword.String()})
}
default:
// Surprisingly cobra does not support this kind of flag validation. See https://github.com/spf13/pflag/issues/236
return nil, fmt.Errorf(
"--upstream-identity-provider-type value not recognized: %s (supported values: %s)",
requestedIDPType,
strings.Join([]string{
idpdiscoveryv1alpha1.IDPTypeOIDC.String(),
idpdiscoveryv1alpha1.IDPTypeLDAP.String(),
idpdiscoveryv1alpha1.IDPTypeActiveDirectory.String(),
}, ", "),
)
}
}
func makeClient(caBundlePaths []string, caBundleData []string) (*http.Client, error) {
pool := x509.NewCertPool()
for _, p := range caBundlePaths {
@@ -261,18 +307,7 @@ func makeClient(caBundlePaths []string, caBundleData []string) (*http.Client, er
}
pool.AppendCertsFromPEM(pem)
}
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
RootCAs: pool,
MinVersion: tls.VersionTLS12,
},
},
}
client.Transport = transport.DebugWrappers(client.Transport)
return client, nil
return phttp.Default(pool), nil
}
func tokenCredential(token *oidctypes.Token) *clientauthv1beta1.ExecCredential {
@@ -291,7 +326,7 @@ func tokenCredential(token *oidctypes.Token) *clientauthv1beta1.ExecCredential {
return &cred
}
func SetLogLevel(lookupEnv func(string) (string, bool)) (*plog.PLogger, error) {
func SetLogLevel(lookupEnv func(string) (string, bool)) (plog.Logger, error) {
debug, _ := lookupEnv("PINNIPED_DEBUG")
if debug == "true" {
err := plog.ValidateAndSetLogLevelGlobally(plog.LevelDebug)
@@ -300,7 +335,7 @@ func SetLogLevel(lookupEnv func(string) (string, bool)) (*plog.PLogger, error) {
}
}
logger := plog.New("Pinniped login: ")
return &logger, nil
return logger, nil
}
// mustGetConfigDir returns a directory that follows the XDG base directory convention:

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
@@ -77,8 +77,9 @@ func TestLoginOIDCCommand(t *testing.T) {
--scopes strings OIDC scopes to request during login (default [offline_access,openid,pinniped:request-audience])
--session-cache string Path to session cache file (default "` + cfgDir + `/sessions.yaml")
--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') (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') (default "oidc")
`),
},
{
@@ -148,11 +149,11 @@ func TestLoginOIDCCommand(t *testing.T) {
},
wantError: true,
wantStderr: here.Doc(`
Error: --upstream-identity-provider-type value not recognized: invalid (supported values: oidc, ldap)
Error: --upstream-identity-provider-type value not recognized: invalid (supported values: oidc, ldap, activedirectory)
`),
},
{
name: "oidc upstream type is allowed",
name: "oidc upstream type with default flow is allowed",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
@@ -160,10 +161,48 @@ func TestLoginOIDCCommand(t *testing.T) {
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantOptionsCount: 4,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
},
{
name: "ldap upstream type is allowed",
name: "oidc upstream type with CLI flow is allowed",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "oidc",
"--upstream-identity-provider-flow", "cli_password",
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantOptionsCount: 5,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
},
{
name: "oidc upstream type with browser flow is allowed",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "oidc",
"--upstream-identity-provider-flow", "browser_authcode",
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantOptionsCount: 4,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
},
{
name: "oidc upstream type with unsupported flow is an error",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "oidc",
"--upstream-identity-provider-flow", "foobar",
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantError: true,
wantStderr: here.Doc(`
Error: --upstream-identity-provider-flow value not recognized for identity provider type "oidc": foobar (supported values: browser_authcode, cli_password)
`),
},
{
name: "ldap upstream type with default flow is allowed",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
@@ -171,7 +210,70 @@ func TestLoginOIDCCommand(t *testing.T) {
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantOptionsCount: 5,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
},
{
name: "activedirectory upstream type with default flow is allowed",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "activedirectory",
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantOptionsCount: 5,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
},
{
name: "ldap upstream type with CLI flow is allowed",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "ldap",
"--upstream-identity-provider-flow", "cli_password",
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantOptionsCount: 5,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
},
{
name: "ldap upstream type with unsupported flow is an error",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "ldap",
"--upstream-identity-provider-flow", "browser_authcode", // "browser_authcode" is only supported for OIDC upstreams
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantError: true,
wantStderr: here.Doc(`
Error: --upstream-identity-provider-flow value not recognized for identity provider type "ldap": browser_authcode (supported values: [cli_password])
`),
},
{
name: "active directory upstream type with CLI flow is allowed",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "activedirectory",
"--upstream-identity-provider-flow", "cli_password",
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantOptionsCount: 5,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
},
{
name: "active directory upstream type with unsupported flow is an error",
args: []string{
"--issuer", "test-issuer",
"--client-id", "test-client-id",
"--upstream-identity-provider-type", "activedirectory",
"--upstream-identity-provider-flow", "browser_authcode", // "browser_authcode" is only supported for OIDC upstreams
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
},
wantError: true,
wantStderr: here.Doc(`
Error: --upstream-identity-provider-flow value not recognized for identity provider type "activedirectory": browser_authcode (supported values: [cli_password])
`),
},
{
name: "login error",
@@ -214,7 +316,7 @@ func TestLoginOIDCCommand(t *testing.T) {
},
env: map[string]string{"PINNIPED_DEBUG": "true"},
wantOptionsCount: 4,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
wantLogs: []string{
"\"level\"=0 \"msg\"=\"Pinniped login: Performing OIDC login\" \"client id\"=\"test-client-id\" \"issuer\"=\"test-issuer\"",
"\"level\"=0 \"msg\"=\"Pinniped login: No concierge configured, skipping token credential exchange\"",
@@ -226,6 +328,7 @@ func TestLoginOIDCCommand(t *testing.T) {
"--client-id", "test-client-id",
"--issuer", "test-issuer",
"--skip-browser",
"--skip-listen",
"--listen-port", "1234",
"--debug-session-cache",
"--request-audience", "cluster-1234",
@@ -242,8 +345,8 @@ func TestLoginOIDCCommand(t *testing.T) {
"--upstream-identity-provider-type", "ldap",
},
env: map[string]string{"PINNIPED_DEBUG": "true"},
wantOptionsCount: 10,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"exchanged-token"}}` + "\n",
wantOptionsCount: 11,
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"token":"exchanged-token"}}` + "\n",
wantLogs: []string{
"\"level\"=0 \"msg\"=\"Pinniped login: Performing OIDC login\" \"client id\"=\"test-client-id\" \"issuer\"=\"test-issuer\"",
"\"level\"=0 \"msg\"=\"Pinniped login: Exchanging token for cluster credential\" \"authenticator name\"=\"test-authenticator\" \"authenticator type\"=\"webhook\" \"endpoint\"=\"https://127.0.0.1:1234/\"",
@@ -255,8 +358,8 @@ func TestLoginOIDCCommand(t *testing.T) {
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
testLogger := testlogger.New(t)
klog.SetLogger(testLogger)
testLogger := testlogger.NewLegacy(t) //nolint: staticcheck // old test with lots of log statements
klog.SetLogger(testLogger.Logger)
var (
gotOptions []oidcclient.Option
)

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
@@ -119,7 +119,7 @@ func TestLoginStaticCommand(t *testing.T) {
env: map[string]string{
"TEST_TOKEN_ENV": "test-token",
},
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"test-token"}}` + "\n",
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"token":"test-token"}}` + "\n",
},
{
name: "concierge failure",
@@ -159,14 +159,14 @@ func TestLoginStaticCommand(t *testing.T) {
"--token", "test-token",
},
env: map[string]string{"PINNIPED_DEBUG": "true"},
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"test-token"}}` + "\n",
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"token":"test-token"}}` + "\n",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
testLogger := testlogger.New(t)
klog.SetLogger(testLogger)
testLogger := testlogger.NewLegacy(t) //nolint: staticcheck // old test with lots of log statements
klog.SetLogger(testLogger.Logger)
cmd := staticLoginCommand(staticLoginDeps{
lookupEnv: func(s string) (string, bool) {
v, ok := tt.env[s]

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package cmd
@@ -7,8 +7,6 @@ import (
"os"
"github.com/spf13/cobra"
"go.pinniped.dev/internal/plog"
)
//nolint: gochecknoglobals
@@ -19,12 +17,6 @@ var rootCmd = &cobra.Command{
SilenceUsage: true, // do not print usage message when commands fail
}
//nolint: gochecknoinits
func init() {
// We don't want klog flags showing up in our CLI.
plog.RemoveKlogGlobalFlags()
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {

View File

@@ -1,9 +1,24 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main
import "go.pinniped.dev/cmd/pinniped/cmd"
import (
"os"
"github.com/pkg/browser"
"go.pinniped.dev/cmd/pinniped/cmd"
// this side effect import ensures that we use fipsonly crypto in fips_strict mode.
_ "go.pinniped.dev/internal/crypto/ptls"
)
//nolint: gochecknoinits
func init() {
// browsers like chrome like to write to our std out which breaks our JSON ExecCredential output
// thus we redirect the browser's std out to our std err
browser.Stdout = os.Stderr
}
func main() {
cmd.Execute()

View File

@@ -1,10 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.0
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: jwtauthenticators.authentication.concierge.pinniped.dev
spec:
@@ -24,6 +23,12 @@ spec:
- jsonPath: .spec.issuer
name: Issuer
type: string
- jsonPath: .spec.audience
name: Audience
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:

View File

@@ -1,10 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.0
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: webhookauthenticators.authentication.concierge.pinniped.dev
spec:
@@ -24,6 +23,9 @@ spec:
- jsonPath: .spec.endpoint
name: Endpoint
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:

View File

@@ -1,10 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.0
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: credentialissuers.config.concierge.pinniped.dev
spec:
@@ -18,7 +17,17 @@ spec:
singular: credentialissuer
scope: Cluster
versions:
- name: v1alpha1
- additionalPrinterColumns:
- jsonPath: .spec.impersonationProxy.mode
name: ProxyMode
type: string
- jsonPath: .status.strategies[?(@.status == "Success")].type
name: DefaultStrategy
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: CredentialIssuer describes the configuration and status of the
@@ -47,7 +56,7 @@ spec:
description: "ExternalEndpoint describes the HTTPS endpoint where
the proxy will be exposed. If not set, the proxy will be served
using the external name of the LoadBalancer service or the cluster
service DNS name. \n This field must be non-empty when spec.impersonationProxy.service.mode
service DNS name. \n This field must be non-empty when spec.impersonationProxy.service.type
is \"None\"."
type: string
mode:

View File

@@ -1,9 +1,10 @@
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
#! SPDX-License-Identifier: Apache-2.0
#@ load("@ytt:data", "data")
#@ load("@ytt:json", "json")
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel", "pinnipedDevAPIGroupWithPrefix")
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel", "pinnipedDevAPIGroupWithPrefix")
#@ load("@ytt:template", "template")
#@ if not data.values.into_namespace:
---
@@ -57,6 +58,8 @@ data:
durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @)
renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @)
apiGroupSuffix: (@= data.values.api_group_suffix @)
# aggregatedAPIServerPort may be set here, although other YAML references to the default port (10250) may also need to be updated
# impersonationProxyServerPort may be set here, although other YAML references to the default port (8444) may also need to be updated
names:
servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @)
credentialIssuer: (@= defaultResourceNameWithSuffix("config") @)
@@ -108,10 +111,16 @@ metadata:
spec:
replicas: #@ data.values.replicas
selector:
#! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades.
matchLabels: #@ defaultLabel()
template:
metadata:
labels: #@ defaultLabel()
labels:
#! This has always included defaultLabel(), which is used by this Deployment's selector.
_: #@ template.replace(defaultLabel())
#! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically
#! without accidentally selecting any other Deployment's Pods, especially the kube cert agent Deployment's Pods.
_: #@ template.replace(deploymentPodLabel())
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
spec:
@@ -131,6 +140,8 @@ spec:
image: #@ data.values.image_repo + ":" + data.values.image_tag
#@ end
imagePullPolicy: IfNotPresent
securityContext:
readOnlyRootFilesystem: true
resources:
requests:
cpu: "100m"
@@ -138,20 +149,35 @@ spec:
limits:
cpu: "100m"
memory: "128Mi"
args:
command:
- pinniped-concierge
- --config=/etc/config/pinniped.yaml
- --downward-api-path=/etc/podinfo
volumeMounts:
- name: tmp
mountPath: /tmp
- name: config-volume
mountPath: /etc/config
readOnly: true
- name: podinfo
mountPath: /etc/podinfo
readOnly: true
- name: impersonation-proxy
mountPath: /var/run/secrets/impersonation-proxy.concierge.pinniped.dev/serviceaccount
readOnly: true
env:
#@ if data.values.https_proxy:
- name: HTTPS_PROXY
value: #@ data.values.https_proxy
#@ end
#@ if data.values.https_proxy and data.values.no_proxy:
- name: NO_PROXY
value: #@ data.values.no_proxy
#@ end
livenessProbe:
httpGet:
path: /healthz
port: 8443
port: 10250
scheme: HTTPS
initialDelaySeconds: 2
timeoutSeconds: 15
@@ -160,13 +186,17 @@ spec:
readinessProbe:
httpGet:
path: /healthz
port: 8443
port: 10250
scheme: HTTPS
initialDelaySeconds: 2
timeoutSeconds: 3
periodSeconds: 10
failureThreshold: 3
volumes:
- name: tmp
emptyDir:
medium: Memory
sizeLimit: 100Mi
- name: config-volume
configMap:
name: #@ defaultResourceNameWithSuffix("config")
@@ -191,7 +221,9 @@ spec:
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- key: node-role.kubernetes.io/master #! Allow running on master nodes too
- key: node-role.kubernetes.io/master #! Allow running on master nodes too (name deprecated by kubernetes 1.20).
effect: NoSchedule
- key: node-role.kubernetes.io/control-plane #! The new name for these nodes as of Kubernetes 1.24.
effect: NoSchedule
#! "system-cluster-critical" cannot be used outside the kube-system namespace until Kubernetes >= 1.17,
#! so we skip setting this for now (see https://github.com/kubernetes/kubernetes/issues/60596).
@@ -204,7 +236,7 @@ spec:
- weight: 50
podAffinityTerm:
labelSelector:
matchLabels: #@ defaultLabel()
matchLabels: #@ deploymentPodLabel()
topologyKey: kubernetes.io/hostname
---
apiVersion: v1
@@ -214,13 +246,16 @@ metadata:
name: #@ defaultResourceNameWithSuffix("api")
namespace: #@ namespace()
labels: #@ labels()
#! prevent kapp from altering the selector of our services to match kubectl behavior
annotations:
kapp.k14s.io/disable-default-label-scoping-rules: ""
spec:
type: ClusterIP
selector: #@ defaultLabel()
selector: #@ deploymentPodLabel()
ports:
- protocol: TCP
port: 443
targetPort: 8443
targetPort: 10250
---
apiVersion: v1
kind: Service
@@ -228,9 +263,12 @@ metadata:
name: #@ defaultResourceNameWithSuffix("proxy")
namespace: #@ namespace()
labels: #@ labels()
#! prevent kapp from altering the selector of our services to match kubectl behavior
annotations:
kapp.k14s.io/disable-default-label-scoping-rules: ""
spec:
type: ClusterIP
selector: #@ defaultLabel()
selector: #@ deploymentPodLabel()
ports:
- protocol: TCP
port: 443

View File

@@ -25,9 +25,14 @@
#@ end
#@ def defaultLabel():
#! Note that the name of this label's key is also assumed by kubecertagent.go and impersonator_config.go
app: #@ data.values.app_name
#@ end
#@ def deploymentPodLabel():
deployment.pinniped.dev: concierge
#@ end
#@ def labels():
_: #@ template.replace(defaultLabel())
_: #@ template.replace(data.values.custom_labels)

View File

@@ -145,7 +145,7 @@ rules:
#! We need to be able to create and update deployments in our namespace so we can manage the kube-cert-agent Deployment.
- apiGroups: [ apps ]
resources: [ deployments ]
verbs: [ create, get, list, patch, update, watch ]
verbs: [ create, get, list, patch, update, watch, delete ]
#! We need to be able to get replicasets so we can form the correct owner references on our generated objects.
- apiGroups: [ apps ]
resources: [ replicasets ]
@@ -153,6 +153,9 @@ rules:
- apiGroups: [ "" ]
resources: [ configmaps ]
verbs: [ list, get, watch ]
- apiGroups: [ coordination.k8s.io ]
resources: [ leases ]
verbs: [ create, get, update ]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1

View File

@@ -41,7 +41,7 @@ kube_cert_agent_image:
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
#! Pinniped will try to guess the right K8s API URL for sharing that information with potential clients.
#! This settings allows the guess to be overridden.
#! This setting allows the guess to be overridden.
#! Optional.
discovery_url: #! e.g., https://example.com
@@ -55,8 +55,8 @@ api_serving_certificate_renew_before_seconds: 2160000
#! information), trace (timing information), all (kitchen sink).
log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs.
run_as_user: 1001 #! run_as_user specifies the user ID that will own the process
run_as_group: 1001 #! run_as_group specifies the group ID that will own the process
run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice
run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice
#! Specify the API group suffix for all Pinniped API groups. By default, this is set to
#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev,
@@ -93,3 +93,11 @@ impersonation_proxy_spec:
{service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"}
#! When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP.
load_balancer_ip:
#! Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Concierge containers.
#! These will be used when the Concierge makes backend-to-backend calls to authenticators using HTTPS,
#! e.g. when the Concierge fetches discovery documents, JWKS keys, and POSTs to token webhooks.
#! The Concierge never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY.
#! Optional.
https_proxy: #! e.g. http://proxy.example.com
no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints

View File

@@ -63,8 +63,8 @@ spec:
image: #@ data.values.image_repo + ":" + data.values.image_tag
#@ end
imagePullPolicy: IfNotPresent
command: #! override the default entrypoint
- /usr/local/bin/local-user-authenticator
command:
- local-user-authenticator
---
apiVersion: v1
kind: Service
@@ -73,6 +73,9 @@ metadata:
namespace: local-user-authenticator
labels:
app: local-user-authenticator
#! prevent kapp from altering the selector of our services to match kubectl behavior
annotations:
kapp.k14s.io/disable-default-label-scoping-rules: ""
spec:
type: ClusterIP
selector:

View File

@@ -15,5 +15,5 @@ image_tag: latest
#! Optional.
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
run_as_user: 1001 #! run_as_user specifies the user ID that will own the process
run_as_group: 1001 #! run_as_group specifies the group ID that will own the process
run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice
run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice

View File

@@ -1,10 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.0
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: federationdomains.config.supervisor.pinniped.dev
spec:
@@ -18,7 +17,17 @@ spec:
singular: federationdomain
scope: Namespaced
versions:
- name: v1alpha1
- additionalPrinterColumns:
- jsonPath: .spec.issuer
name: Issuer
type: string
- jsonPath: .status.status
name: Status
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: FederationDomain describes the configuration of an OIDC provider.
@@ -67,12 +76,13 @@ spec:
so all issuers with the same DNS hostname must use the same
SecretName value even if they have different port numbers. \n
SecretName is not required when you would like to use only the
HTTP endpoints (e.g. when terminating TLS at an Ingress). It
is also not required when you would like all requests to this
OIDC Provider's HTTPS endpoints to use the default TLS certificate,
which is configured elsewhere. \n When your Issuer URL's host
is an IP address, then this field is ignored. SNI does not work
for IP addresses."
HTTP endpoints (e.g. when the HTTP listener is configured to
listen on loopback interfaces or UNIX domain sockets for traffic
from a service mesh sidecar). It is also not required when you
would like all requests to this OIDC Provider's HTTPS endpoints
to use the default TLS certificate, which is configured elsewhere.
\n When your Issuer URL's host is an IP address, then this field
is ignored. SNI does not work for IP addresses."
type: string
type: object
required:

View File

@@ -1,9 +1,19 @@
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
#! SPDX-License-Identifier: Apache-2.0
#@ load("@ytt:data", "data")
#@ load("@ytt:json", "json")
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel")
#@ load("@ytt:yaml", "yaml")
#@ load("helpers.lib.yaml",
#@ "defaultLabel",
#@ "labels",
#@ "deploymentPodLabel",
#@ "namespace",
#@ "defaultResourceName",
#@ "defaultResourceNameWithSuffix",
#@ "getPinnipedConfigMapData",
#@ "hasUnixNetworkEndpoint",
#@ )
#@ load("@ytt:template", "template")
#@ if not data.values.into_namespace:
---
@@ -29,14 +39,7 @@ metadata:
labels: #@ labels()
data:
#@yaml/text-templated-strings
pinniped.yaml: |
apiGroupSuffix: (@= data.values.api_group_suffix @)
names:
defaultTLSCertificateSecret: (@= defaultResourceNameWithSuffix("default-tls-certificate") @)
labels: (@= json.encode(labels()).rstrip() @)
(@ if data.values.log_level: @)
logLevel: (@= getAndValidateLogLevel() @)
(@ end @)
pinniped.yaml: #@ yaml.encode(getPinnipedConfigMapData())
---
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
apiVersion: v1
@@ -59,10 +62,16 @@ metadata:
spec:
replicas: #@ data.values.replicas
selector:
#! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades.
matchLabels: #@ defaultLabel()
template:
metadata:
labels: #@ defaultLabel()
labels:
#! This has always included defaultLabel(), which is used by this Deployment's selector.
_: #@ template.replace(defaultLabel())
#! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically
#! without accidentally selecting pods from any future Deployments which might also want to use the defaultLabel().
_: #@ template.replace(deploymentPodLabel())
spec:
securityContext:
runAsUser: #@ data.values.run_as_user
@@ -80,11 +89,12 @@ spec:
image: #@ data.values.image_repo + ":" + data.values.image_tag
#@ end
imagePullPolicy: IfNotPresent
command: #! override the default entrypoint
- /usr/local/bin/pinniped-supervisor
args:
command:
- pinniped-supervisor
- /etc/podinfo
- /etc/config/pinniped.yaml
securityContext:
readOnlyRootFilesystem: true
resources:
requests:
cpu: "100m"
@@ -95,18 +105,32 @@ spec:
volumeMounts:
- name: config-volume
mountPath: /etc/config
readOnly: true
- name: podinfo
mountPath: /etc/podinfo
readOnly: true
#@ if hasUnixNetworkEndpoint():
- name: socket
mountPath: /pinniped_socket
readOnly: false #! writable to allow for socket use
#@ end
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 8443
protocol: TCP
env:
#@ if data.values.https_proxy:
- name: HTTPS_PROXY
value: #@ data.values.https_proxy
#@ end
#@ if data.values.https_proxy and data.values.no_proxy:
- name: NO_PROXY
value: #@ data.values.no_proxy
#@ end
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
port: 8443
scheme: HTTPS
initialDelaySeconds: 2
timeoutSeconds: 15
periodSeconds: 10
@@ -114,8 +138,8 @@ spec:
readinessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
port: 8443
scheme: HTTPS
initialDelaySeconds: 2
timeoutSeconds: 3
periodSeconds: 10
@@ -136,6 +160,10 @@ spec:
- path: "name"
fieldRef:
fieldPath: metadata.name
#@ if hasUnixNetworkEndpoint():
- name: socket
emptyDir: {}
#@ end
#! This will help make sure our multiple pods run on different nodes, making
#! our deployment "more" "HA".
affinity:
@@ -144,5 +172,5 @@ spec:
- weight: 50
podAffinityTerm:
labelSelector:
matchLabels: #@ defaultLabel()
matchLabels: #@ deploymentPodLabel()
topologyKey: kubernetes.io/hostname

View File

@@ -1,4 +1,4 @@
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
#! SPDX-License-Identifier: Apache-2.0
#@ load("@ytt:data", "data")
@@ -28,6 +28,10 @@
app: #@ data.values.app_name
#@ end
#@ def deploymentPodLabel():
deployment.pinniped.dev: supervisor
#@ end
#@ def labels():
_: #@ template.replace(defaultLabel())
_: #@ template.replace(data.values.custom_labels)
@@ -40,3 +44,38 @@ _: #@ template.replace(data.values.custom_labels)
#@ end
#@ return log_level
#@ end
#@ def getPinnipedConfigMapData():
#@ config = {
#@ "apiGroupSuffix": data.values.api_group_suffix,
#@ "names": {
#@ "defaultTLSCertificateSecret": defaultResourceNameWithSuffix("default-tls-certificate"),
#@ },
#@ "labels": labels(),
#@ "insecureAcceptExternalUnencryptedHttpRequests": data.values.deprecated_insecure_accept_external_unencrypted_http_requests
#@ }
#@ if data.values.log_level:
#@ config["logLevel"] = getAndValidateLogLevel()
#@ end
#@ if data.values.endpoints:
#@ config["endpoints"] = data.values.endpoints
#@ end
#@ return config
#@ end
#@ def getattr_safe(val, *args):
#@ out = None
#@ for arg in args:
#@ if not hasattr(val, arg):
#@ return None
#@ end
#@ out = getattr(val, arg)
#@ val = out
#@ end
#@ return out
#@ end
#@ def hasUnixNetworkEndpoint():
#@ return getattr_safe(data.values.endpoints, "http", "network") == "unix" or \
#@ getattr_safe(data.values.endpoints, "https", "network") == "unix"
#@ end

View File

@@ -0,0 +1,304 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
spec:
group: idp.supervisor.pinniped.dev
names:
categories:
- pinniped
- pinniped-idp
- pinniped-idps
kind: ActiveDirectoryIdentityProvider
listKind: ActiveDirectoryIdentityProviderList
plural: activedirectoryidentityproviders
singular: activedirectoryidentityprovider
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.host
name: Host
type: string
- jsonPath: .status.phase
name: Status
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: ActiveDirectoryIdentityProvider describes the configuration of
an upstream Microsoft Active Directory identity provider.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec for configuring the identity provider.
properties:
bind:
description: Bind contains the configuration for how to provide access
credentials during an initial bind to the ActiveDirectory server
to be allowed to perform searches and binds to validate a user's
credentials during a user's authentication attempt.
properties:
secretName:
description: SecretName contains the name of a namespace-local
Secret object that provides the username and password for an
Active Directory bind user. This account will be used to perform
LDAP searches. The Secret should be of type "kubernetes.io/basic-auth"
which includes "username" and "password" keys. The username
value should be the full dn (distinguished name) of your bind
account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
The password must be non-empty.
minLength: 1
type: string
required:
- secretName
type: object
groupSearch:
description: GroupSearch contains the configuration for searching
for a user's group membership in ActiveDirectory.
properties:
attributes:
description: Attributes specifies how the group's information
should be read from each ActiveDirectory entry which was found
as the result of the group search.
properties:
groupName:
description: GroupName specifies the name of the attribute
in the Active Directory entries whose value shall become
a group name in the user's list of groups after a successful
authentication. The value of this field is case-sensitive
and must match the case of the attribute name returned by
the ActiveDirectory server in the user's entry. E.g. "cn"
for common name. Distinguished names can be used by specifying
lower-case "dn". Optional. When not specified, this defaults
to a custom field that looks like "sAMAccountName@domain",
where domain is constructed from the domain components of
the group DN.
type: string
type: object
base:
description: Base is the dn (distinguished name) that should be
used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com".
Optional, when not specified it will be based on the result
of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
The default behavior searches your entire domain for groups.
It may make sense to specify a subtree as a search base if you
wish to exclude some groups for security reasons or to make
searches faster.
type: string
filter:
description: Filter is the ActiveDirectory search filter which
should be applied when searching for groups for a user. The
pattern "{}" must occur in the filter at least once and will
be dynamically replaced by the dn (distinguished name) of the
user entry found as a result of the user search. E.g. "member={}"
or "&(objectClass=groupOfNames)(member={})". For more information
about ActiveDirectory filters, see https://ldap.com/ldap-filters.
Note that the dn (distinguished name) is not an attribute of
an entry, so "dn={}" cannot be used. Optional. When not specified,
the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})".
This searches nested groups by default. Note that nested group
search can be slow for some Active Directory servers. To disable
it, you can set the filter to "(&(objectClass=group)(member={})"
type: string
skipGroupRefresh:
description: "The user's group membership is refreshed as they
interact with the supervisor to obtain new credentials (as their
old credentials expire). This allows group membership changes
to be quickly reflected into Kubernetes clusters. Since group
membership is often used to bind authorization policies, it
is important to keep the groups observed in Kubernetes clusters
in-sync with the identity provider. \n In some environments,
frequent group membership queries may result in a significant
performance impact on the identity provider and/or the supervisor.
The best approach to handle performance impacts is to tweak
the group query to be more performant, for example by disabling
nested group search or by using a more targeted group search
base. \n If the group search query cannot be made performant
and you are willing to have group memberships remain static
for approximately a day, then set skipGroupRefresh to true.
\ This is an insecure configuration as authorization policies
that are bound to group membership will not notice if a user
has been removed from a particular group until their next login.
\n This is an experimental feature that may be removed or significantly
altered in the future. Consumers of this configuration should
carefully read all release notes before upgrading to ensure
that the meaning of this field has not changed."
type: boolean
type: object
host:
description: 'Host is the hostname of this Active Directory identity
provider, i.e., where to connect. For example: ldap.example.com:636.'
minLength: 1
type: string
tls:
description: TLS contains the connection settings for how to establish
the connection to the Host.
properties:
certificateAuthorityData:
description: X.509 Certificate Authority (base64-encoded PEM bundle).
If omitted, a default set of system roots will be trusted.
type: string
type: object
userSearch:
description: UserSearch contains the configuration for searching for
a user by name in Active Directory.
properties:
attributes:
description: Attributes specifies how the user's information should
be read from the ActiveDirectory entry which was found as the
result of the user search.
properties:
uid:
description: UID specifies the name of the attribute in the
ActiveDirectory entry which whose value shall be used to
uniquely identify the user within this ActiveDirectory provider
after a successful authentication. Optional, when empty
this defaults to "objectGUID".
type: string
username:
description: Username specifies the name of the attribute
in Active Directory entry whose value shall become the username
of the user after a successful authentication. Optional,
when empty this defaults to "userPrincipalName".
type: string
type: object
base:
description: Base is the dn (distinguished name) that should be
used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
Optional, when not specified it will be based on the result
of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
The default behavior searches your entire domain for users.
It may make sense to specify a subtree as a search base if you
wish to exclude some users or to make searches faster.
type: string
filter:
description: Filter is the search filter which should be applied
when searching for users. The pattern "{}" must occur in the
filter at least once and will be dynamically replaced by the
username for which the search is being run. E.g. "mail={}" or
"&(objectClass=person)(uid={})". For more information about
LDAP filters, see https://ldap.com/ldap-filters. Note that the
dn (distinguished name) is not an attribute of an entry, so
"dn={}" cannot be used. Optional. When not specified, the default
will be '(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))'
This means that the user is a person, is not a computer, the
sAMAccountType is for a normal user account, and is not shown
in advanced view only (which would likely mean its a system
created service account with advanced permissions). Also, either
the sAMAccountName, the userPrincipalName, or the mail attribute
matches the input username.
type: string
type: object
required:
- host
type: object
status:
description: Status of the identity provider.
properties:
conditions:
description: Represents the observations of an identity provider's
current state.
items:
description: Condition status of a resource (mirrored from the metav1.Condition
type added in Kubernetes 1.19). In a future API version we can
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
phase:
default: Pending
description: Phase summarizes the overall status of the ActiveDirectoryIdentityProvider.
enum:
- Pending
- Ready
- Error
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -1,10 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.0
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: ldapidentityproviders.idp.supervisor.pinniped.dev
spec:
@@ -111,6 +110,30 @@ spec:
an entry, so "dn={}" cannot be used. Optional. When not specified,
the default will act as if the Filter were specified as "member={}".
type: string
skipGroupRefresh:
description: "The user's group membership is refreshed as they
interact with the supervisor to obtain new credentials (as their
old credentials expire). This allows group membership changes
to be quickly reflected into Kubernetes clusters. Since group
membership is often used to bind authorization policies, it
is important to keep the groups observed in Kubernetes clusters
in-sync with the identity provider. \n In some environments,
frequent group membership queries may result in a significant
performance impact on the identity provider and/or the supervisor.
The best approach to handle performance impacts is to tweak
the group query to be more performant, for example by disabling
nested group search or by using a more targeted group search
base. \n If the group search query cannot be made performant
and you are willing to have group memberships remain static
for approximately a day, then set skipGroupRefresh to true.
\ This is an insecure configuration as authorization policies
that are bound to group membership will not notice if a user
has been removed from a particular group until their next login.
\n This is an experimental feature that may be removed or significantly
altered in the future. Consumers of this configuration should
carefully read all release notes before upgrading to ensure
that the meaning of this field has not changed."
type: boolean
type: object
host:
description: 'Host is the hostname of this LDAP identity provider,

View File

@@ -1,10 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.0
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: oidcidentityproviders.idp.supervisor.pinniped.dev
spec:
@@ -56,26 +55,150 @@ spec:
the OAuth2 authorization request parameters to be used with this
OIDC identity provider.
properties:
additionalAuthorizeParameters:
description: additionalAuthorizeParameters are extra query parameters
that should be included in the authorize request to your OIDC
provider in the authorization request during an OIDC Authorization
Code Flow. By default, no extra parameters are sent. The standard
parameters that will be sent are "response_type", "scope", "client_id",
"state", "nonce", "code_challenge", "code_challenge_method",
and "redirect_uri". These parameters cannot be included in this
setting. Additionally, the "hd" parameter cannot be included
in this setting at this time. The "hd" parameter is used by
Google's OIDC provider to provide a hint as to which "hosted
domain" the user should use during login. However, Pinniped
does not yet support validating the hosted domain in the resulting
ID token, so it is not yet safe to use this feature of Google's
OIDC provider with Pinniped. This setting does not influence
the parameters sent to the token endpoint in the Resource Owner
Password Credentials Grant. The Pinniped Supervisor requires
that your OIDC provider returns refresh tokens to the Supervisor
from the authorization flows. Some OIDC providers may require
a certain value for the "prompt" parameter in order to properly
request refresh tokens. See the documentation of your OIDC provider's
authorization endpoint for its requirements for what to include
in the request in order to receive a refresh token in the response,
if anything. If your provider requires the prompt parameter
to request a refresh token, then include it here. Also note
that most providers also require a certain scope to be requested
in order to receive refresh tokens. See the additionalScopes
setting for more information about using scopes to request refresh
tokens.
items:
description: Parameter is a key/value pair which represents
a parameter in an HTTP request.
properties:
name:
description: The name of the parameter. Required.
minLength: 1
type: string
value:
description: The value of the parameter.
type: string
required:
- name
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
additionalScopes:
description: AdditionalScopes are the scopes in addition to "openid"
that will be requested as part of the authorization request
flow with an OIDC identity provider. By default only the "openid"
scope will be requested.
description: 'additionalScopes are the additional scopes that
will be requested from your OIDC provider in the authorization
request during an OIDC Authorization Code Flow and in the token
request during a Resource Owner Password Credentials Grant.
Note that the "openid" scope will always be requested regardless
of the value in this setting, since it is always required according
to the OIDC spec. By default, when this field is not set, the
Supervisor will request the following scopes: "openid", "offline_access",
"email", and "profile". See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
for a description of the "profile" and "email" scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
for a description of the "offline_access" scope. This default
value may change in future versions of Pinniped as the standard
evolves, or as common patterns used by providers who implement
the standard in the ecosystem evolve. By setting this list to
anything other than an empty list, you are overriding the default
value, so you may wish to include some of "offline_access",
"email", and "profile" in your override list. If you do not
want any of these scopes to be requested, you may set this list
to contain only "openid". Some OIDC providers may also require
a scope to get access to the user''s group membership, in which
case you may wish to include it in this list. Sometimes the
scope to request the user''s group membership is called "groups",
but unfortunately this is not specified in the OIDC standard.
Generally speaking, you should include any scopes required to
cause the appropriate claims to be the returned by your OIDC
provider in the ID token or userinfo endpoint results for those
claims which you would like to use in the oidcClaims settings
to determine the usernames and group memberships of your Kubernetes
users. See your OIDC provider''s documentation for more information
about what scopes are available to request claims. Additionally,
the Pinniped Supervisor requires that your OIDC provider returns
refresh tokens to the Supervisor from these authorization flows.
For most OIDC providers, the scope required to receive refresh
tokens will be "offline_access". See the documentation of your
OIDC provider''s authorization and token endpoints for its requirements
for what to include in the request in order to receive a refresh
token in the response, if anything. Note that it may be safe
to send "offline_access" even to providers which do not require
it, since the provider may ignore scopes that it does not understand
or require (see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3).
In the unusual case that you must avoid sending the "offline_access"
scope, then you must override the default value of this setting.
This is required if your OIDC provider will reject the request
when it includes "offline_access" (e.g. GitLab''s OIDC provider).'
items:
type: string
type: array
allowPasswordGrant:
description: allowPasswordGrant, when true, will allow the use
of OAuth 2.0's Resource Owner Password Credentials Grant (see
https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to
authenticate to the OIDC provider using a username and password
without a web browser, in addition to the usual browser-based
OIDC Authorization Code Flow. The Resource Owner Password Credentials
Grant is not officially part of the OIDC specification, so it
may not be supported by your OIDC provider. If your OIDC provider
supports returning ID tokens from a Resource Owner Password
Credentials Grant token request, then you can choose to set
this field to true. This will allow end users to choose to present
their username and password to the kubectl CLI (using the Pinniped
plugin) to authenticate to the cluster, without using a web
browser to log in as is customary in OIDC Authorization Code
Flow. This may be convenient for users, especially for identities
from your OIDC provider which are not intended to represent
a human actor, such as service accounts performing actions in
a CI/CD environment. Even if your OIDC provider supports it,
you may wish to disable this behavior by setting this field
to false when you prefer to only allow users of this OIDCIdentityProvider
to log in via the browser-based OIDC Authorization Code Flow.
Using the Resource Owner Password Credentials Grant means that
the Pinniped CLI and Pinniped Supervisor will directly handle
your end users' passwords (similar to LDAPIdentityProvider),
and you will not be able to require multi-factor authentication
or use the other web-based login features of your OIDC provider
during Resource Owner Password Credentials Grant logins. allowPasswordGrant
defaults to false.
type: boolean
type: object
claims:
description: Claims provides the names of token claims that will be
used when inspecting an identity from this OIDC identity provider.
properties:
groups:
description: Groups provides the name of the token claim that
will be used to ascertain the groups to which an identity belongs.
description: Groups provides the name of the ID token claim or
userinfo endpoint response claim that will be used to ascertain
the groups to which an identity belongs. By default, the identities
will not include any group memberships when this setting is
not configured.
type: string
username:
description: Username provides the name of the token claim that
will be used to ascertain an identity's username.
description: Username provides the name of the ID token claim
or userinfo endpoint response claim that will be used to ascertain
an identity's username. When not set, the username will be an
automatically constructed unique string which will include the
issuer URL of your OIDC provider along with the value of the
"sub" (subject) claim from the ID token.
type: string
type: object
client:

View File

@@ -40,6 +40,14 @@ rules:
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
resources: [ldapidentityproviders/status]
verbs: [get, patch, update]
- apiGroups:
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
resources: [activedirectoryidentityproviders]
verbs: [get, list, watch]
- apiGroups:
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
resources: [activedirectoryidentityproviders/status]
verbs: [get, patch, update]
#! We want to be able to read pods/replicasets/deployment so we can learn who our deployment is to set
#! as an owner reference.
- apiGroups: [""]
@@ -48,6 +56,9 @@ rules:
- apiGroups: [apps]
resources: [replicasets,deployments]
verbs: [get]
- apiGroups: [ coordination.k8s.io ]
resources: [ leases ]
verbs: [ create, get, update ]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1

View File

@@ -1,10 +1,24 @@
#! Copyright 2020 the Pinniped contributors. All Rights Reserved.
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
#! SPDX-License-Identifier: Apache-2.0
#@ load("@ytt:data", "data")
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
#@ load("@ytt:assert", "assert")
#@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
#@ if data.values.service_http_nodeport_port or data.values.service_https_nodeport_port:
#@ if hasattr(data.values, "service_http_nodeport_port"):
#@ assert.fail('value "service_http_nodeport_port" has been renamed to "deprecated_service_http_nodeport_port" and will be removed in a future release')
#@ end
#@ if hasattr(data.values, "service_http_nodeport_nodeport"):
#@ assert.fail('value "service_http_nodeport_nodeport" has been renamed to "deprecated_service_http_nodeport_nodeport" and will be removed in a future release')
#@ end
#@ if hasattr(data.values, "service_http_loadbalancer_port"):
#@ assert.fail('value "service_http_loadbalancer_port" has been renamed to "deprecated_service_http_loadbalancer_port" and will be removed in a future release')
#@ end
#@ if hasattr(data.values, "service_http_clusterip_port"):
#@ assert.fail('value "service_http_clusterip_port" has been renamed to "deprecated_service_http_clusterip_port" and will be removed in a future release')
#@ end
#@ if data.values.deprecated_service_http_nodeport_port or data.values.service_https_nodeport_port:
---
apiVersion: v1
kind: Service
@@ -12,18 +26,20 @@ metadata:
name: #@ defaultResourceNameWithSuffix("nodeport")
namespace: #@ namespace()
labels: #@ labels()
#! prevent kapp from altering the selector of our services to match kubectl behavior
annotations:
kapp.k14s.io/disable-default-label-scoping-rules: ""
spec:
type: NodePort
selector:
app: #@ data.values.app_name
selector: #@ deploymentPodLabel()
ports:
#@ if data.values.service_http_nodeport_port:
#@ if data.values.deprecated_service_http_nodeport_port:
- name: http
protocol: TCP
port: #@ data.values.service_http_nodeport_port
port: #@ data.values.deprecated_service_http_nodeport_port
targetPort: 8080
#@ if data.values.service_http_nodeport_nodeport:
nodePort: #@ data.values.service_http_nodeport_nodeport
#@ if data.values.deprecated_service_http_nodeport_nodeport:
nodePort: #@ data.values.deprecated_service_http_nodeport_nodeport
#@ end
#@ end
#@ if data.values.service_https_nodeport_port:
@@ -37,7 +53,7 @@ spec:
#@ end
#@ end
#@ if data.values.service_http_clusterip_port or data.values.service_https_clusterip_port:
#@ if data.values.deprecated_service_http_clusterip_port or data.values.service_https_clusterip_port:
---
apiVersion: v1
kind: Service
@@ -45,14 +61,17 @@ metadata:
name: #@ defaultResourceNameWithSuffix("clusterip")
namespace: #@ namespace()
labels: #@ labels()
#! prevent kapp from altering the selector of our services to match kubectl behavior
annotations:
kapp.k14s.io/disable-default-label-scoping-rules: ""
spec:
type: ClusterIP
selector: #@ defaultLabel()
selector: #@ deploymentPodLabel()
ports:
#@ if data.values.service_http_clusterip_port:
#@ if data.values.deprecated_service_http_clusterip_port:
- name: http
protocol: TCP
port: #@ data.values.service_http_clusterip_port
port: #@ data.values.deprecated_service_http_clusterip_port
targetPort: 8080
#@ end
#@ if data.values.service_https_clusterip_port:
@@ -63,7 +82,7 @@ spec:
#@ end
#@ end
#@ if data.values.service_http_loadbalancer_port or data.values.service_https_loadbalancer_port:
#@ if data.values.deprecated_service_http_loadbalancer_port or data.values.service_https_loadbalancer_port:
---
apiVersion: v1
kind: Service
@@ -71,17 +90,20 @@ metadata:
name: #@ defaultResourceNameWithSuffix("loadbalancer")
namespace: #@ namespace()
labels: #@ labels()
#! prevent kapp from altering the selector of our services to match kubectl behavior
annotations:
kapp.k14s.io/disable-default-label-scoping-rules: ""
spec:
type: LoadBalancer
selector: #@ defaultLabel()
selector: #@ deploymentPodLabel()
#@ if data.values.service_loadbalancer_ip:
loadBalancerIP: #@ data.values.service_loadbalancer_ip
#@ end
ports:
#@ if data.values.service_http_loadbalancer_port:
#@ if data.values.deprecated_service_http_loadbalancer_port:
- name: http
protocol: TCP
port: #@ data.values.service_http_loadbalancer_port
port: #@ data.values.deprecated_service_http_loadbalancer_port
targetPort: 8080
#@ end
#@ if data.values.service_https_loadbalancer_port:

View File

@@ -1,4 +1,4 @@
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
#! SPDX-License-Identifier: Apache-2.0
#@data/values
@@ -35,33 +35,95 @@ image_tag: latest
#! Optional.
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
#! Specify how to expose the Supervisor app's HTTP and/or HTTPS ports as a Service.
#! Typically you would set a value for only one of the following service types, for either HTTP or HTTPS depending on your needs.
#! An HTTP service should not be exposed outside the cluster. It would not be secure to serve OIDC endpoints to end users via HTTP.
#! Setting any of these values means that a Service of that type will be created.
#! Specify how to expose the Supervisor app's HTTPS port as a Service.
#! Typically, you would set a value for only one of the following service types.
#! Setting any of these values means that a Service of that type will be created. They are all optional.
#! Note that all port numbers should be numbers (not strings), i.e. use ytt's `--data-value-yaml` instead of `--data-value`.
service_http_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`; e.g. 31234
service_http_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_http_nodeport_port` is specified; e.g. 31234
service_http_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
service_http_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
#! Several of these values have been deprecated and will be removed in a future release. Their names have been changed to
#! mark them as deprecated and to make it obvious upon upgrade to anyone who was using them that they have been deprecated.
deprecated_service_http_nodeport_port: #! will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`; e.g. 31234
deprecated_service_http_nodeport_nodeport: #! will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified; e.g. 31234
deprecated_service_http_loadbalancer_port: #! will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
deprecated_service_http_clusterip_port: #! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
service_https_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`; e.g. 31243
service_https_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_http_nodeport_port` is specified; e.g. 31243
service_https_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified; e.g. 31243
service_https_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
service_https_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
#! The `loadBalancerIP` value of the LoadBalancer Service.
#! Ignored unless service_http_loadbalancer_port and/or service_https_loadbalancer_port are provided.
#! Ignored unless service_https_loadbalancer_port is provided.
#! Optional.
service_loadbalancer_ip: #! e.g. 1.2.3.4
#! Specify the verbosity of logging: info ("nice to know" information), debug (developer
#! information), trace (timing information), all (kitchen sink).
#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information),
#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged.
log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs.
run_as_user: 1001 #! run_as_user specifies the user ID that will own the process
run_as_group: 1001 #! run_as_group specifies the group ID that will own the process
run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice
run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice
#! Specify the API group suffix for all Pinniped API groups. By default, this is set to
#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev,
#! authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then
#! Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc.
api_group_suffix: pinniped.dev
#! Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers.
#! These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS,
#! e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider.
#! The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY.
#! Optional.
https_proxy: #! e.g. http://proxy.example.com
no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints
#! Control the HTTP and HTTPS listeners of the Supervisor.
#!
#! The schema of this config is as follows:
#!
#! endpoints:
#! https:
#! network: tcp | unix | disabled
#! address: host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix
#! http:
#! network: same as above
#! address: same as above, except that when network=tcp then the address is only allowed to bind to loopback interfaces
#!
#! Setting network to disabled turns off that particular listener.
#! See https://pkg.go.dev/net#Listen and https://pkg.go.dev/net#Dial for a description of what can be
#! specified in the address parameter based on the given network parameter. To aid in the use of unix
#! domain sockets, a writable empty dir volume is mounted at /pinniped_socket when network is set to "unix."
#!
#! The current defaults are:
#!
#! endpoints:
#! https:
#! network: tcp
#! address: :8443
#! http:
#! network: disabled
#!
#! These defaults mean: For HTTPS listening, bind to all interfaces using TCP on port 8443.
#! Disable HTTP listening by default.
#!
#! The HTTP listener can only be bound to loopback interfaces. This allows the listener to accept
#! traffic from within the pod, e.g. from a service mesh sidecar. The HTTP listener should not be
#! used to accept traffic from outside the pod, since that would mean that the network traffic could be
#! transmitted unencrypted. The HTTPS listener should be used instead to accept traffic from outside the pod.
#! Ingresses and load balancers that terminate TLS connections should re-encrypt the data and route traffic
#! to the HTTPS listener. Unix domain sockets may also be used for integrations with service meshes.
#!
#! Changing the HTTPS port number must be accompanied by matching changes to the service and deployment
#! manifests. Changes to the HTTPS listener must be coordinated with the deployment health checks.
#!
#! Optional.
endpoints:
#! Optionally override the validation on the endpoints.http value which checks that only loopback interfaces are used.
#! When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any
#! interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced
#! to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time
#! to change their ingress strategy to avoid using plain HTTP into the Supervisor pods.
#! This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time
#! traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available.
#! Allowed values are true (boolean), "true" (string), false (boolean), and "false" (string). The default is false.
#! Optional.
deprecated_insecure_accept_external_unencrypted_http_requests: false

View File

@@ -31,3 +31,12 @@ metadata:
name: #@ pinnipedDevAPIGroupWithPrefix("ldapidentityproviders.idp.supervisor")
spec:
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"activedirectoryidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
---
metadata:
#@overlay/match missing_ok=True
labels: #@ labels()
name: #@ pinnipedDevAPIGroupWithPrefix("activedirectoryidentityproviders.idp.supervisor")
spec:
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")

View File

@@ -24,7 +24,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped concierge authenticatio
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-condition"]
==== Condition
Condition status of a resource (mirrored from the metav1.Condition type added in Kubernetes 1.19). In a future API version we can switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
.Appears In:
****
@@ -36,7 +36,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped concierge authenticatio
|===
| Field | Description
| *`type`* __string__ | type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
| *`status`* __ConditionStatus__ | status of the condition, one of True, False, Unknown.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-conditionstatus[$$ConditionStatus$$]__ | status of the condition, one of True, False, Unknown.
| *`observedGeneration`* __integer__ | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
| *`lastTransitionTime`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#time-v1-meta[$$Time$$]__ | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
| *`reason`* __string__ | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
@@ -47,7 +47,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped concierge authenticatio
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-conditionstatus"]
==== ConditionStatus (string)
ConditionStatus is effectively an enum type for Condition.Status.
.Appears In:
****
@@ -137,7 +137,7 @@ JWTTokenClaims allows customization of the claims that will be mapped to user id
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-tlsspec"]
==== TLSSpec
Configuration for configuring TLS on various authenticators.
.Appears In:
****
@@ -240,7 +240,7 @@ CredentialIssuer describes the configuration and status of the Pinniped Concierg
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-credentialissuerfrontend"]
==== CredentialIssuerFrontend
CredentialIssuerFrontend describes how to connect using a particular integration strategy.
.Appears In:
****
@@ -259,7 +259,7 @@ CredentialIssuer describes the configuration and status of the Pinniped Concierg
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer. This type is deprecated and will be removed in a future version.
.Appears In:
****
@@ -314,7 +314,7 @@ CredentialIssuerStatus describes the status of the Concierge.
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-credentialissuerstrategy"]
==== CredentialIssuerStrategy
CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
.Appears In:
****
@@ -336,7 +336,7 @@ CredentialIssuerStatus describes the status of the Concierge.
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
==== ImpersonationProxyInfo
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
.Appears In:
****
@@ -354,7 +354,7 @@ CredentialIssuerStatus describes the status of the Concierge.
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-impersonationproxymode"]
==== ImpersonationProxyMode (string)
ImpersonationProxyMode enumerates the configuration modes for the impersonation proxy.
.Appears In:
****
@@ -376,7 +376,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`type`* __ImpersonationProxyServiceType__ | Type specifies the type of Service to provision for the impersonation proxy.
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-impersonationproxyservicetype[$$ImpersonationProxyServiceType$$]__ | Type specifies the type of Service to provision for the impersonation proxy.
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
@@ -386,7 +386,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-impersonationproxyservicetype"]
==== ImpersonationProxyServiceType (string)
ImpersonationProxyServiceType enumerates the types of service that can be provisioned for the impersonation proxy.
.Appears In:
****
@@ -398,7 +398,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-impersonationproxyspec"]
==== ImpersonationProxySpec
ImpersonationProxySpec describes the intended configuration of the Concierge impersonation proxy.
.Appears In:
****
@@ -408,17 +408,17 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`mode`* __ImpersonationProxyMode__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name.
This field must be non-empty when spec.impersonationProxy.service.mode is "None".
This field must be non-empty when spec.impersonationProxy.service.type is "None".
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
==== TokenCredentialRequestAPIInfo
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
.Appears In:
****
@@ -538,7 +538,7 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
SecretName is required if you would like to use different TLS certificates for issuers of different hostnames. SNI requests do not include port numbers, so all issuers with the same DNS hostname must use the same SecretName value even if they have different port numbers.
SecretName is not required when you would like to use only the HTTP endpoints (e.g. when terminating TLS at an Ingress). It is also not required when you would like all requests to this OIDC Provider's HTTPS endpoints to use the default TLS certificate, which is configured elsewhere.
SecretName is not required when you would like to use only the HTTP endpoints (e.g. when the HTTP listener is configured to listen on loopback interfaces or UNIX domain sockets for traffic from a service mesh sidecar). It is also not required when you would like all requests to this OIDC Provider's HTTPS endpoints to use the default TLS certificate, which is configured elsewhere.
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|===
@@ -748,13 +748,169 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity pro
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition"]
==== Condition
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovider"]
==== ActiveDirectoryIdentityProvider
ActiveDirectoryIdentityProvider describes the configuration of an upstream Microsoft Active Directory identity provider.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderlist[$$ActiveDirectoryIdentityProviderList$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderspec[$$ActiveDirectoryIdentityProviderSpec$$]__ | Spec for configuring the identity provider.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderstatus[$$ActiveDirectoryIdentityProviderStatus$$]__ | Status of the identity provider.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderbind"]
==== ActiveDirectoryIdentityProviderBind
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderspec[$$ActiveDirectoryIdentityProviderSpec$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`secretName`* __string__ | SecretName contains the name of a namespace-local Secret object that provides the username and password for an Active Directory bind user. This account will be used to perform LDAP searches. The Secret should be of type "kubernetes.io/basic-auth" which includes "username" and "password" keys. The username value should be the full dn (distinguished name) of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password must be non-empty.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearch"]
==== ActiveDirectoryIdentityProviderGroupSearch
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderspec[$$ActiveDirectoryIdentityProviderSpec$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". Optional, when not specified it will be based on the result of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). The default behavior searches your entire domain for groups. It may make sense to specify a subtree as a search base if you wish to exclude some groups for security reasons or to make searches faster.
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes"]
==== ActiveDirectoryIdentityProviderGroupSearchAttributes
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearch[$$ActiveDirectoryIdentityProviderGroupSearch$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`groupName`* __string__ | GroupName specifies the name of the attribute in the Active Directory entries whose value shall become a group name in the user's list of groups after a successful authentication. The value of this field is case-sensitive and must match the case of the attribute name returned by the ActiveDirectory server in the user's entry. E.g. "cn" for common name. Distinguished names can be used by specifying lower-case "dn". Optional. When not specified, this defaults to a custom field that looks like "sAMAccountName@domain", where domain is constructed from the domain components of the group DN.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderspec"]
==== ActiveDirectoryIdentityProviderSpec
Spec for configuring an ActiveDirectory identity provider.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovider[$$ActiveDirectoryIdentityProvider$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`host`* __string__ | Host is the hostname of this Active Directory identity provider, i.e., where to connect. For example: ldap.example.com:636.
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS contains the connection settings for how to establish the connection to the Host.
| *`bind`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderbind[$$ActiveDirectoryIdentityProviderBind$$]__ | Bind contains the configuration for how to provide access credentials during an initial bind to the ActiveDirectory server to be allowed to perform searches and binds to validate a user's credentials during a user's authentication attempt.
| *`userSearch`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderusersearch[$$ActiveDirectoryIdentityProviderUserSearch$$]__ | UserSearch contains the configuration for searching for a user by name in Active Directory.
| *`groupSearch`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearch[$$ActiveDirectoryIdentityProviderGroupSearch$$]__ | GroupSearch contains the configuration for searching for a user's group membership in ActiveDirectory.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderstatus"]
==== ActiveDirectoryIdentityProviderStatus
Status of an Active Directory identity provider.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovider[$$ActiveDirectoryIdentityProvider$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`phase`* __ActiveDirectoryIdentityProviderPhase__ | Phase summarizes the overall status of the ActiveDirectoryIdentityProvider.
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderusersearch"]
==== ActiveDirectoryIdentityProviderUserSearch
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderspec[$$ActiveDirectoryIdentityProviderSpec$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com". Optional, when not specified it will be based on the result of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). The default behavior searches your entire domain for users. It may make sense to specify a subtree as a search base if you wish to exclude some users or to make searches faster.
| *`filter`* __string__ | Filter is the search filter which should be applied when searching for users. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the username for which the search is being run. E.g. "mail={}" or "&(objectClass=person)(uid={})". For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will be '(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(\|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))' This means that the user is a person, is not a computer, the sAMAccountType is for a normal user account, and is not shown in advanced view only (which would likely mean its a system created service account with advanced permissions). Also, either the sAMAccountName, the userPrincipalName, or the mail attribute matches the input username.
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderusersearchattributes[$$ActiveDirectoryIdentityProviderUserSearchAttributes$$]__ | Attributes specifies how the user's information should be read from the ActiveDirectory entry which was found as the result of the user search.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderusersearchattributes"]
==== ActiveDirectoryIdentityProviderUserSearchAttributes
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderusersearch[$$ActiveDirectoryIdentityProviderUserSearch$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`username`* __string__ | Username specifies the name of the attribute in Active Directory entry whose value shall become the username of the user after a successful authentication. Optional, when empty this defaults to "userPrincipalName".
| *`uid`* __string__ | UID specifies the name of the attribute in the ActiveDirectory entry which whose value shall be used to uniquely identify the user within this ActiveDirectory provider after a successful authentication. Optional, when empty this defaults to "objectGUID".
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition"]
==== Condition
Condition status of a resource (mirrored from the metav1.Condition type added in Kubernetes 1.19). In a future API version we can switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderstatus[$$ActiveDirectoryIdentityProviderStatus$$]
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcidentityproviderstatus[$$OIDCIdentityProviderStatus$$]
****
@@ -763,7 +919,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity pro
|===
| Field | Description
| *`type`* __string__ | type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
| *`status`* __ConditionStatus__ | status of the condition, one of True, False, Unknown.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-conditionstatus[$$ConditionStatus$$]__ | status of the condition, one of True, False, Unknown.
| *`observedGeneration`* __integer__ | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
| *`lastTransitionTime`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#time-v1-meta[$$Time$$]__ | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
| *`reason`* __string__ | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
@@ -774,7 +930,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity pro
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-conditionstatus"]
==== ConditionStatus (string)
ConditionStatus is effectively an enum type for Condition.Status.
.Appears In:
****
@@ -836,6 +992,10 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". When not specified, no group search will be performed and authenticated users will not belong to any groups from the LDAP provider. Also, when not specified, the values of Filter and Attributes are ignored.
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|===
@@ -947,7 +1107,9 @@ OIDCAuthorizationConfig provides information about how to form the OAuth2 author
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`additionalScopes`* __string array__ | AdditionalScopes are the scopes in addition to "openid" that will be requested as part of the authorization request flow with an OIDC identity provider. By default only the "openid" scope will be requested.
| *`additionalScopes`* __string array__ | additionalScopes are the additional scopes that will be requested from your OIDC provider in the authorization request during an OIDC Authorization Code Flow and in the token request during a Resource Owner Password Credentials Grant. Note that the "openid" scope will always be requested regardless of the value in this setting, since it is always required according to the OIDC spec. By default, when this field is not set, the Supervisor will request the following scopes: "openid", "offline_access", "email", and "profile". See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims for a description of the "profile" and "email" scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess for a description of the "offline_access" scope. This default value may change in future versions of Pinniped as the standard evolves, or as common patterns used by providers who implement the standard in the ecosystem evolve. By setting this list to anything other than an empty list, you are overriding the default value, so you may wish to include some of "offline_access", "email", and "profile" in your override list. If you do not want any of these scopes to be requested, you may set this list to contain only "openid". Some OIDC providers may also require a scope to get access to the user's group membership, in which case you may wish to include it in this list. Sometimes the scope to request the user's group membership is called "groups", but unfortunately this is not specified in the OIDC standard. Generally speaking, you should include any scopes required to cause the appropriate claims to be the returned by your OIDC provider in the ID token or userinfo endpoint results for those claims which you would like to use in the oidcClaims settings to determine the usernames and group memberships of your Kubernetes users. See your OIDC provider's documentation for more information about what scopes are available to request claims. Additionally, the Pinniped Supervisor requires that your OIDC provider returns refresh tokens to the Supervisor from these authorization flows. For most OIDC providers, the scope required to receive refresh tokens will be "offline_access". See the documentation of your OIDC provider's authorization and token endpoints for its requirements for what to include in the request in order to receive a refresh token in the response, if anything. Note that it may be safe to send "offline_access" even to providers which do not require it, since the provider may ignore scopes that it does not understand or require (see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3). In the unusual case that you must avoid sending the "offline_access" scope, then you must override the default value of this setting. This is required if your OIDC provider will reject the request when it includes "offline_access" (e.g. GitLab's OIDC provider).
| *`additionalAuthorizeParameters`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-parameter[$$Parameter$$] array__ | additionalAuthorizeParameters are extra query parameters that should be included in the authorize request to your OIDC provider in the authorization request during an OIDC Authorization Code Flow. By default, no extra parameters are sent. The standard parameters that will be sent are "response_type", "scope", "client_id", "state", "nonce", "code_challenge", "code_challenge_method", and "redirect_uri". These parameters cannot be included in this setting. Additionally, the "hd" parameter cannot be included in this setting at this time. The "hd" parameter is used by Google's OIDC provider to provide a hint as to which "hosted domain" the user should use during login. However, Pinniped does not yet support validating the hosted domain in the resulting ID token, so it is not yet safe to use this feature of Google's OIDC provider with Pinniped. This setting does not influence the parameters sent to the token endpoint in the Resource Owner Password Credentials Grant. The Pinniped Supervisor requires that your OIDC provider returns refresh tokens to the Supervisor from the authorization flows. Some OIDC providers may require a certain value for the "prompt" parameter in order to properly request refresh tokens. See the documentation of your OIDC provider's authorization endpoint for its requirements for what to include in the request in order to receive a refresh token in the response, if anything. If your provider requires the prompt parameter to request a refresh token, then include it here. Also note that most providers also require a certain scope to be requested in order to receive refresh tokens. See the additionalScopes setting for more information about using scopes to request refresh tokens.
| *`allowPasswordGrant`* __boolean__ | allowPasswordGrant, when true, will allow the use of OAuth 2.0's Resource Owner Password Credentials Grant (see https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to authenticate to the OIDC provider using a username and password without a web browser, in addition to the usual browser-based OIDC Authorization Code Flow. The Resource Owner Password Credentials Grant is not officially part of the OIDC specification, so it may not be supported by your OIDC provider. If your OIDC provider supports returning ID tokens from a Resource Owner Password Credentials Grant token request, then you can choose to set this field to true. This will allow end users to choose to present their username and password to the kubectl CLI (using the Pinniped plugin) to authenticate to the cluster, without using a web browser to log in as is customary in OIDC Authorization Code Flow. This may be convenient for users, especially for identities from your OIDC provider which are not intended to represent a human actor, such as service accounts performing actions in a CI/CD environment. Even if your OIDC provider supports it, you may wish to disable this behavior by setting this field to false when you prefer to only allow users of this OIDCIdentityProvider to log in via the browser-based OIDC Authorization Code Flow. Using the Resource Owner Password Credentials Grant means that the Pinniped CLI and Pinniped Supervisor will directly handle your end users' passwords (similar to LDAPIdentityProvider), and you will not be able to require multi-factor authentication or use the other web-based login features of your OIDC provider during Resource Owner Password Credentials Grant logins. allowPasswordGrant defaults to false.
|===
@@ -964,8 +1126,8 @@ OIDCClaims provides a mapping from upstream claims into identities.
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`groups`* __string__ | Groups provides the name of the token claim that will be used to ascertain the groups to which an identity belongs.
| *`username`* __string__ | Username provides the name of the token claim that will be used to ascertain an identity's username.
| *`groups`* __string__ | Groups provides the name of the ID token claim or userinfo endpoint response claim that will be used to ascertain the groups to which an identity belongs. By default, the identities will not include any group memberships when this setting is not configured.
| *`username`* __string__ | Username provides the name of the ID token claim or userinfo endpoint response claim that will be used to ascertain an identity's username. When not set, the username will be an automatically constructed unique string which will include the issuer URL of your OIDC provider along with the value of the "sub" (subject) claim from the ID token.
|===
@@ -1011,7 +1173,7 @@ OIDCIdentityProvider describes the configuration of an upstream OpenID Connect i
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcidentityproviderspec"]
==== OIDCIdentityProviderSpec
Spec for configuring an OIDC identity provider.
OIDCIdentityProviderSpec is the spec for configuring an OIDC identity provider.
.Appears In:
****
@@ -1032,7 +1194,7 @@ Spec for configuring an OIDC identity provider.
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcidentityproviderstatus"]
==== OIDCIdentityProviderStatus
Status of an OIDC identity provider.
OIDCIdentityProviderStatus is the status of an OIDC identity provider.
.Appears In:
****
@@ -1047,13 +1209,32 @@ Status of an OIDC identity provider.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-tlsspec"]
==== TLSSpec
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-parameter"]
==== Parameter
Parameter is a key/value pair which represents a parameter in an HTTP request.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcauthorizationconfig[$$OIDCAuthorizationConfig$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`name`* __string__ | The name of the parameter. Required.
| *`value`* __string__ | The value of the parameter.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-tlsspec"]
==== TLSSpec
Configuration for TLS parameters related to identity provider integration.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityproviderspec[$$ActiveDirectoryIdentityProviderSpec$$]
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcidentityproviderspec[$$OIDCIdentityProviderSpec$$]
****

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -61,6 +61,8 @@ type JWTTokenClaims struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories=pinniped;pinniped-authenticator;pinniped-authenticators,scope=Cluster
// +kubebuilder:printcolumn:name="Issuer",type=string,JSONPath=`.spec.issuer`
// +kubebuilder:printcolumn:name="Audience",type=string,JSONPath=`.spec.audience`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:subresource:status
type JWTAuthenticator struct {
metav1.TypeMeta `json:",inline"`

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
@@ -33,6 +33,7 @@ type WebhookAuthenticatorSpec struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:categories=pinniped;pinniped-authenticator;pinniped-authenticators,scope=Cluster
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=`.spec.endpoint`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:subresource:status
type WebhookAuthenticator struct {
metav1.TypeMeta `json:",inline"`

View File

@@ -1,6 +1,7 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Code generated by deepcopy-gen. DO NOT EDIT.

View File

@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// +k8s:openapi-gen=true

Some files were not shown because too many files have changed in this diff Show More