mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-31 01:52:38 +00:00
Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf98c69c0d | ||
|
|
62f6d8516b | ||
|
|
604ecc583c | ||
|
|
a010794873 | ||
|
|
c7462bf1f6 | ||
|
|
b396d12456 | ||
|
|
695ea3a165 | ||
|
|
d625ada06a | ||
|
|
0f48620d9c | ||
|
|
c2496aab6b | ||
|
|
00734d143e | ||
|
|
d90b3c23ef | ||
|
|
035dbffd28 | ||
|
|
e3710289e5 | ||
|
|
99b67b89ac | ||
|
|
e374841857 | ||
|
|
9f2336476f | ||
|
|
63b560d740 | ||
|
|
f54834cbee | ||
|
|
749633e43c | ||
|
|
308c76cd69 | ||
|
|
fc9a261b77 | ||
|
|
d2d860bd3b | ||
|
|
9cb3638354 | ||
|
|
6133276555 | ||
|
|
a7a3016ae5 | ||
|
|
dd0dcad8c4 | ||
|
|
ed8c9448de | ||
|
|
5e80fb26f0 | ||
|
|
292855332c | ||
|
|
68b0dd83f2 | ||
|
|
611fc61c12 | ||
|
|
2cd4a2c730 | ||
|
|
3e89915a98 | ||
|
|
f4aaee8bd7 | ||
|
|
d56413a289 | ||
|
|
27b629af3a | ||
|
|
1a3cb65fa4 | ||
|
|
4b3eb0e6ec | ||
|
|
f89b13bc62 | ||
|
|
8b7fec5049 | ||
|
|
3a6573f89e | ||
|
|
4e04f5b606 | ||
|
|
39a86e7d52 | ||
|
|
8cfc1c08ec | ||
|
|
c90637398d | ||
|
|
737aabb620 | ||
|
|
0e930b3d63 | ||
|
|
876f626e7d | ||
|
|
0dc704be9c | ||
|
|
e437832698 | ||
|
|
274ca4cb73 | ||
|
|
a99ff646a0 | ||
|
|
02eb26f135 | ||
|
|
e90f19f8ab | ||
|
|
00c2c5cf6e | ||
|
|
3386774f5f | ||
|
|
7e4330be93 | ||
|
|
f5b3e6da93 | ||
|
|
5c39374915 | ||
|
|
4fdb931141 | ||
|
|
3a02854192 | ||
|
|
63c071d6ea | ||
|
|
6dc96f4224 | ||
|
|
aa8f8f7fda | ||
|
|
f5167bb279 | ||
|
|
b84eafc173 | ||
|
|
50ed1b0cf9 | ||
|
|
1d873be184 | ||
|
|
5a0d6eddb1 | ||
|
|
31b45525ce | ||
|
|
430c73b903 | ||
|
|
cc1befbc57 | ||
|
|
68a0ad4112 | ||
|
|
9aca187559 | ||
|
|
d0fb9f3637 | ||
|
|
51d1bc32e8 | ||
|
|
e9b9dd6fa3 | ||
|
|
7e43aa4e12 | ||
|
|
de509db7be | ||
|
|
69c6676d8f | ||
|
|
2ab11dccfc | ||
|
|
d64b4677b9 | ||
|
|
f040f098dc | ||
|
|
abe3391cce | ||
|
|
6ae27c87f6 | ||
|
|
3d2446d235 | ||
|
|
4f01b3157f | ||
|
|
14e728aa0d | ||
|
|
4a266a44db | ||
|
|
900db0d3a3 | ||
|
|
8b95b141b2 | ||
|
|
5a9f2f3181 | ||
|
|
4f43f01e55 | ||
|
|
7221be5a8a | ||
|
|
83ab099b84 | ||
|
|
5f79860c8c | ||
|
|
e4f7b5d181 | ||
|
|
9619a0f226 | ||
|
|
23f414c384 | ||
|
|
4872be0a84 | ||
|
|
691307a269 | ||
|
|
6d846ad2a9 | ||
|
|
ff24c757b7 | ||
|
|
ee4663aa19 | ||
|
|
119c591500 | ||
|
|
275412e902 | ||
|
|
fe75ebe4b2 | ||
|
|
fabb80cf19 | ||
|
|
7577f20c61 | ||
|
|
f441714f93 | ||
|
|
2c9547e6a4 | ||
|
|
3bf3ed03f5 | ||
|
|
c279253e20 | ||
|
|
fa9ddf48d5 | ||
|
|
b8a9c4d1e5 | ||
|
|
b4365c100f | ||
|
|
ef4b0c9cff | ||
|
|
b625b4a076 | ||
|
|
acbe9ce23d | ||
|
|
90c95866d1 | ||
|
|
57fc177266 | ||
|
|
0366f4087f | ||
|
|
3f6d287b44 | ||
|
|
36aa701b56 | ||
|
|
fc5a776645 | ||
|
|
c2b4390bfa |
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
@@ -71,12 +71,6 @@ updates:
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/go-lint-runner/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/integration-test-runner/"
|
||||
open-pull-requests-limit: 100
|
||||
|
||||
13
Dockerfile
13
Dockerfile
@@ -1,10 +1,10 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ARG BUILD_IMAGE=golang:1.23.4@sha256:574185e5c6b9d09873f455a7c205ea0514bfd99738c5dc7750196403a44ed4b7
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:6cd937e9155bdfd805d1b94e037f9d6a899603306030936a3b11680af0c2ed58
|
||||
ARG BUILD_IMAGE=golang:1.24.1@sha256:af0bb3052d6700e1bc70a37bca483dc8d76994fd16ae441ad72390eea6016d03
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:b35229a3a6398fe8f86138c74c611e386f128c20378354fc5442811700d5600d
|
||||
|
||||
# Prepare to cross-compile by always running the build stage in the build platform, not the target platform.
|
||||
FROM --platform=$BUILDPLATFORM $BUILD_IMAGE AS build-env
|
||||
@@ -21,6 +21,9 @@ ENV KUBE_GIT_VERSION=$KUBE_GIT_VERSION
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
# If provided, must be a comma-separated list of Go build tags.
|
||||
ARG ADDITIONAL_BUILD_TAGS
|
||||
|
||||
# Build the statically linked (CGO_ENABLED=0) binary.
|
||||
# Mount source, build cache, and module cache for performance reasons.
|
||||
# See https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
|
||||
@@ -29,8 +32,8 @@ RUN \
|
||||
--mount=type=cache,target=/cache/gocache \
|
||||
--mount=type=cache,target=/cache/gomodcache \
|
||||
export GOCACHE=/cache/gocache GOMODCACHE=/cache/gomodcache CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH && \
|
||||
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/... && \
|
||||
go build -tags $ADDITIONAL_BUILD_TAGS -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 -tags $ADDITIONAL_BUILD_TAGS -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
|
||||
|
||||
@@ -47,4 +47,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-2024 the Pinniped contributors. All Rights Reserved.
|
||||
Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -1,34 +1,36 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
|
||||
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||
"go.pinniped.dev/internal/groupsuffix"
|
||||
"go.pinniped.dev/internal/kubeclient"
|
||||
)
|
||||
|
||||
// getConciergeClientsetFunc is a function that can return a clientset for the Concierge API given a
|
||||
// getClientsetsFunc is a function that can return clients for the Concierge and Kubernetes APIs given a
|
||||
// clientConfig and the apiGroupSuffix with which the API is running.
|
||||
type getConciergeClientsetFunc func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error)
|
||||
type getClientsetsFunc func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error)
|
||||
|
||||
// getRealConciergeClientset returns a real implementation of a conciergeclientset.Interface.
|
||||
func getRealConciergeClientset(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error) {
|
||||
// getRealClientsets returns real implementations of the Concierge and Kubernetes client interfaces.
|
||||
func getRealClientsets(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error) {
|
||||
restConfig, err := clientConfig.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
client, err := kubeclient.New(
|
||||
kubeclient.WithConfig(restConfig),
|
||||
kubeclient.WithMiddleware(groupsuffix.New(apiGroupSuffix)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return client.PinnipedConcierge, nil
|
||||
return client.PinnipedConcierge, client.Kubernetes, client.Aggregation, nil
|
||||
}
|
||||
|
||||
// newClientConfig returns a clientcmd.ClientConfig given an optional kubeconfig path override and
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -20,10 +20,12 @@ import (
|
||||
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||
_ "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"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
@@ -38,7 +40,7 @@ import (
|
||||
type kubeconfigDeps struct {
|
||||
getenv func(key string) string
|
||||
getPathToSelf func() (string, error)
|
||||
getClientset getConciergeClientsetFunc
|
||||
getClientsets getClientsetsFunc
|
||||
log plog.MinLogger
|
||||
}
|
||||
|
||||
@@ -46,7 +48,7 @@ func kubeconfigRealDeps() kubeconfigDeps {
|
||||
return kubeconfigDeps{
|
||||
getenv: os.Getenv,
|
||||
getPathToSelf: os.Executable,
|
||||
getClientset: getRealConciergeClientset,
|
||||
getClientsets: getRealClientsets,
|
||||
log: plog.New(),
|
||||
}
|
||||
}
|
||||
@@ -215,7 +217,7 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
return fmt.Errorf("could not load --kubeconfig/--kubeconfig-context: %w", err)
|
||||
}
|
||||
cluster := currentKubeConfig.Clusters[currentKubeconfigNames.ClusterName]
|
||||
clientset, err := deps.getClientset(clientConfig, flags.concierge.apiGroupSuffix)
|
||||
conciergeClient, kubeClient, aggregatorClient, err := deps.getClientsets(clientConfig, flags.concierge.apiGroupSuffix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not configure Kubernetes client: %w", err)
|
||||
}
|
||||
@@ -228,13 +230,15 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
}
|
||||
|
||||
if !flags.concierge.disabled {
|
||||
credentialIssuer, err := waitForCredentialIssuer(ctx, clientset, flags, deps)
|
||||
// Look up the Concierge's CredentialIssuer, and optionally wait for it to have no pending strategies showing in its status.
|
||||
credentialIssuer, err := waitForCredentialIssuer(ctx, conciergeClient, flags, deps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Decide which Concierge authenticator should be used in the resulting kubeconfig.
|
||||
authenticator, err := lookupAuthenticator(
|
||||
clientset,
|
||||
conciergeClient,
|
||||
flags.concierge.authenticatorType,
|
||||
flags.concierge.authenticatorName,
|
||||
deps.log,
|
||||
@@ -242,10 +246,15 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Discover from the CredentialIssuer how the resulting kubeconfig should be configured to talk to this Concierge.
|
||||
if err := discoverConciergeParams(credentialIssuer, &flags, cluster, deps.log); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := discoverAuthenticatorParams(authenticator, &flags, deps.log); err != nil {
|
||||
|
||||
// Discover how the resulting kubeconfig should interact with the selected authenticator.
|
||||
// For a JWTAuthenticator, this includes discovering how to talk to the OIDC issuer configured in its spec fields.
|
||||
if err := discoverAuthenticatorParams(ctx, authenticator, &flags, kubeClient, aggregatorClient, deps.log); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -255,6 +264,7 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
}
|
||||
|
||||
if len(flags.oidc.issuer) > 0 {
|
||||
// The OIDC provider may or may not be a Pinniped Supervisor. Find out.
|
||||
err = pinnipedSupervisorDiscovery(ctx, &flags, deps.log)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -488,7 +498,14 @@ func logStrategies(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, l
|
||||
}
|
||||
}
|
||||
|
||||
func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconfigParams, log plog.MinLogger) error {
|
||||
func discoverAuthenticatorParams(
|
||||
ctx context.Context,
|
||||
authenticator metav1.Object,
|
||||
flags *getKubeconfigParams,
|
||||
kubeClient kubernetes.Interface,
|
||||
aggregatorClient aggregatorclient.Interface,
|
||||
log plog.MinLogger,
|
||||
) error {
|
||||
switch auth := authenticator.(type) {
|
||||
case *authenticationv1alpha1.WebhookAuthenticator:
|
||||
// If the --concierge-authenticator-type/--concierge-authenticator-name flags were not set explicitly, set
|
||||
@@ -520,19 +537,130 @@ func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconf
|
||||
}
|
||||
|
||||
// If the --oidc-ca-bundle flags was not set explicitly, default it to the
|
||||
// spec.tls.certificateAuthorityData field of the JWTAuthenticator.
|
||||
if len(flags.oidc.caBundle) == 0 && auth.Spec.TLS != nil && auth.Spec.TLS.CertificateAuthorityData != "" {
|
||||
decoded, err := base64.StdEncoding.DecodeString(auth.Spec.TLS.CertificateAuthorityData)
|
||||
// spec.tls.certificateAuthorityData field of the JWTAuthenticator, if that field is set, or else
|
||||
// try to discover it from the spec.tls.certificateAuthorityDataSource, if that field is set.
|
||||
if len(flags.oidc.caBundle) == 0 && auth.Spec.TLS != nil {
|
||||
err := discoverOIDCCABundle(ctx, auth, flags, kubeClient, aggregatorClient, log)
|
||||
if err != nil {
|
||||
return fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator %s has invalid spec.tls.certificateAuthorityData: %w", auth.Name, err)
|
||||
return err
|
||||
}
|
||||
log.Info("discovered OIDC CA bundle", "roots", countCACerts(decoded))
|
||||
flags.oidc.caBundle = decoded
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func discoverOIDCCABundle(
|
||||
ctx context.Context,
|
||||
jwtAuthenticator *authenticationv1alpha1.JWTAuthenticator,
|
||||
flags *getKubeconfigParams,
|
||||
kubeClient kubernetes.Interface,
|
||||
aggregatorClient aggregatorclient.Interface,
|
||||
log plog.MinLogger,
|
||||
) error {
|
||||
if jwtAuthenticator.Spec.TLS.CertificateAuthorityData != "" {
|
||||
decodedCABundleData, err := base64.StdEncoding.DecodeString(jwtAuthenticator.Spec.TLS.CertificateAuthorityData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator %s has invalid spec.tls.certificateAuthorityData: %w", jwtAuthenticator.Name, err)
|
||||
}
|
||||
log.Info("discovered OIDC CA bundle", "roots", countCACerts(decodedCABundleData))
|
||||
flags.oidc.caBundle = decodedCABundleData
|
||||
} else if jwtAuthenticator.Spec.TLS.CertificateAuthorityDataSource != nil {
|
||||
caBundleData, err := discoverOIDCCABundleFromCertificateAuthorityDataSource(
|
||||
ctx, jwtAuthenticator, flags.concierge.apiGroupSuffix, kubeClient, aggregatorClient, log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
flags.oidc.caBundle = caBundleData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func discoverOIDCCABundleFromCertificateAuthorityDataSource(
|
||||
ctx context.Context,
|
||||
jwtAuthenticator *authenticationv1alpha1.JWTAuthenticator,
|
||||
apiGroupSuffix string,
|
||||
kubeClient kubernetes.Interface,
|
||||
aggregatorClient aggregatorclient.Interface,
|
||||
log plog.MinLogger,
|
||||
) ([]byte, error) {
|
||||
conciergeNamespace, err := discoverConciergeNamespace(ctx, apiGroupSuffix, aggregatorClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator %s: %w", jwtAuthenticator.Name, err)
|
||||
}
|
||||
log.Info("discovered Concierge namespace for API group suffix", "apiGroupSuffix", apiGroupSuffix)
|
||||
|
||||
var caBundleData []byte
|
||||
var keyExisted bool
|
||||
caSource := jwtAuthenticator.Spec.TLS.CertificateAuthorityDataSource
|
||||
|
||||
// Note that the Kind, Name, and Key fields must all be non-empty, and Kind must be Secret or ConfigMap, due to CRD validations.
|
||||
switch caSource.Kind {
|
||||
case authenticationv1alpha1.CertificateAuthorityDataSourceKindConfigMap:
|
||||
caBundleConfigMap, err := kubeClient.CoreV1().ConfigMaps(conciergeNamespace).Get(ctx, caSource.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but encountered error getting %s %s/%s specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource: %w",
|
||||
caSource.Kind, conciergeNamespace, caSource.Name, jwtAuthenticator.Name, err)
|
||||
}
|
||||
var caBundleDataStr string
|
||||
caBundleDataStr, keyExisted = caBundleConfigMap.Data[caSource.Key]
|
||||
caBundleData = []byte(caBundleDataStr)
|
||||
case authenticationv1alpha1.CertificateAuthorityDataSourceKindSecret:
|
||||
caBundleSecret, err := kubeClient.CoreV1().Secrets(conciergeNamespace).Get(ctx, caSource.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but encountered error getting %s %s/%s specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource: %w",
|
||||
caSource.Kind, conciergeNamespace, caSource.Name, jwtAuthenticator.Name, err)
|
||||
}
|
||||
caBundleData, keyExisted = caBundleSecret.Data[caSource.Key]
|
||||
default:
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.Kind value %q is not supported by this CLI version",
|
||||
jwtAuthenticator.Name, caSource.Kind)
|
||||
}
|
||||
|
||||
if !keyExisted {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but key %q specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.key does not exist in %s %s/%s",
|
||||
caSource.Key, jwtAuthenticator.Name, caSource.Kind, conciergeNamespace, caSource.Name)
|
||||
}
|
||||
|
||||
if len(caBundleData) == 0 {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but key %q specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.key exists but has empty value in %s %s/%s",
|
||||
caSource.Key, jwtAuthenticator.Name, caSource.Kind, conciergeNamespace, caSource.Name)
|
||||
}
|
||||
|
||||
numCACerts := countCACerts(caBundleData)
|
||||
if numCACerts == 0 {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but value at key %q specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.key does not contain any CA certificates in %s %s/%s",
|
||||
caSource.Key, jwtAuthenticator.Name, caSource.Kind, conciergeNamespace, caSource.Name)
|
||||
}
|
||||
|
||||
log.Info("discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource", "roots", numCACerts)
|
||||
return caBundleData, nil
|
||||
}
|
||||
|
||||
func discoverConciergeNamespace(ctx context.Context, apiGroupSuffix string, aggregatorClient aggregatorclient.Interface) (string, error) {
|
||||
// Let's look for the APIService for the API group of the Concierge's TokenCredentialRequest aggregated API.
|
||||
apiGroup := "login.concierge." + apiGroupSuffix
|
||||
|
||||
// List all APIServices.
|
||||
apiServiceList, err := aggregatorClient.ApiregistrationV1().APIServices().List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error listing APIServices: %w", err)
|
||||
}
|
||||
|
||||
// Find one with the expected API group name.
|
||||
for _, apiService := range apiServiceList.Items {
|
||||
if apiService.Spec.Group == apiGroup {
|
||||
if apiService.Spec.Service.Namespace != "" {
|
||||
// We are assuming that all API versions (e.g. v1alpha1) of this API group are backed by service(s)
|
||||
// in the same namespace, which is the namespace of the Concierge hosting this API suffix.
|
||||
return apiService.Spec.Service.Namespace, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find any APIService for the expected API group name which contained a namespace reference in its spec.
|
||||
return "", fmt.Errorf("could not find APIService with non-empty spec.service.namespace for API group %s", apiGroup)
|
||||
}
|
||||
|
||||
func getConciergeFrontend(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, mode conciergeModeFlag) (*conciergeconfigv1alpha1.CredentialIssuerFrontend, error) {
|
||||
for _, strategy := range credentialIssuer.Status.Strategies {
|
||||
// Skip unhealthy strategies.
|
||||
@@ -540,26 +668,15 @@ func getConciergeFrontend(credentialIssuer *conciergeconfigv1alpha1.CredentialIs
|
||||
continue
|
||||
}
|
||||
|
||||
// Backfill the .status.strategies[].frontend field from .status.kubeConfigInfo for backwards compatibility.
|
||||
if strategy.Type == conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType && strategy.Frontend == nil && credentialIssuer.Status.KubeConfigInfo != nil {
|
||||
strategy = *strategy.DeepCopy()
|
||||
strategy.Frontend = &conciergeconfigv1alpha1.CredentialIssuerFrontend{
|
||||
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
|
||||
Server: credentialIssuer.Status.KubeConfigInfo.Server,
|
||||
CertificateAuthorityData: credentialIssuer.Status.KubeConfigInfo.CertificateAuthorityData,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// If the strategy frontend is still nil, skip.
|
||||
// If the strategy frontend is nil, skip.
|
||||
if strategy.Frontend == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip any unknown frontend types.
|
||||
switch strategy.Frontend.Type {
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType, conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -15,10 +15,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
kubetesting "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
aggregatorfake "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
@@ -64,14 +70,69 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
jwtAuthenticator := func(issuerCABundle string, issuerURL string) runtime.Object {
|
||||
caBundleInSecret := func(issuerCABundle, secretName, secretNamespace, secretDataKey string) runtime.Object {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: secretNamespace,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
secretDataKey: []byte(issuerCABundle),
|
||||
"other": []byte("unrelated"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
caBundleInConfigmap := func(issuerCABundle, cmName, cmNamespace, cmDataKey string) runtime.Object {
|
||||
return &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cmName,
|
||||
Namespace: cmNamespace,
|
||||
},
|
||||
Data: map[string]string{
|
||||
cmDataKey: issuerCABundle,
|
||||
"other": "unrelated",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
jwtAuthenticator := func(issuerCABundle, issuerURL string) *authenticationv1alpha1.JWTAuthenticator {
|
||||
encodedCABundle := ""
|
||||
if issuerCABundle != "" {
|
||||
encodedCABundle = base64.StdEncoding.EncodeToString([]byte(issuerCABundle))
|
||||
}
|
||||
return &authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"},
|
||||
Spec: authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: issuerURL,
|
||||
Audience: "test-audience",
|
||||
TLS: &authenticationv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(issuerCABundle)),
|
||||
CertificateAuthorityData: encodedCABundle,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
jwtAuthenticatorWithCABundleDataSource := func(sourceKind, sourceName, sourceKey, issuerURL string) runtime.Object {
|
||||
authenticator := jwtAuthenticator("", issuerURL)
|
||||
authenticator.Spec.TLS.CertificateAuthorityDataSource = &authenticationv1alpha1.CertificateAuthorityDataSourceSpec{
|
||||
Kind: authenticationv1alpha1.CertificateAuthorityDataSourceKind(sourceKind),
|
||||
Name: sourceName,
|
||||
Key: sourceKey,
|
||||
}
|
||||
return authenticator
|
||||
}
|
||||
|
||||
apiService := func(group, version, serviceNamespace string) *v1.APIService {
|
||||
return &v1.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: version + "." + group,
|
||||
},
|
||||
Spec: v1.APIServiceSpec{
|
||||
Group: group,
|
||||
Version: version,
|
||||
Service: &v1.ServiceReference{
|
||||
Namespace: serviceNamespace,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -144,7 +205,11 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
getPathToSelfErr error
|
||||
getClientsetErr error
|
||||
conciergeObjects func(string, string) []runtime.Object
|
||||
kubeObjects func(string) []runtime.Object
|
||||
apiServiceObjects []runtime.Object
|
||||
conciergeReactions []kubetesting.Reactor
|
||||
kubeReactions []kubetesting.Reactor
|
||||
apiServiceReactions []kubetesting.Reactor
|
||||
oidcDiscoveryResponse func(string) string
|
||||
oidcDiscoveryStatusCode int
|
||||
idpsDiscoveryResponse string
|
||||
@@ -613,18 +678,18 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
&conciergeconfigv1alpha1.CredentialIssuer{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
|
||||
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
|
||||
KubeConfigInfo: &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
|
||||
Server: "https://concierge-endpoint",
|
||||
CertificateAuthorityData: "ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==",
|
||||
},
|
||||
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{{
|
||||
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
|
||||
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
|
||||
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
|
||||
Message: "Successfully fetched key",
|
||||
LastUpdateTime: metav1.Now(),
|
||||
// Simulate a previous version of CredentialIssuer that's missing this Frontend field.
|
||||
Frontend: nil,
|
||||
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
|
||||
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
|
||||
Server: "https://concierge-endpoint.example.com",
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
@@ -656,6 +721,321 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator test-authenticator has invalid spec.tls.certificateAuthorityData: illegal base64 data at input byte 7` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but Secret not found",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error getting Secret test-concierge-namespace/my-ca-secret specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource: secrets "my-ca-secret" not found` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in ConfigMap, but ConfigMap not found",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("ConfigMap", "my-ca-configmap", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error getting ConfigMap test-concierge-namespace/my-ca-configmap specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource: configmaps "my-ca-configmap" not found` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but invalid TLS bundle found in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret("invalid CA bundle data", "my-ca-secret", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but value at key "ca.crt" specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.key does not contain any CA certificates in Secret test-concierge-namespace/my-ca-secret` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but specified key not found in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret(issuerCABundle, "my-ca-secret", "test-concierge-namespace", "wrong_key_name"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but key "ca.crt" specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.key does not exist in Secret test-concierge-namespace/my-ca-secret` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but specified key has empty value in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret("", "my-ca-secret", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but key "ca.crt" specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.key exists but has empty value in Secret test-concierge-namespace/my-ca-secret` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle source, but source's Kind is not supported",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Unsupported-Value", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.Kind value "Unsupported-Value" is not supported by this CLI version` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but no related APIService found",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("unrelated.example.com", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator test-authenticator: could not find APIService with non-empty spec.service.namespace for API group login.concierge.pinniped.dev` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but related APIService has empty namespace in spec",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", ""),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator test-authenticator: could not find APIService with non-empty spec.service.namespace for API group login.concierge.pinniped.dev` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but error when listing APIServices",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceReactions: []kubetesting.Reactor{
|
||||
&kubetesting.SimpleReactor{
|
||||
Verb: "*",
|
||||
Resource: "apiservices",
|
||||
Reaction: func(kubetesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, fmt.Errorf("some list error")
|
||||
},
|
||||
},
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator test-authenticator: error listing APIServices: some list error` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator, invalid substring in audience",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
@@ -1600,6 +1980,257 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
"--skip-validation",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret(issuerCABundle, "my-ca-secret", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
apiService("unrelated.pinniped.dev", "v1alpha1", "unrelated-namespace"),
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha2", "test-concierge-namespace"),
|
||||
},
|
||||
oidcDiscoveryResponse: onlyIssuerOIDCDiscoveryResponse,
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource {"roots": 1}`,
|
||||
}
|
||||
},
|
||||
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
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=pinniped.dev
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=jwt
|
||||
- --concierge-endpoint=https://fake-server-url-value
|
||||
- --concierge-ca-bundle-data=ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
- --issuer=%s
|
||||
- --client-id=pinniped-cli
|
||||
- --scopes=offline_access,openid,pinniped:request-audience,username,groups
|
||||
- --ca-bundle-data=%s
|
||||
- --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,
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in ConfigMap",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
"--skip-validation",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("ConfigMap", "my-ca-configmap", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInConfigmap(issuerCABundle, "my-ca-configmap", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
apiService("unrelated.pinniped.dev", "v1alpha1", "unrelated-namespace"),
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha2", "test-concierge-namespace"),
|
||||
},
|
||||
oidcDiscoveryResponse: onlyIssuerOIDCDiscoveryResponse,
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource {"roots": 1}`,
|
||||
}
|
||||
},
|
||||
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
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=pinniped.dev
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=jwt
|
||||
- --concierge-endpoint=https://fake-server-url-value
|
||||
- --concierge-ca-bundle-data=ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
- --issuer=%s
|
||||
- --client-id=pinniped-cli
|
||||
- --scopes=offline_access,openid,pinniped:request-audience,username,groups
|
||||
- --ca-bundle-data=%s
|
||||
- --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,
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in ConfigMap with a custom API group suffix",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
"--concierge-api-group-suffix=acme.com",
|
||||
"--skip-validation",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("ConfigMap", "my-ca-configmap", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInConfigmap(issuerCABundle, "my-ca-configmap", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.acme.com", "v1alpha1", "test-concierge-namespace"),
|
||||
apiService("unrelated.pinniped.dev", "v1alpha1", "unrelated-namespace"),
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha2", "another-unrelated-namespace"),
|
||||
},
|
||||
oidcDiscoveryResponse: onlyIssuerOIDCDiscoveryResponse,
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "acme.com"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource {"roots": 1}`,
|
||||
}
|
||||
},
|
||||
wantAPIGroupSuffix: "acme.com",
|
||||
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
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=acme.com
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=jwt
|
||||
- --concierge-endpoint=https://fake-server-url-value
|
||||
- --concierge-ca-bundle-data=ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
- --issuer=%s
|
||||
- --client-id=pinniped-cli
|
||||
- --scopes=offline_access,openid,pinniped:request-audience,username,groups
|
||||
- --ca-bundle-data=%s
|
||||
- --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,
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect nothing, set a bunch of options",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
@@ -3211,6 +3842,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var issuerEndpointPtr *string
|
||||
@@ -3245,6 +3877,37 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
}), nil)
|
||||
issuerEndpointPtr = ptr.To(testServer.URL)
|
||||
|
||||
getClientsetFunc := func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error) {
|
||||
if tt.wantAPIGroupSuffix == "" {
|
||||
require.Equal(t, "pinniped.dev", apiGroupSuffix) // "pinniped.dev" = api group suffix default
|
||||
} else {
|
||||
require.Equal(t, tt.wantAPIGroupSuffix, apiGroupSuffix)
|
||||
}
|
||||
if tt.getClientsetErr != nil {
|
||||
return nil, nil, nil, tt.getClientsetErr
|
||||
}
|
||||
fakeAggregatorClient := aggregatorfake.NewSimpleClientset(tt.apiServiceObjects...)
|
||||
fakeKubeClient := fake.NewClientset()
|
||||
if tt.kubeObjects != nil {
|
||||
kubeObjects := tt.kubeObjects(string(testServerCA))
|
||||
fakeKubeClient = fake.NewClientset(kubeObjects...)
|
||||
}
|
||||
fakeConciergeClient := conciergefake.NewSimpleClientset()
|
||||
if tt.conciergeObjects != nil {
|
||||
fakeConciergeClient = conciergefake.NewSimpleClientset(tt.conciergeObjects(string(testServerCA), testServer.URL)...)
|
||||
}
|
||||
if len(tt.conciergeReactions) > 0 {
|
||||
fakeConciergeClient.ReactionChain = slices.Concat(tt.conciergeReactions, fakeConciergeClient.ReactionChain)
|
||||
}
|
||||
if len(tt.kubeReactions) > 0 {
|
||||
fakeKubeClient.ReactionChain = slices.Concat(tt.kubeReactions, fakeKubeClient.ReactionChain)
|
||||
}
|
||||
if len(tt.apiServiceReactions) > 0 {
|
||||
fakeAggregatorClient.ReactionChain = slices.Concat(tt.apiServiceReactions, fakeAggregatorClient.ReactionChain)
|
||||
}
|
||||
return fakeConciergeClient, fakeKubeClient, fakeAggregatorClient, nil
|
||||
}
|
||||
|
||||
var log bytes.Buffer
|
||||
|
||||
cmd := kubeconfigCommand(kubeconfigDeps{
|
||||
@@ -3257,25 +3920,8 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
}
|
||||
return ".../path/to/pinniped", nil
|
||||
},
|
||||
getClientset: func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error) {
|
||||
if tt.wantAPIGroupSuffix == "" {
|
||||
require.Equal(t, "pinniped.dev", apiGroupSuffix) // "pinniped.dev" = api group suffix default
|
||||
} else {
|
||||
require.Equal(t, tt.wantAPIGroupSuffix, apiGroupSuffix)
|
||||
}
|
||||
if tt.getClientsetErr != nil {
|
||||
return nil, tt.getClientsetErr
|
||||
}
|
||||
fake := conciergefake.NewSimpleClientset()
|
||||
if tt.conciergeObjects != nil {
|
||||
fake = conciergefake.NewSimpleClientset(tt.conciergeObjects(string(testServerCA), testServer.URL)...)
|
||||
}
|
||||
if len(tt.conciergeReactions) > 0 {
|
||||
fake.ReactionChain = slices.Concat(tt.conciergeReactions, fake.ReactionChain)
|
||||
}
|
||||
return fake, nil
|
||||
},
|
||||
log: plog.TestConsoleLogger(t, &log),
|
||||
getClientsets: getClientsetFunc,
|
||||
log: plog.TestConsoleLogger(t, &log),
|
||||
})
|
||||
require.NotNil(t, cmd)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -25,14 +25,14 @@ import (
|
||||
)
|
||||
|
||||
type whoamiDeps struct {
|
||||
getenv func(key string) string
|
||||
getClientset getConciergeClientsetFunc
|
||||
getenv func(key string) string
|
||||
getClientsets getClientsetsFunc
|
||||
}
|
||||
|
||||
func whoamiRealDeps() whoamiDeps {
|
||||
return whoamiDeps{
|
||||
getenv: os.Getenv,
|
||||
getClientset: getRealConciergeClientset,
|
||||
getenv: os.Getenv,
|
||||
getClientsets: getRealClientsets,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func newWhoamiCommand(deps whoamiDeps) *cobra.Command {
|
||||
|
||||
func runWhoami(output io.Writer, deps whoamiDeps, flags *whoamiFlags) error {
|
||||
clientConfig := newClientConfig(flags.kubeconfigPath, flags.kubeconfigContextOverride)
|
||||
clientset, err := deps.getClientset(clientConfig, flags.apiGroupSuffix)
|
||||
conciergeClient, _, _, err := deps.getClientsets(clientConfig, flags.apiGroupSuffix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not configure Kubernetes client: %w", err)
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func runWhoami(output io.Writer, deps whoamiDeps, flags *whoamiFlags) error {
|
||||
defer cancelFunc()
|
||||
}
|
||||
|
||||
whoAmI, err := clientset.IdentityV1alpha1().WhoAmIRequests().Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
|
||||
whoAmI, err := conciergeClient.IdentityV1alpha1().WhoAmIRequests().Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
hint := ""
|
||||
if apierrors.IsNotFound(err) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2023-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -11,8 +11,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
kubetesting "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
|
||||
identityv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/identity/v1alpha1"
|
||||
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||
@@ -290,14 +292,15 @@ func TestWhoami(t *testing.T) {
|
||||
wantStderr: "Error: could not complete WhoAmIRequest (is the Pinniped WhoAmI API running and healthy?): whoamirequests.identity.concierge.pinniped.dev \"whatever\" not found\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
getClientset := func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error) {
|
||||
getClientsetFunc := func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error) {
|
||||
if test.gettingClientsetErr != nil {
|
||||
return nil, test.gettingClientsetErr
|
||||
return nil, nil, nil, test.gettingClientsetErr
|
||||
}
|
||||
clientset := conciergefake.NewSimpleClientset()
|
||||
clientset.PrependReactor("create", "whoamirequests", func(_ kubetesting.Action) (bool, runtime.Object, error) {
|
||||
conciergeClient := conciergefake.NewSimpleClientset()
|
||||
conciergeClient.PrependReactor("create", "whoamirequests", func(_ kubetesting.Action) (bool, runtime.Object, error) {
|
||||
if test.callingAPIErr != nil {
|
||||
return true, nil, test.callingAPIErr
|
||||
}
|
||||
@@ -316,13 +319,14 @@ func TestWhoami(t *testing.T) {
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
return clientset, nil
|
||||
return conciergeClient, nil, nil, nil
|
||||
}
|
||||
|
||||
cmd := newWhoamiCommand(whoamiDeps{
|
||||
getenv: func(key string) string {
|
||||
return test.env[key]
|
||||
},
|
||||
getClientset: getClientset,
|
||||
getClientsets: getClientsetFunc,
|
||||
})
|
||||
|
||||
stdout, stderr := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -134,24 +134,6 @@ spec:
|
||||
status:
|
||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
||||
properties:
|
||||
kubeConfigInfo:
|
||||
description: |-
|
||||
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
This field is deprecated and will be removed in a future version.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: The K8s API server CA bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
server:
|
||||
description: The K8s API server URL.
|
||||
minLength: 1
|
||||
pattern: ^https://|^http://
|
||||
type: string
|
||||
required:
|
||||
- certificateAuthorityData
|
||||
- server
|
||||
type: object
|
||||
strategies:
|
||||
description: List of integration strategies that were attempted by
|
||||
Pinniped.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -68,6 +68,7 @@ data:
|
||||
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
|
||||
aggregatedAPIServerDisableAdmissionPlugins: []
|
||||
names:
|
||||
servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @)
|
||||
credentialIssuer: (@= defaultResourceNameWithSuffix("config") @)
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -289,6 +289,9 @@ spec:
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: issuer must be an HTTPS URL
|
||||
rule: isURL(self) && url(self).getScheme() == 'https'
|
||||
tls:
|
||||
description: TLS specifies a secret which will contain Transport Layer
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -61,7 +61,8 @@ _: #@ template.replace(data.values.custom_labels)
|
||||
#@ "audit": {
|
||||
#@ "logUsernamesAndGroups": data.values.audit.log_usernames_and_groups,
|
||||
#@ "logInternalPaths": data.values.audit.log_internal_paths
|
||||
#@ }
|
||||
#@ },
|
||||
#@ "aggregatedAPIServerDisableAdmissionPlugins": []
|
||||
#@ }
|
||||
#@ if data.values.log_level:
|
||||
#@ config["log"] = {}
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
62
generated/1.25/README.adoc
generated
62
generated/1.25/README.adoc
generated
@@ -65,7 +65,6 @@ certificate bundle. +
|
||||
|
||||
JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
|
||||
|
||||
Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid
|
||||
signature, existence of claims, etc.) and extract the username and groups from the token.
|
||||
|
||||
@@ -429,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-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:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`server`* __string__ | The K8s API server URL. +
|
||||
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerspec"]
|
||||
@@ -481,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
|
||||
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
|
||||
This field is deprecated and will be removed in a future version. +
|
||||
|===
|
||||
|
||||
|
||||
@@ -566,7 +544,6 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
||||
| Field | Description
|
||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-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. +
|
||||
@@ -609,11 +586,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
||||
| *`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.type is "None". +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
||||
|
||||
|
||||
If this field is empty, the impersonation proxy will generate its own TLS certificate. +
|
||||
|===
|
||||
|
||||
@@ -624,11 +599,9 @@ If this field is empty, the impersonation proxy will generate its own TLS certif
|
||||
ImpersonationProxyTLSSpec contains information about how the Concierge impersonation proxy should
|
||||
serve TLS.
|
||||
|
||||
|
||||
If CertificateAuthorityData is not provided, the Concierge impersonation proxy will check the secret
|
||||
for a field called "ca.crt", which will be used as the CertificateAuthorityData.
|
||||
|
||||
|
||||
If neither CertificateAuthorityData nor ca.crt is provided, no CA bundle will be advertised for
|
||||
the impersonation proxy endpoint.
|
||||
|
||||
@@ -812,13 +785,11 @@ the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer i
|
||||
https://example.com/foo, then your authorization endpoint will look like +
|
||||
https://example.com/foo/some/path/to/auth/endpoint). +
|
||||
|
||||
|
||||
See +
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information. +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain. +
|
||||
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
||||
|
||||
|
||||
An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server, +
|
||||
how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to +
|
||||
extract a normalized user identity. Normalized user identities include a username and a list of group names. +
|
||||
@@ -831,7 +802,6 @@ rejection policies. Even though a user was able to authenticate with the identit
|
||||
the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could +
|
||||
disallow the authentication unless the user belongs to a specific group in the identity provider. +
|
||||
|
||||
|
||||
For backwards compatibility with versions of Pinniped which predate support for multiple identity providers, +
|
||||
an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which +
|
||||
exist in the same namespace, but also to reject all authentication requests when there is more than one identity +
|
||||
@@ -880,21 +850,17 @@ the TLS serving certificate for the HTTPS endpoints served by this FederationDom
|
||||
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 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. +
|
||||
|===
|
||||
|
||||
@@ -919,14 +885,12 @@ Each is a CEL expression. It may use the basic CEL language as defined in +
|
||||
https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in +
|
||||
https://github.com/google/cel-go/tree/master/ext#strings. +
|
||||
|
||||
|
||||
The username and groups extracted from the identity provider, and the constants defined in this CR, are +
|
||||
available as variables in all expressions. The username is provided via a variable called `username` and +
|
||||
the list of group names is provided via a variable called `groups` (which may be an empty list). +
|
||||
Each user-provided constants is provided via a variable named `strConst.varName` for string constants +
|
||||
and `strListConst.varName` for string list constants. +
|
||||
|
||||
|
||||
The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1. +
|
||||
Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated +
|
||||
and the authentication attempt is rejected. +
|
||||
@@ -939,7 +903,6 @@ groups list. +
|
||||
Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames. +
|
||||
After each expression, the new (potentially changed) username or groups get passed to the following expression. +
|
||||
|
||||
|
||||
Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain. +
|
||||
During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the +
|
||||
authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username +
|
||||
@@ -1109,7 +1072,6 @@ Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking
|
||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-granttype[$$GrantType$$] array__ | allowedGrantTypes is a list of the allowed grant_type param values that should be accepted during OIDC flows with this +
|
||||
client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- authorization_code: allows the client to perform the authorization code grant flow, i.e. allows the webapp to +
|
||||
authenticate users. This grant must always be listed. +
|
||||
@@ -1120,7 +1082,6 @@ which is a step in the process to be able to get a cluster credential for the us
|
||||
This grant must be listed if allowedScopes lists pinniped:request-audience. +
|
||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-scope[$$Scope$$] array__ | allowedScopes is a list of the allowed scopes param values that should be accepted during OIDC flows with this client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- openid: The client is allowed to request ID tokens. ID tokens only include the required claims by default (iss, sub, aud, exp, iat). +
|
||||
This scope must always be listed. +
|
||||
@@ -1532,21 +1493,18 @@ 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 +
|
||||
@@ -1797,10 +1755,8 @@ GitHubClaims allows customization of the username and groups claims.
|
||||
| Field | Description
|
||||
| *`username`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-idp-v1alpha1-githubusernameattribute[$$GitHubUsernameAttribute$$]__ | Username configures which property of the GitHub user record shall determine the username in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "id", "login", or "login:id". Defaults to "login:id". +
|
||||
|
||||
|
||||
GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens, +
|
||||
and may not start or end with hyphens. GitHub users are allowed to change their login name, +
|
||||
although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar", +
|
||||
@@ -1808,41 +1764,32 @@ then a second user might change their name from "baz" to "foo" in order to take
|
||||
username of the first user. For this reason, it is not as safe to make authorization decisions +
|
||||
based only on the user's login attribute. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these usernames are presented to Kubernetes. +
|
||||
|
||||
|
||||
Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and +
|
||||
unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value +
|
||||
from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable +
|
||||
choice to concatenate the two values. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user). +
|
||||
| *`groups`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-idp-v1alpha1-githubgroupnameattribute[$$GitHubGroupNameAttribute$$]__ | Groups configures which property of the GitHub team record shall determine the group names in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "name" or "slug". Defaults to "slug". +
|
||||
|
||||
|
||||
GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!"). +
|
||||
|
||||
|
||||
GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins"). +
|
||||
|
||||
|
||||
Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a +
|
||||
forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters +
|
||||
or single hyphens, so the first forward slash `/` will be the separator between the organization login name and +
|
||||
the team name or slug. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these group names are presented to Kubernetes. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user). +
|
||||
|===
|
||||
@@ -1865,7 +1812,6 @@ for web-based login flows.
|
||||
| *`secretName`* __string__ | SecretName contains the name of a namespace-local Secret object that provides the clientID and +
|
||||
clientSecret for an GitHub App or GitHub OAuth2 client. +
|
||||
|
||||
|
||||
This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret". +
|
||||
|===
|
||||
|
||||
@@ -1890,7 +1836,6 @@ names to present to Kubernetes. See the response schema for
|
||||
GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
|
||||
|
||||
Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
as OIDCClients.
|
||||
|
||||
@@ -1977,10 +1922,8 @@ GitHubIdentityProviderStatus is the status of an GitHub identity provider.
|
||||
| *`policy`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-idp-v1alpha1-githuballowedauthorganizationspolicy[$$GitHubAllowedAuthOrganizationsPolicy$$]__ | Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers". +
|
||||
Defaults to "OnlyUsersFromAllowedOrganizations". +
|
||||
|
||||
|
||||
Must be set to "AllGitHubUsers" if the allowed field is empty. +
|
||||
|
||||
|
||||
This field only exists to ensure that Pinniped administrators are aware that an empty list of +
|
||||
allowedOrganizations means all GitHub users are allowed to log in. +
|
||||
| *`allowed`* __string array__ | Allowed, when specified, indicates that only users with membership in at least one of the listed +
|
||||
@@ -1988,12 +1931,10 @@ GitHub organizations may log in. In addition, the group membership presented to
|
||||
teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be +
|
||||
provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP. +
|
||||
|
||||
|
||||
The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations, +
|
||||
otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams +
|
||||
within that organization. +
|
||||
|
||||
|
||||
If no organizations are listed, you must set organizations: AllGitHubUsers. +
|
||||
|===
|
||||
|
||||
@@ -2095,21 +2036,18 @@ 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 +
|
||||
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialIssuerKubeConfigInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
|
||||
*out = *in
|
||||
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.KubeConfigInfo != nil {
|
||||
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
|
||||
*out = new(CredentialIssuerKubeConfigInfo)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -134,24 +134,6 @@ spec:
|
||||
status:
|
||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
||||
properties:
|
||||
kubeConfigInfo:
|
||||
description: |-
|
||||
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
This field is deprecated and will be removed in a future version.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: The K8s API server CA bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
server:
|
||||
description: The K8s API server URL.
|
||||
minLength: 1
|
||||
pattern: ^https://|^http://
|
||||
type: string
|
||||
required:
|
||||
- certificateAuthorityData
|
||||
- server
|
||||
type: object
|
||||
strategies:
|
||||
description: List of integration strategies that were attempted by
|
||||
Pinniped.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -289,6 +289,9 @@ spec:
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: issuer must be an HTTPS URL
|
||||
rule: isURL(self) && url(self).getScheme() == 'https'
|
||||
tls:
|
||||
description: TLS specifies a secret which will contain Transport Layer
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
62
generated/1.26/README.adoc
generated
62
generated/1.26/README.adoc
generated
@@ -65,7 +65,6 @@ certificate bundle. +
|
||||
|
||||
JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
|
||||
|
||||
Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid
|
||||
signature, existence of claims, etc.) and extract the username and groups from the token.
|
||||
|
||||
@@ -429,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-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:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`server`* __string__ | The K8s API server URL. +
|
||||
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerspec"]
|
||||
@@ -481,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
|
||||
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
|
||||
This field is deprecated and will be removed in a future version. +
|
||||
|===
|
||||
|
||||
|
||||
@@ -566,7 +544,6 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
||||
| Field | Description
|
||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-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. +
|
||||
@@ -609,11 +586,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
||||
| *`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.type is "None". +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
||||
|
||||
|
||||
If this field is empty, the impersonation proxy will generate its own TLS certificate. +
|
||||
|===
|
||||
|
||||
@@ -624,11 +599,9 @@ If this field is empty, the impersonation proxy will generate its own TLS certif
|
||||
ImpersonationProxyTLSSpec contains information about how the Concierge impersonation proxy should
|
||||
serve TLS.
|
||||
|
||||
|
||||
If CertificateAuthorityData is not provided, the Concierge impersonation proxy will check the secret
|
||||
for a field called "ca.crt", which will be used as the CertificateAuthorityData.
|
||||
|
||||
|
||||
If neither CertificateAuthorityData nor ca.crt is provided, no CA bundle will be advertised for
|
||||
the impersonation proxy endpoint.
|
||||
|
||||
@@ -812,13 +785,11 @@ the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer i
|
||||
https://example.com/foo, then your authorization endpoint will look like +
|
||||
https://example.com/foo/some/path/to/auth/endpoint). +
|
||||
|
||||
|
||||
See +
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information. +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain. +
|
||||
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
||||
|
||||
|
||||
An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server, +
|
||||
how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to +
|
||||
extract a normalized user identity. Normalized user identities include a username and a list of group names. +
|
||||
@@ -831,7 +802,6 @@ rejection policies. Even though a user was able to authenticate with the identit
|
||||
the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could +
|
||||
disallow the authentication unless the user belongs to a specific group in the identity provider. +
|
||||
|
||||
|
||||
For backwards compatibility with versions of Pinniped which predate support for multiple identity providers, +
|
||||
an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which +
|
||||
exist in the same namespace, but also to reject all authentication requests when there is more than one identity +
|
||||
@@ -880,21 +850,17 @@ the TLS serving certificate for the HTTPS endpoints served by this FederationDom
|
||||
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 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. +
|
||||
|===
|
||||
|
||||
@@ -919,14 +885,12 @@ Each is a CEL expression. It may use the basic CEL language as defined in +
|
||||
https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in +
|
||||
https://github.com/google/cel-go/tree/master/ext#strings. +
|
||||
|
||||
|
||||
The username and groups extracted from the identity provider, and the constants defined in this CR, are +
|
||||
available as variables in all expressions. The username is provided via a variable called `username` and +
|
||||
the list of group names is provided via a variable called `groups` (which may be an empty list). +
|
||||
Each user-provided constants is provided via a variable named `strConst.varName` for string constants +
|
||||
and `strListConst.varName` for string list constants. +
|
||||
|
||||
|
||||
The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1. +
|
||||
Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated +
|
||||
and the authentication attempt is rejected. +
|
||||
@@ -939,7 +903,6 @@ groups list. +
|
||||
Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames. +
|
||||
After each expression, the new (potentially changed) username or groups get passed to the following expression. +
|
||||
|
||||
|
||||
Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain. +
|
||||
During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the +
|
||||
authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username +
|
||||
@@ -1109,7 +1072,6 @@ Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking
|
||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-granttype[$$GrantType$$] array__ | allowedGrantTypes is a list of the allowed grant_type param values that should be accepted during OIDC flows with this +
|
||||
client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- authorization_code: allows the client to perform the authorization code grant flow, i.e. allows the webapp to +
|
||||
authenticate users. This grant must always be listed. +
|
||||
@@ -1120,7 +1082,6 @@ which is a step in the process to be able to get a cluster credential for the us
|
||||
This grant must be listed if allowedScopes lists pinniped:request-audience. +
|
||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-scope[$$Scope$$] array__ | allowedScopes is a list of the allowed scopes param values that should be accepted during OIDC flows with this client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- openid: The client is allowed to request ID tokens. ID tokens only include the required claims by default (iss, sub, aud, exp, iat). +
|
||||
This scope must always be listed. +
|
||||
@@ -1532,21 +1493,18 @@ 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 +
|
||||
@@ -1797,10 +1755,8 @@ GitHubClaims allows customization of the username and groups claims.
|
||||
| Field | Description
|
||||
| *`username`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-idp-v1alpha1-githubusernameattribute[$$GitHubUsernameAttribute$$]__ | Username configures which property of the GitHub user record shall determine the username in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "id", "login", or "login:id". Defaults to "login:id". +
|
||||
|
||||
|
||||
GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens, +
|
||||
and may not start or end with hyphens. GitHub users are allowed to change their login name, +
|
||||
although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar", +
|
||||
@@ -1808,41 +1764,32 @@ then a second user might change their name from "baz" to "foo" in order to take
|
||||
username of the first user. For this reason, it is not as safe to make authorization decisions +
|
||||
based only on the user's login attribute. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these usernames are presented to Kubernetes. +
|
||||
|
||||
|
||||
Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and +
|
||||
unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value +
|
||||
from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable +
|
||||
choice to concatenate the two values. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user). +
|
||||
| *`groups`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-idp-v1alpha1-githubgroupnameattribute[$$GitHubGroupNameAttribute$$]__ | Groups configures which property of the GitHub team record shall determine the group names in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "name" or "slug". Defaults to "slug". +
|
||||
|
||||
|
||||
GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!"). +
|
||||
|
||||
|
||||
GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins"). +
|
||||
|
||||
|
||||
Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a +
|
||||
forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters +
|
||||
or single hyphens, so the first forward slash `/` will be the separator between the organization login name and +
|
||||
the team name or slug. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these group names are presented to Kubernetes. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user). +
|
||||
|===
|
||||
@@ -1865,7 +1812,6 @@ for web-based login flows.
|
||||
| *`secretName`* __string__ | SecretName contains the name of a namespace-local Secret object that provides the clientID and +
|
||||
clientSecret for an GitHub App or GitHub OAuth2 client. +
|
||||
|
||||
|
||||
This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret". +
|
||||
|===
|
||||
|
||||
@@ -1890,7 +1836,6 @@ names to present to Kubernetes. See the response schema for
|
||||
GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
|
||||
|
||||
Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
as OIDCClients.
|
||||
|
||||
@@ -1977,10 +1922,8 @@ GitHubIdentityProviderStatus is the status of an GitHub identity provider.
|
||||
| *`policy`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-idp-v1alpha1-githuballowedauthorganizationspolicy[$$GitHubAllowedAuthOrganizationsPolicy$$]__ | Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers". +
|
||||
Defaults to "OnlyUsersFromAllowedOrganizations". +
|
||||
|
||||
|
||||
Must be set to "AllGitHubUsers" if the allowed field is empty. +
|
||||
|
||||
|
||||
This field only exists to ensure that Pinniped administrators are aware that an empty list of +
|
||||
allowedOrganizations means all GitHub users are allowed to log in. +
|
||||
| *`allowed`* __string array__ | Allowed, when specified, indicates that only users with membership in at least one of the listed +
|
||||
@@ -1988,12 +1931,10 @@ GitHub organizations may log in. In addition, the group membership presented to
|
||||
teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be +
|
||||
provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP. +
|
||||
|
||||
|
||||
The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations, +
|
||||
otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams +
|
||||
within that organization. +
|
||||
|
||||
|
||||
If no organizations are listed, you must set organizations: AllGitHubUsers. +
|
||||
|===
|
||||
|
||||
@@ -2095,21 +2036,18 @@ 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 +
|
||||
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialIssuerKubeConfigInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
|
||||
*out = *in
|
||||
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.KubeConfigInfo != nil {
|
||||
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
|
||||
*out = new(CredentialIssuerKubeConfigInfo)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -134,24 +134,6 @@ spec:
|
||||
status:
|
||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
||||
properties:
|
||||
kubeConfigInfo:
|
||||
description: |-
|
||||
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
This field is deprecated and will be removed in a future version.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: The K8s API server CA bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
server:
|
||||
description: The K8s API server URL.
|
||||
minLength: 1
|
||||
pattern: ^https://|^http://
|
||||
type: string
|
||||
required:
|
||||
- certificateAuthorityData
|
||||
- server
|
||||
type: object
|
||||
strategies:
|
||||
description: List of integration strategies that were attempted by
|
||||
Pinniped.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -289,6 +289,9 @@ spec:
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: issuer must be an HTTPS URL
|
||||
rule: isURL(self) && url(self).getScheme() == 'https'
|
||||
tls:
|
||||
description: TLS specifies a secret which will contain Transport Layer
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
62
generated/1.27/README.adoc
generated
62
generated/1.27/README.adoc
generated
@@ -65,7 +65,6 @@ certificate bundle. +
|
||||
|
||||
JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
|
||||
|
||||
Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid
|
||||
signature, existence of claims, etc.) and extract the username and groups from the token.
|
||||
|
||||
@@ -429,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-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:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`server`* __string__ | The K8s API server URL. +
|
||||
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerspec"]
|
||||
@@ -481,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
|
||||
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
|
||||
This field is deprecated and will be removed in a future version. +
|
||||
|===
|
||||
|
||||
|
||||
@@ -566,7 +544,6 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
||||
| Field | Description
|
||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-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. +
|
||||
@@ -609,11 +586,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
||||
| *`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.type is "None". +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
||||
|
||||
|
||||
If this field is empty, the impersonation proxy will generate its own TLS certificate. +
|
||||
|===
|
||||
|
||||
@@ -624,11 +599,9 @@ If this field is empty, the impersonation proxy will generate its own TLS certif
|
||||
ImpersonationProxyTLSSpec contains information about how the Concierge impersonation proxy should
|
||||
serve TLS.
|
||||
|
||||
|
||||
If CertificateAuthorityData is not provided, the Concierge impersonation proxy will check the secret
|
||||
for a field called "ca.crt", which will be used as the CertificateAuthorityData.
|
||||
|
||||
|
||||
If neither CertificateAuthorityData nor ca.crt is provided, no CA bundle will be advertised for
|
||||
the impersonation proxy endpoint.
|
||||
|
||||
@@ -812,13 +785,11 @@ the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer i
|
||||
https://example.com/foo, then your authorization endpoint will look like +
|
||||
https://example.com/foo/some/path/to/auth/endpoint). +
|
||||
|
||||
|
||||
See +
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information. +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain. +
|
||||
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
||||
|
||||
|
||||
An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server, +
|
||||
how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to +
|
||||
extract a normalized user identity. Normalized user identities include a username and a list of group names. +
|
||||
@@ -831,7 +802,6 @@ rejection policies. Even though a user was able to authenticate with the identit
|
||||
the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could +
|
||||
disallow the authentication unless the user belongs to a specific group in the identity provider. +
|
||||
|
||||
|
||||
For backwards compatibility with versions of Pinniped which predate support for multiple identity providers, +
|
||||
an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which +
|
||||
exist in the same namespace, but also to reject all authentication requests when there is more than one identity +
|
||||
@@ -880,21 +850,17 @@ the TLS serving certificate for the HTTPS endpoints served by this FederationDom
|
||||
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 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. +
|
||||
|===
|
||||
|
||||
@@ -919,14 +885,12 @@ Each is a CEL expression. It may use the basic CEL language as defined in +
|
||||
https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in +
|
||||
https://github.com/google/cel-go/tree/master/ext#strings. +
|
||||
|
||||
|
||||
The username and groups extracted from the identity provider, and the constants defined in this CR, are +
|
||||
available as variables in all expressions. The username is provided via a variable called `username` and +
|
||||
the list of group names is provided via a variable called `groups` (which may be an empty list). +
|
||||
Each user-provided constants is provided via a variable named `strConst.varName` for string constants +
|
||||
and `strListConst.varName` for string list constants. +
|
||||
|
||||
|
||||
The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1. +
|
||||
Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated +
|
||||
and the authentication attempt is rejected. +
|
||||
@@ -939,7 +903,6 @@ groups list. +
|
||||
Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames. +
|
||||
After each expression, the new (potentially changed) username or groups get passed to the following expression. +
|
||||
|
||||
|
||||
Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain. +
|
||||
During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the +
|
||||
authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username +
|
||||
@@ -1109,7 +1072,6 @@ Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking
|
||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-granttype[$$GrantType$$] array__ | allowedGrantTypes is a list of the allowed grant_type param values that should be accepted during OIDC flows with this +
|
||||
client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- authorization_code: allows the client to perform the authorization code grant flow, i.e. allows the webapp to +
|
||||
authenticate users. This grant must always be listed. +
|
||||
@@ -1120,7 +1082,6 @@ which is a step in the process to be able to get a cluster credential for the us
|
||||
This grant must be listed if allowedScopes lists pinniped:request-audience. +
|
||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-scope[$$Scope$$] array__ | allowedScopes is a list of the allowed scopes param values that should be accepted during OIDC flows with this client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- openid: The client is allowed to request ID tokens. ID tokens only include the required claims by default (iss, sub, aud, exp, iat). +
|
||||
This scope must always be listed. +
|
||||
@@ -1532,21 +1493,18 @@ 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 +
|
||||
@@ -1797,10 +1755,8 @@ GitHubClaims allows customization of the username and groups claims.
|
||||
| Field | Description
|
||||
| *`username`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-idp-v1alpha1-githubusernameattribute[$$GitHubUsernameAttribute$$]__ | Username configures which property of the GitHub user record shall determine the username in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "id", "login", or "login:id". Defaults to "login:id". +
|
||||
|
||||
|
||||
GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens, +
|
||||
and may not start or end with hyphens. GitHub users are allowed to change their login name, +
|
||||
although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar", +
|
||||
@@ -1808,41 +1764,32 @@ then a second user might change their name from "baz" to "foo" in order to take
|
||||
username of the first user. For this reason, it is not as safe to make authorization decisions +
|
||||
based only on the user's login attribute. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these usernames are presented to Kubernetes. +
|
||||
|
||||
|
||||
Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and +
|
||||
unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value +
|
||||
from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable +
|
||||
choice to concatenate the two values. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user). +
|
||||
| *`groups`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-idp-v1alpha1-githubgroupnameattribute[$$GitHubGroupNameAttribute$$]__ | Groups configures which property of the GitHub team record shall determine the group names in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "name" or "slug". Defaults to "slug". +
|
||||
|
||||
|
||||
GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!"). +
|
||||
|
||||
|
||||
GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins"). +
|
||||
|
||||
|
||||
Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a +
|
||||
forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters +
|
||||
or single hyphens, so the first forward slash `/` will be the separator between the organization login name and +
|
||||
the team name or slug. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these group names are presented to Kubernetes. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user). +
|
||||
|===
|
||||
@@ -1865,7 +1812,6 @@ for web-based login flows.
|
||||
| *`secretName`* __string__ | SecretName contains the name of a namespace-local Secret object that provides the clientID and +
|
||||
clientSecret for an GitHub App or GitHub OAuth2 client. +
|
||||
|
||||
|
||||
This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret". +
|
||||
|===
|
||||
|
||||
@@ -1890,7 +1836,6 @@ names to present to Kubernetes. See the response schema for
|
||||
GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
|
||||
|
||||
Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
as OIDCClients.
|
||||
|
||||
@@ -1977,10 +1922,8 @@ GitHubIdentityProviderStatus is the status of an GitHub identity provider.
|
||||
| *`policy`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-idp-v1alpha1-githuballowedauthorganizationspolicy[$$GitHubAllowedAuthOrganizationsPolicy$$]__ | Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers". +
|
||||
Defaults to "OnlyUsersFromAllowedOrganizations". +
|
||||
|
||||
|
||||
Must be set to "AllGitHubUsers" if the allowed field is empty. +
|
||||
|
||||
|
||||
This field only exists to ensure that Pinniped administrators are aware that an empty list of +
|
||||
allowedOrganizations means all GitHub users are allowed to log in. +
|
||||
| *`allowed`* __string array__ | Allowed, when specified, indicates that only users with membership in at least one of the listed +
|
||||
@@ -1988,12 +1931,10 @@ GitHub organizations may log in. In addition, the group membership presented to
|
||||
teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be +
|
||||
provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP. +
|
||||
|
||||
|
||||
The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations, +
|
||||
otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams +
|
||||
within that organization. +
|
||||
|
||||
|
||||
If no organizations are listed, you must set organizations: AllGitHubUsers. +
|
||||
|===
|
||||
|
||||
@@ -2095,21 +2036,18 @@ 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 +
|
||||
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialIssuerKubeConfigInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
|
||||
*out = *in
|
||||
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.KubeConfigInfo != nil {
|
||||
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
|
||||
*out = new(CredentialIssuerKubeConfigInfo)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -134,24 +134,6 @@ spec:
|
||||
status:
|
||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
||||
properties:
|
||||
kubeConfigInfo:
|
||||
description: |-
|
||||
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
This field is deprecated and will be removed in a future version.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: The K8s API server CA bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
server:
|
||||
description: The K8s API server URL.
|
||||
minLength: 1
|
||||
pattern: ^https://|^http://
|
||||
type: string
|
||||
required:
|
||||
- certificateAuthorityData
|
||||
- server
|
||||
type: object
|
||||
strategies:
|
||||
description: List of integration strategies that were attempted by
|
||||
Pinniped.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -289,6 +289,9 @@ spec:
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: issuer must be an HTTPS URL
|
||||
rule: isURL(self) && url(self).getScheme() == 'https'
|
||||
tls:
|
||||
description: TLS specifies a secret which will contain Transport Layer
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
62
generated/1.28/README.adoc
generated
62
generated/1.28/README.adoc
generated
@@ -65,7 +65,6 @@ certificate bundle. +
|
||||
|
||||
JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
|
||||
|
||||
Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid
|
||||
signature, existence of claims, etc.) and extract the username and groups from the token.
|
||||
|
||||
@@ -429,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-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:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`server`* __string__ | The K8s API server URL. +
|
||||
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerspec"]
|
||||
@@ -481,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
|
||||
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
|
||||
This field is deprecated and will be removed in a future version. +
|
||||
|===
|
||||
|
||||
|
||||
@@ -566,7 +544,6 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
||||
| Field | Description
|
||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-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. +
|
||||
@@ -609,11 +586,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
||||
| *`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.type is "None". +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
||||
|
||||
|
||||
If this field is empty, the impersonation proxy will generate its own TLS certificate. +
|
||||
|===
|
||||
|
||||
@@ -624,11 +599,9 @@ If this field is empty, the impersonation proxy will generate its own TLS certif
|
||||
ImpersonationProxyTLSSpec contains information about how the Concierge impersonation proxy should
|
||||
serve TLS.
|
||||
|
||||
|
||||
If CertificateAuthorityData is not provided, the Concierge impersonation proxy will check the secret
|
||||
for a field called "ca.crt", which will be used as the CertificateAuthorityData.
|
||||
|
||||
|
||||
If neither CertificateAuthorityData nor ca.crt is provided, no CA bundle will be advertised for
|
||||
the impersonation proxy endpoint.
|
||||
|
||||
@@ -812,13 +785,11 @@ the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer i
|
||||
https://example.com/foo, then your authorization endpoint will look like +
|
||||
https://example.com/foo/some/path/to/auth/endpoint). +
|
||||
|
||||
|
||||
See +
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information. +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain. +
|
||||
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
||||
|
||||
|
||||
An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server, +
|
||||
how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to +
|
||||
extract a normalized user identity. Normalized user identities include a username and a list of group names. +
|
||||
@@ -831,7 +802,6 @@ rejection policies. Even though a user was able to authenticate with the identit
|
||||
the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could +
|
||||
disallow the authentication unless the user belongs to a specific group in the identity provider. +
|
||||
|
||||
|
||||
For backwards compatibility with versions of Pinniped which predate support for multiple identity providers, +
|
||||
an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which +
|
||||
exist in the same namespace, but also to reject all authentication requests when there is more than one identity +
|
||||
@@ -880,21 +850,17 @@ the TLS serving certificate for the HTTPS endpoints served by this FederationDom
|
||||
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 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. +
|
||||
|===
|
||||
|
||||
@@ -919,14 +885,12 @@ Each is a CEL expression. It may use the basic CEL language as defined in +
|
||||
https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in +
|
||||
https://github.com/google/cel-go/tree/master/ext#strings. +
|
||||
|
||||
|
||||
The username and groups extracted from the identity provider, and the constants defined in this CR, are +
|
||||
available as variables in all expressions. The username is provided via a variable called `username` and +
|
||||
the list of group names is provided via a variable called `groups` (which may be an empty list). +
|
||||
Each user-provided constants is provided via a variable named `strConst.varName` for string constants +
|
||||
and `strListConst.varName` for string list constants. +
|
||||
|
||||
|
||||
The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1. +
|
||||
Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated +
|
||||
and the authentication attempt is rejected. +
|
||||
@@ -939,7 +903,6 @@ groups list. +
|
||||
Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames. +
|
||||
After each expression, the new (potentially changed) username or groups get passed to the following expression. +
|
||||
|
||||
|
||||
Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain. +
|
||||
During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the +
|
||||
authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username +
|
||||
@@ -1109,7 +1072,6 @@ Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking
|
||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-granttype[$$GrantType$$] array__ | allowedGrantTypes is a list of the allowed grant_type param values that should be accepted during OIDC flows with this +
|
||||
client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- authorization_code: allows the client to perform the authorization code grant flow, i.e. allows the webapp to +
|
||||
authenticate users. This grant must always be listed. +
|
||||
@@ -1120,7 +1082,6 @@ which is a step in the process to be able to get a cluster credential for the us
|
||||
This grant must be listed if allowedScopes lists pinniped:request-audience. +
|
||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-scope[$$Scope$$] array__ | allowedScopes is a list of the allowed scopes param values that should be accepted during OIDC flows with this client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- openid: The client is allowed to request ID tokens. ID tokens only include the required claims by default (iss, sub, aud, exp, iat). +
|
||||
This scope must always be listed. +
|
||||
@@ -1532,21 +1493,18 @@ 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 +
|
||||
@@ -1797,10 +1755,8 @@ GitHubClaims allows customization of the username and groups claims.
|
||||
| Field | Description
|
||||
| *`username`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-idp-v1alpha1-githubusernameattribute[$$GitHubUsernameAttribute$$]__ | Username configures which property of the GitHub user record shall determine the username in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "id", "login", or "login:id". Defaults to "login:id". +
|
||||
|
||||
|
||||
GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens, +
|
||||
and may not start or end with hyphens. GitHub users are allowed to change their login name, +
|
||||
although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar", +
|
||||
@@ -1808,41 +1764,32 @@ then a second user might change their name from "baz" to "foo" in order to take
|
||||
username of the first user. For this reason, it is not as safe to make authorization decisions +
|
||||
based only on the user's login attribute. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these usernames are presented to Kubernetes. +
|
||||
|
||||
|
||||
Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and +
|
||||
unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value +
|
||||
from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable +
|
||||
choice to concatenate the two values. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user). +
|
||||
| *`groups`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-idp-v1alpha1-githubgroupnameattribute[$$GitHubGroupNameAttribute$$]__ | Groups configures which property of the GitHub team record shall determine the group names in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "name" or "slug". Defaults to "slug". +
|
||||
|
||||
|
||||
GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!"). +
|
||||
|
||||
|
||||
GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins"). +
|
||||
|
||||
|
||||
Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a +
|
||||
forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters +
|
||||
or single hyphens, so the first forward slash `/` will be the separator between the organization login name and +
|
||||
the team name or slug. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these group names are presented to Kubernetes. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user). +
|
||||
|===
|
||||
@@ -1865,7 +1812,6 @@ for web-based login flows.
|
||||
| *`secretName`* __string__ | SecretName contains the name of a namespace-local Secret object that provides the clientID and +
|
||||
clientSecret for an GitHub App or GitHub OAuth2 client. +
|
||||
|
||||
|
||||
This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret". +
|
||||
|===
|
||||
|
||||
@@ -1890,7 +1836,6 @@ names to present to Kubernetes. See the response schema for
|
||||
GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
|
||||
|
||||
Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
as OIDCClients.
|
||||
|
||||
@@ -1977,10 +1922,8 @@ GitHubIdentityProviderStatus is the status of an GitHub identity provider.
|
||||
| *`policy`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-idp-v1alpha1-githuballowedauthorganizationspolicy[$$GitHubAllowedAuthOrganizationsPolicy$$]__ | Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers". +
|
||||
Defaults to "OnlyUsersFromAllowedOrganizations". +
|
||||
|
||||
|
||||
Must be set to "AllGitHubUsers" if the allowed field is empty. +
|
||||
|
||||
|
||||
This field only exists to ensure that Pinniped administrators are aware that an empty list of +
|
||||
allowedOrganizations means all GitHub users are allowed to log in. +
|
||||
| *`allowed`* __string array__ | Allowed, when specified, indicates that only users with membership in at least one of the listed +
|
||||
@@ -1988,12 +1931,10 @@ GitHub organizations may log in. In addition, the group membership presented to
|
||||
teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be +
|
||||
provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP. +
|
||||
|
||||
|
||||
The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations, +
|
||||
otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams +
|
||||
within that organization. +
|
||||
|
||||
|
||||
If no organizations are listed, you must set organizations: AllGitHubUsers. +
|
||||
|===
|
||||
|
||||
@@ -2095,21 +2036,18 @@ 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 +
|
||||
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialIssuerKubeConfigInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
|
||||
*out = *in
|
||||
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.KubeConfigInfo != nil {
|
||||
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
|
||||
*out = new(CredentialIssuerKubeConfigInfo)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -134,24 +134,6 @@ spec:
|
||||
status:
|
||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
||||
properties:
|
||||
kubeConfigInfo:
|
||||
description: |-
|
||||
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
This field is deprecated and will be removed in a future version.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: The K8s API server CA bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
server:
|
||||
description: The K8s API server URL.
|
||||
minLength: 1
|
||||
pattern: ^https://|^http://
|
||||
type: string
|
||||
required:
|
||||
- certificateAuthorityData
|
||||
- server
|
||||
type: object
|
||||
strategies:
|
||||
description: List of integration strategies that were attempted by
|
||||
Pinniped.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -289,6 +289,9 @@ spec:
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: issuer must be an HTTPS URL
|
||||
rule: isURL(self) && url(self).getScheme() == 'https'
|
||||
tls:
|
||||
description: TLS specifies a secret which will contain Transport Layer
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
62
generated/1.29/README.adoc
generated
62
generated/1.29/README.adoc
generated
@@ -65,7 +65,6 @@ certificate bundle. +
|
||||
|
||||
JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
|
||||
|
||||
Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid
|
||||
signature, existence of claims, etc.) and extract the username and groups from the token.
|
||||
|
||||
@@ -429,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-29-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:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`server`* __string__ | The K8s API server URL. +
|
||||
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerspec"]
|
||||
@@ -481,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
|
||||
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
|
||||
This field is deprecated and will be removed in a future version. +
|
||||
|===
|
||||
|
||||
|
||||
@@ -566,7 +544,6 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
||||
| Field | Description
|
||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-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. +
|
||||
@@ -609,11 +586,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
||||
| *`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.type is "None". +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
||||
|
||||
|
||||
If this field is empty, the impersonation proxy will generate its own TLS certificate. +
|
||||
|===
|
||||
|
||||
@@ -624,11 +599,9 @@ If this field is empty, the impersonation proxy will generate its own TLS certif
|
||||
ImpersonationProxyTLSSpec contains information about how the Concierge impersonation proxy should
|
||||
serve TLS.
|
||||
|
||||
|
||||
If CertificateAuthorityData is not provided, the Concierge impersonation proxy will check the secret
|
||||
for a field called "ca.crt", which will be used as the CertificateAuthorityData.
|
||||
|
||||
|
||||
If neither CertificateAuthorityData nor ca.crt is provided, no CA bundle will be advertised for
|
||||
the impersonation proxy endpoint.
|
||||
|
||||
@@ -812,13 +785,11 @@ the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer i
|
||||
https://example.com/foo, then your authorization endpoint will look like +
|
||||
https://example.com/foo/some/path/to/auth/endpoint). +
|
||||
|
||||
|
||||
See +
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information. +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain. +
|
||||
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
||||
|
||||
|
||||
An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server, +
|
||||
how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to +
|
||||
extract a normalized user identity. Normalized user identities include a username and a list of group names. +
|
||||
@@ -831,7 +802,6 @@ rejection policies. Even though a user was able to authenticate with the identit
|
||||
the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could +
|
||||
disallow the authentication unless the user belongs to a specific group in the identity provider. +
|
||||
|
||||
|
||||
For backwards compatibility with versions of Pinniped which predate support for multiple identity providers, +
|
||||
an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which +
|
||||
exist in the same namespace, but also to reject all authentication requests when there is more than one identity +
|
||||
@@ -880,21 +850,17 @@ the TLS serving certificate for the HTTPS endpoints served by this FederationDom
|
||||
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 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. +
|
||||
|===
|
||||
|
||||
@@ -919,14 +885,12 @@ Each is a CEL expression. It may use the basic CEL language as defined in +
|
||||
https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in +
|
||||
https://github.com/google/cel-go/tree/master/ext#strings. +
|
||||
|
||||
|
||||
The username and groups extracted from the identity provider, and the constants defined in this CR, are +
|
||||
available as variables in all expressions. The username is provided via a variable called `username` and +
|
||||
the list of group names is provided via a variable called `groups` (which may be an empty list). +
|
||||
Each user-provided constants is provided via a variable named `strConst.varName` for string constants +
|
||||
and `strListConst.varName` for string list constants. +
|
||||
|
||||
|
||||
The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1. +
|
||||
Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated +
|
||||
and the authentication attempt is rejected. +
|
||||
@@ -939,7 +903,6 @@ groups list. +
|
||||
Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames. +
|
||||
After each expression, the new (potentially changed) username or groups get passed to the following expression. +
|
||||
|
||||
|
||||
Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain. +
|
||||
During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the +
|
||||
authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username +
|
||||
@@ -1109,7 +1072,6 @@ Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking
|
||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-supervisor-config-v1alpha1-granttype[$$GrantType$$] array__ | allowedGrantTypes is a list of the allowed grant_type param values that should be accepted during OIDC flows with this +
|
||||
client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- authorization_code: allows the client to perform the authorization code grant flow, i.e. allows the webapp to +
|
||||
authenticate users. This grant must always be listed. +
|
||||
@@ -1120,7 +1082,6 @@ which is a step in the process to be able to get a cluster credential for the us
|
||||
This grant must be listed if allowedScopes lists pinniped:request-audience. +
|
||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-supervisor-config-v1alpha1-scope[$$Scope$$] array__ | allowedScopes is a list of the allowed scopes param values that should be accepted during OIDC flows with this client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- openid: The client is allowed to request ID tokens. ID tokens only include the required claims by default (iss, sub, aud, exp, iat). +
|
||||
This scope must always be listed. +
|
||||
@@ -1532,21 +1493,18 @@ 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 +
|
||||
@@ -1797,10 +1755,8 @@ GitHubClaims allows customization of the username and groups claims.
|
||||
| Field | Description
|
||||
| *`username`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-supervisor-idp-v1alpha1-githubusernameattribute[$$GitHubUsernameAttribute$$]__ | Username configures which property of the GitHub user record shall determine the username in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "id", "login", or "login:id". Defaults to "login:id". +
|
||||
|
||||
|
||||
GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens, +
|
||||
and may not start or end with hyphens. GitHub users are allowed to change their login name, +
|
||||
although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar", +
|
||||
@@ -1808,41 +1764,32 @@ then a second user might change their name from "baz" to "foo" in order to take
|
||||
username of the first user. For this reason, it is not as safe to make authorization decisions +
|
||||
based only on the user's login attribute. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these usernames are presented to Kubernetes. +
|
||||
|
||||
|
||||
Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and +
|
||||
unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value +
|
||||
from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable +
|
||||
choice to concatenate the two values. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user). +
|
||||
| *`groups`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-supervisor-idp-v1alpha1-githubgroupnameattribute[$$GitHubGroupNameAttribute$$]__ | Groups configures which property of the GitHub team record shall determine the group names in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "name" or "slug". Defaults to "slug". +
|
||||
|
||||
|
||||
GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!"). +
|
||||
|
||||
|
||||
GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins"). +
|
||||
|
||||
|
||||
Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a +
|
||||
forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters +
|
||||
or single hyphens, so the first forward slash `/` will be the separator between the organization login name and +
|
||||
the team name or slug. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these group names are presented to Kubernetes. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user). +
|
||||
|===
|
||||
@@ -1865,7 +1812,6 @@ for web-based login flows.
|
||||
| *`secretName`* __string__ | SecretName contains the name of a namespace-local Secret object that provides the clientID and +
|
||||
clientSecret for an GitHub App or GitHub OAuth2 client. +
|
||||
|
||||
|
||||
This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret". +
|
||||
|===
|
||||
|
||||
@@ -1890,7 +1836,6 @@ names to present to Kubernetes. See the response schema for
|
||||
GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
|
||||
|
||||
Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
as OIDCClients.
|
||||
|
||||
@@ -1977,10 +1922,8 @@ GitHubIdentityProviderStatus is the status of an GitHub identity provider.
|
||||
| *`policy`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-supervisor-idp-v1alpha1-githuballowedauthorganizationspolicy[$$GitHubAllowedAuthOrganizationsPolicy$$]__ | Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers". +
|
||||
Defaults to "OnlyUsersFromAllowedOrganizations". +
|
||||
|
||||
|
||||
Must be set to "AllGitHubUsers" if the allowed field is empty. +
|
||||
|
||||
|
||||
This field only exists to ensure that Pinniped administrators are aware that an empty list of +
|
||||
allowedOrganizations means all GitHub users are allowed to log in. +
|
||||
| *`allowed`* __string array__ | Allowed, when specified, indicates that only users with membership in at least one of the listed +
|
||||
@@ -1988,12 +1931,10 @@ GitHub organizations may log in. In addition, the group membership presented to
|
||||
teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be +
|
||||
provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP. +
|
||||
|
||||
|
||||
The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations, +
|
||||
otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams +
|
||||
within that organization. +
|
||||
|
||||
|
||||
If no organizations are listed, you must set organizations: AllGitHubUsers. +
|
||||
|===
|
||||
|
||||
@@ -2095,21 +2036,18 @@ 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 +
|
||||
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialIssuerKubeConfigInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
|
||||
*out = *in
|
||||
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.KubeConfigInfo != nil {
|
||||
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
|
||||
*out = new(CredentialIssuerKubeConfigInfo)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
4
generated/1.29/apis/go.mod
generated
4
generated/1.29/apis/go.mod
generated
@@ -4,8 +4,8 @@ module go.pinniped.dev/generated/1.29/apis
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
k8s.io/api v0.29.11
|
||||
k8s.io/apimachinery v0.29.11
|
||||
k8s.io/api v0.29.14
|
||||
k8s.io/apimachinery v0.29.14
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
8
generated/1.29/apis/go.sum
generated
8
generated/1.29/apis/go.sum
generated
@@ -75,10 +75,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.29.11 h1:6FwDo33f1WX5Yu0RQTX9YAd3wth8Ik0B4SXQKsoQfbk=
|
||||
k8s.io/api v0.29.11/go.mod h1:3TDAW1OpFbz/Yx5r0W06b6eiAfHEwtH61VYDzpTU4Ng=
|
||||
k8s.io/apimachinery v0.29.11 h1:55+6ue9advpA7T0sX2ZJDHCLKuiFfrAAR/39VQN9KEQ=
|
||||
k8s.io/apimachinery v0.29.11/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
|
||||
k8s.io/api v0.29.14 h1:JWFh5ufowH3Y6tCgEzY3URVJHb27f0tEDEej0nCjWDw=
|
||||
k8s.io/api v0.29.14/go.mod h1:IV8YqKxMm8JGLBLlHM13Npn5lCITH10XYipWEW+YEOQ=
|
||||
k8s.io/apimachinery v0.29.14 h1:IDhwnGNCp836SLOwW1SoEfFNV77wxIklhxeAHX9vmSo=
|
||||
k8s.io/apimachinery v0.29.14/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
||||
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
6
generated/1.29/client/go.mod
generated
6
generated/1.29/client/go.mod
generated
@@ -7,8 +7,8 @@ replace go.pinniped.dev/generated/1.29/apis => ../apis
|
||||
|
||||
require (
|
||||
go.pinniped.dev/generated/1.29/apis v0.0.0
|
||||
k8s.io/apimachinery v0.29.11
|
||||
k8s.io/client-go v0.29.11
|
||||
k8s.io/apimachinery v0.29.14
|
||||
k8s.io/client-go v0.29.14
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00
|
||||
)
|
||||
|
||||
@@ -44,7 +44,7 @@ require (
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.29.11 // indirect
|
||||
k8s.io/api v0.29.14 // indirect
|
||||
k8s.io/klog/v2 v2.110.1 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
|
||||
12
generated/1.29/client/go.sum
generated
12
generated/1.29/client/go.sum
generated
@@ -134,12 +134,12 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.29.11 h1:6FwDo33f1WX5Yu0RQTX9YAd3wth8Ik0B4SXQKsoQfbk=
|
||||
k8s.io/api v0.29.11/go.mod h1:3TDAW1OpFbz/Yx5r0W06b6eiAfHEwtH61VYDzpTU4Ng=
|
||||
k8s.io/apimachinery v0.29.11 h1:55+6ue9advpA7T0sX2ZJDHCLKuiFfrAAR/39VQN9KEQ=
|
||||
k8s.io/apimachinery v0.29.11/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
|
||||
k8s.io/client-go v0.29.11 h1:mBX7Ub0uqpLMwWz3J/AGS/xKOZsjr349qZ1vxVoL1l8=
|
||||
k8s.io/client-go v0.29.11/go.mod h1:WOEoi/eLg2YEg3/yEd7YK3CNScYkM8AEScQadxUnaTE=
|
||||
k8s.io/api v0.29.14 h1:JWFh5ufowH3Y6tCgEzY3URVJHb27f0tEDEej0nCjWDw=
|
||||
k8s.io/api v0.29.14/go.mod h1:IV8YqKxMm8JGLBLlHM13Npn5lCITH10XYipWEW+YEOQ=
|
||||
k8s.io/apimachinery v0.29.14 h1:IDhwnGNCp836SLOwW1SoEfFNV77wxIklhxeAHX9vmSo=
|
||||
k8s.io/apimachinery v0.29.14/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
|
||||
k8s.io/client-go v0.29.14 h1:OSnzZ9DClaFRgl3zMAY2kGZhNjdGJkEb+RDz+MW2h6k=
|
||||
k8s.io/client-go v0.29.14/go.mod h1:XtZt5n5UxKfPJ+sCoTPcEavWgZbLFFxMnAFFRQGK1RY=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -134,24 +134,6 @@ spec:
|
||||
status:
|
||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
||||
properties:
|
||||
kubeConfigInfo:
|
||||
description: |-
|
||||
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
This field is deprecated and will be removed in a future version.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: The K8s API server CA bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
server:
|
||||
description: The K8s API server URL.
|
||||
minLength: 1
|
||||
pattern: ^https://|^http://
|
||||
type: string
|
||||
required:
|
||||
- certificateAuthorityData
|
||||
- server
|
||||
type: object
|
||||
strategies:
|
||||
description: List of integration strategies that were attempted by
|
||||
Pinniped.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -289,6 +289,9 @@ spec:
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: issuer must be an HTTPS URL
|
||||
rule: isURL(self) && url(self).getScheme() == 'https'
|
||||
tls:
|
||||
description: TLS specifies a secret which will contain Transport Layer
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
62
generated/1.30/README.adoc
generated
62
generated/1.30/README.adoc
generated
@@ -65,7 +65,6 @@ certificate bundle. +
|
||||
|
||||
JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
|
||||
|
||||
Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid
|
||||
signature, existence of claims, etc.) and extract the username and groups from the token.
|
||||
|
||||
@@ -429,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-30-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:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`server`* __string__ | The K8s API server URL. +
|
||||
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerspec"]
|
||||
@@ -481,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
|
||||
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
|
||||
This field is deprecated and will be removed in a future version. +
|
||||
|===
|
||||
|
||||
|
||||
@@ -566,7 +544,6 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
||||
| Field | Description
|
||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-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. +
|
||||
@@ -609,11 +586,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
||||
| *`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.type is "None". +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
||||
|
||||
|
||||
If this field is empty, the impersonation proxy will generate its own TLS certificate. +
|
||||
|===
|
||||
|
||||
@@ -624,11 +599,9 @@ If this field is empty, the impersonation proxy will generate its own TLS certif
|
||||
ImpersonationProxyTLSSpec contains information about how the Concierge impersonation proxy should
|
||||
serve TLS.
|
||||
|
||||
|
||||
If CertificateAuthorityData is not provided, the Concierge impersonation proxy will check the secret
|
||||
for a field called "ca.crt", which will be used as the CertificateAuthorityData.
|
||||
|
||||
|
||||
If neither CertificateAuthorityData nor ca.crt is provided, no CA bundle will be advertised for
|
||||
the impersonation proxy endpoint.
|
||||
|
||||
@@ -812,13 +785,11 @@ the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer i
|
||||
https://example.com/foo, then your authorization endpoint will look like +
|
||||
https://example.com/foo/some/path/to/auth/endpoint). +
|
||||
|
||||
|
||||
See +
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information. +
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain. +
|
||||
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
||||
|
||||
|
||||
An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server, +
|
||||
how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to +
|
||||
extract a normalized user identity. Normalized user identities include a username and a list of group names. +
|
||||
@@ -831,7 +802,6 @@ rejection policies. Even though a user was able to authenticate with the identit
|
||||
the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could +
|
||||
disallow the authentication unless the user belongs to a specific group in the identity provider. +
|
||||
|
||||
|
||||
For backwards compatibility with versions of Pinniped which predate support for multiple identity providers, +
|
||||
an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which +
|
||||
exist in the same namespace, but also to reject all authentication requests when there is more than one identity +
|
||||
@@ -880,21 +850,17 @@ the TLS serving certificate for the HTTPS endpoints served by this FederationDom
|
||||
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 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. +
|
||||
|===
|
||||
|
||||
@@ -919,14 +885,12 @@ Each is a CEL expression. It may use the basic CEL language as defined in +
|
||||
https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in +
|
||||
https://github.com/google/cel-go/tree/master/ext#strings. +
|
||||
|
||||
|
||||
The username and groups extracted from the identity provider, and the constants defined in this CR, are +
|
||||
available as variables in all expressions. The username is provided via a variable called `username` and +
|
||||
the list of group names is provided via a variable called `groups` (which may be an empty list). +
|
||||
Each user-provided constants is provided via a variable named `strConst.varName` for string constants +
|
||||
and `strListConst.varName` for string list constants. +
|
||||
|
||||
|
||||
The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1. +
|
||||
Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated +
|
||||
and the authentication attempt is rejected. +
|
||||
@@ -939,7 +903,6 @@ groups list. +
|
||||
Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames. +
|
||||
After each expression, the new (potentially changed) username or groups get passed to the following expression. +
|
||||
|
||||
|
||||
Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain. +
|
||||
During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the +
|
||||
authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username +
|
||||
@@ -1109,7 +1072,6 @@ Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking
|
||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-supervisor-config-v1alpha1-granttype[$$GrantType$$] array__ | allowedGrantTypes is a list of the allowed grant_type param values that should be accepted during OIDC flows with this +
|
||||
client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- authorization_code: allows the client to perform the authorization code grant flow, i.e. allows the webapp to +
|
||||
authenticate users. This grant must always be listed. +
|
||||
@@ -1120,7 +1082,6 @@ which is a step in the process to be able to get a cluster credential for the us
|
||||
This grant must be listed if allowedScopes lists pinniped:request-audience. +
|
||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-supervisor-config-v1alpha1-scope[$$Scope$$] array__ | allowedScopes is a list of the allowed scopes param values that should be accepted during OIDC flows with this client. +
|
||||
|
||||
|
||||
Must only contain the following values: +
|
||||
- openid: The client is allowed to request ID tokens. ID tokens only include the required claims by default (iss, sub, aud, exp, iat). +
|
||||
This scope must always be listed. +
|
||||
@@ -1532,21 +1493,18 @@ 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 +
|
||||
@@ -1797,10 +1755,8 @@ GitHubClaims allows customization of the username and groups claims.
|
||||
| Field | Description
|
||||
| *`username`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-supervisor-idp-v1alpha1-githubusernameattribute[$$GitHubUsernameAttribute$$]__ | Username configures which property of the GitHub user record shall determine the username in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "id", "login", or "login:id". Defaults to "login:id". +
|
||||
|
||||
|
||||
GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens, +
|
||||
and may not start or end with hyphens. GitHub users are allowed to change their login name, +
|
||||
although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar", +
|
||||
@@ -1808,41 +1764,32 @@ then a second user might change their name from "baz" to "foo" in order to take
|
||||
username of the first user. For this reason, it is not as safe to make authorization decisions +
|
||||
based only on the user's login attribute. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these usernames are presented to Kubernetes. +
|
||||
|
||||
|
||||
Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and +
|
||||
unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value +
|
||||
from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable +
|
||||
choice to concatenate the two values. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user). +
|
||||
| *`groups`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-supervisor-idp-v1alpha1-githubgroupnameattribute[$$GitHubGroupNameAttribute$$]__ | Groups configures which property of the GitHub team record shall determine the group names in Kubernetes. +
|
||||
|
||||
|
||||
Can be either "name" or "slug". Defaults to "slug". +
|
||||
|
||||
|
||||
GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!"). +
|
||||
|
||||
|
||||
GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins"). +
|
||||
|
||||
|
||||
Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a +
|
||||
forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters +
|
||||
or single hyphens, so the first forward slash `/` will be the separator between the organization login name and +
|
||||
the team name or slug. +
|
||||
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's +
|
||||
FederationDomain to further customize how these group names are presented to Kubernetes. +
|
||||
|
||||
|
||||
See the response schema for +
|
||||
[List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user). +
|
||||
|===
|
||||
@@ -1865,7 +1812,6 @@ for web-based login flows.
|
||||
| *`secretName`* __string__ | SecretName contains the name of a namespace-local Secret object that provides the clientID and +
|
||||
clientSecret for an GitHub App or GitHub OAuth2 client. +
|
||||
|
||||
|
||||
This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret". +
|
||||
|===
|
||||
|
||||
@@ -1890,7 +1836,6 @@ names to present to Kubernetes. See the response schema for
|
||||
GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
|
||||
|
||||
Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
as OIDCClients.
|
||||
|
||||
@@ -1977,10 +1922,8 @@ GitHubIdentityProviderStatus is the status of an GitHub identity provider.
|
||||
| *`policy`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-supervisor-idp-v1alpha1-githuballowedauthorganizationspolicy[$$GitHubAllowedAuthOrganizationsPolicy$$]__ | Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers". +
|
||||
Defaults to "OnlyUsersFromAllowedOrganizations". +
|
||||
|
||||
|
||||
Must be set to "AllGitHubUsers" if the allowed field is empty. +
|
||||
|
||||
|
||||
This field only exists to ensure that Pinniped administrators are aware that an empty list of +
|
||||
allowedOrganizations means all GitHub users are allowed to log in. +
|
||||
| *`allowed`* __string array__ | Allowed, when specified, indicates that only users with membership in at least one of the listed +
|
||||
@@ -1988,12 +1931,10 @@ GitHub organizations may log in. In addition, the group membership presented to
|
||||
teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be +
|
||||
provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP. +
|
||||
|
||||
|
||||
The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations, +
|
||||
otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams +
|
||||
within that organization. +
|
||||
|
||||
|
||||
If no organizations are listed, you must set organizations: AllGitHubUsers. +
|
||||
|===
|
||||
|
||||
@@ -2095,21 +2036,18 @@ 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 +
|
||||
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
|
||||
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CredentialIssuerKubeConfigInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
|
||||
*out = *in
|
||||
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.KubeConfigInfo != nil {
|
||||
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
|
||||
*out = new(CredentialIssuerKubeConfigInfo)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
6
generated/1.30/apis/go.mod
generated
6
generated/1.30/apis/go.mod
generated
@@ -3,11 +3,11 @@ module go.pinniped.dev/generated/1.30/apis
|
||||
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.23.4
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
k8s.io/api v0.30.7
|
||||
k8s.io/apimachinery v0.30.7
|
||||
k8s.io/api v0.30.10
|
||||
k8s.io/apimachinery v0.30.10
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
8
generated/1.30/apis/go.sum
generated
8
generated/1.30/apis/go.sum
generated
@@ -75,10 +75,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.30.7 h1:wB2eHI+IptVYsz5WsAQpI6+Dqi3+11wEWBqIh4fh980=
|
||||
k8s.io/api v0.30.7/go.mod h1:bR0EwbmhYmJvUoeza7ZzBUmYCrVXccQ9JOdfv0BxhH0=
|
||||
k8s.io/apimachinery v0.30.7 h1:CoQFxvzPFKwU1eJGN/8LgM3ZJBC3hKgvwGqRrL43uIY=
|
||||
k8s.io/apimachinery v0.30.7/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||
k8s.io/api v0.30.10 h1:2YvzRF/BELgCvxbQqFKaan5hnj2+y7JOuqu2WpVk3gg=
|
||||
k8s.io/api v0.30.10/go.mod h1:Hyz3ZuK7jVLJBUFvwzDSGwxHuDdsrGs5RzF16wfHIn4=
|
||||
k8s.io/apimachinery v0.30.10 h1:UflKuJeSSArttm05wjYP0GwpTlvjnMbDKFn6F7rKkKU=
|
||||
k8s.io/apimachinery v0.30.10/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
||||
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
8
generated/1.30/client/go.mod
generated
8
generated/1.30/client/go.mod
generated
@@ -3,14 +3,14 @@ module go.pinniped.dev/generated/1.30/client
|
||||
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.23.4
|
||||
toolchain go1.24.1
|
||||
|
||||
replace go.pinniped.dev/generated/1.30/apis => ../apis
|
||||
|
||||
require (
|
||||
go.pinniped.dev/generated/1.30/apis v0.0.0
|
||||
k8s.io/apimachinery v0.30.7
|
||||
k8s.io/client-go v0.30.7
|
||||
k8s.io/apimachinery v0.30.10
|
||||
k8s.io/client-go v0.30.10
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340
|
||||
)
|
||||
|
||||
@@ -46,7 +46,7 @@ require (
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.30.7 // indirect
|
||||
k8s.io/api v0.30.10 // indirect
|
||||
k8s.io/klog/v2 v2.120.1 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
|
||||
12
generated/1.30/client/go.sum
generated
12
generated/1.30/client/go.sum
generated
@@ -134,12 +134,12 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.30.7 h1:wB2eHI+IptVYsz5WsAQpI6+Dqi3+11wEWBqIh4fh980=
|
||||
k8s.io/api v0.30.7/go.mod h1:bR0EwbmhYmJvUoeza7ZzBUmYCrVXccQ9JOdfv0BxhH0=
|
||||
k8s.io/apimachinery v0.30.7 h1:CoQFxvzPFKwU1eJGN/8LgM3ZJBC3hKgvwGqRrL43uIY=
|
||||
k8s.io/apimachinery v0.30.7/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||
k8s.io/client-go v0.30.7 h1:DQRfuGWxDzxPEyyiTE/fxzAsZcj2p9sbc5671njR52w=
|
||||
k8s.io/client-go v0.30.7/go.mod h1:oED9+njB91ExCc4BNPAotniB7WH1ig7CmiBx5pVA1yw=
|
||||
k8s.io/api v0.30.10 h1:2YvzRF/BELgCvxbQqFKaan5hnj2+y7JOuqu2WpVk3gg=
|
||||
k8s.io/api v0.30.10/go.mod h1:Hyz3ZuK7jVLJBUFvwzDSGwxHuDdsrGs5RzF16wfHIn4=
|
||||
k8s.io/apimachinery v0.30.10 h1:UflKuJeSSArttm05wjYP0GwpTlvjnMbDKFn6F7rKkKU=
|
||||
k8s.io/apimachinery v0.30.10/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||
k8s.io/client-go v0.30.10 h1:C0oWM82QMvosIl/IdJhWfTUb7rIxM52rNSutFBknAVY=
|
||||
k8s.io/client-go v0.30.10/go.mod h1:OfTvt0yuo8VpMViOsgvYQb+tMJQLNWVBqXWkzdFXSq4=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user