Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2998f7b713 |
@ -21,6 +21,3 @@
|
|||||||
|
|
||||||
# MacOS Desktop Services Store
|
# MacOS Desktop Services Store
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# Hugo temp file
|
|
||||||
.hugo_build.lock
|
|
||||||
|
19
.drone.yml
19
.drone.yml
@ -1,19 +0,0 @@
|
|||||||
kind: pipeline
|
|
||||||
type: kubernetes
|
|
||||||
name: Container
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build & publish
|
|
||||||
image: spritsail/docker-build
|
|
||||||
context: .
|
|
||||||
settings:
|
|
||||||
repo: bv11-cr01.bessems.eu/library/pinniped-server
|
|
||||||
registry: bv11-cr01.bessems.eu
|
|
||||||
tags: latest
|
|
||||||
build_args:
|
|
||||||
- BUILDPLATFORM=linux/amd64
|
|
||||||
mtu: 1450
|
|
||||||
username:
|
|
||||||
from_secret: harbor_username
|
|
||||||
password:
|
|
||||||
from_secret: harbor_password
|
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -19,6 +19,3 @@
|
|||||||
|
|
||||||
# MacOS Desktop Services Store
|
# MacOS Desktop Services Store
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# Hugo temp file
|
|
||||||
.hugo_build.lock
|
|
||||||
|
23
Dockerfile
23
Dockerfile
@ -3,29 +3,23 @@
|
|||||||
# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
# Prepare to cross-compile by always running the build stage in the build platform, not the target platform.
|
FROM golang:1.21.1 as build-env
|
||||||
FROM --platform=linux/amd64 golang:1.21.3 as build-env
|
|
||||||
|
|
||||||
WORKDIR /work
|
WORKDIR /work
|
||||||
|
COPY . .
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
|
|
||||||
ARG KUBE_GIT_VERSION
|
ARG KUBE_GIT_VERSION
|
||||||
ENV KUBE_GIT_VERSION=$KUBE_GIT_VERSION
|
ENV KUBE_GIT_VERSION=$KUBE_GIT_VERSION
|
||||||
|
|
||||||
# These will be set by buildkit automatically, e.g. TARGETOS set to "linux" and TARGETARCH set to "amd64" or "arm64".
|
# Build the executable binary (CGO_ENABLED=0 means static linking)
|
||||||
# Useful for building multi-arch container images.
|
# Pass in GOCACHE (build cache) and GOMODCACHE (module cache) so they
|
||||||
ARG TARGETOS
|
# can be re-used between image builds.
|
||||||
ARG TARGETARCH
|
|
||||||
|
|
||||||
# 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/
|
|
||||||
RUN \
|
RUN \
|
||||||
--mount=target=. \
|
|
||||||
--mount=type=cache,target=/cache/gocache \
|
--mount=type=cache,target=/cache/gocache \
|
||||||
--mount=type=cache,target=/cache/gomodcache \
|
--mount=type=cache,target=/cache/gomodcache \
|
||||||
export GOCACHE=/cache/gocache GOMODCACHE=/cache/gomodcache CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH && \
|
mkdir out && \
|
||||||
|
export GOCACHE=/cache/gocache GOMODCACHE=/cache/gomodcache CGO_ENABLED=0 GOOS=linux GOARCH=amd64 && \
|
||||||
go build -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-concierge-kube-cert-agent ./cmd/pinniped-concierge-kube-cert-agent/... && \
|
go build -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-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 -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-concierge && \
|
||||||
@ -33,9 +27,6 @@ RUN \
|
|||||||
ln -s /usr/local/bin/pinniped-server /usr/local/bin/local-user-authenticator
|
ln -s /usr/local/bin/pinniped-server /usr/local/bin/local-user-authenticator
|
||||||
|
|
||||||
# Use a distroless runtime image with CA certificates, timezone data, and not much else.
|
# Use a distroless runtime image with CA certificates, timezone data, and not much else.
|
||||||
# Note that we are not using --platform here, so it will choose the base image for the target platform, not the build platform.
|
|
||||||
# By using "distroless/static" instead of "distroless/static-debianXX" we can float on the latest stable version of debian.
|
|
||||||
# See https://github.com/GoogleContainerTools/distroless#base-operating-system
|
|
||||||
FROM gcr.io/distroless/static:nonroot@sha256:2a9e2b4fa771d31fe3346a873be845bfc2159695b9f90ca08e950497006ccc2e
|
FROM gcr.io/distroless/static:nonroot@sha256:2a9e2b4fa771d31fe3346a873be845bfc2159695b9f90ca08e950497006ccc2e
|
||||||
|
|
||||||
# Copy the server binary from the build-env stage.
|
# Copy the server binary from the build-env stage.
|
||||||
|
@ -96,7 +96,6 @@ type getKubeconfigParams struct {
|
|||||||
credentialCachePath string
|
credentialCachePath string
|
||||||
credentialCachePathSet bool
|
credentialCachePathSet bool
|
||||||
installHint string
|
installHint string
|
||||||
pinnipedCliPath string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type discoveryResponseScopesSupported struct {
|
type discoveryResponseScopesSupported struct {
|
||||||
@ -152,16 +151,14 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
|||||||
f.StringVarP(&flags.outputPath, "output", "o", "", "Output file path (default: stdout)")
|
f.StringVarP(&flags.outputPath, "output", "o", "", "Output file path (default: stdout)")
|
||||||
f.StringVar(&flags.generatedNameSuffix, "generated-name-suffix", "-pinniped", "Suffix to append to generated cluster, context, user kubeconfig entries")
|
f.StringVar(&flags.generatedNameSuffix, "generated-name-suffix", "-pinniped", "Suffix to append to generated cluster, context, user kubeconfig entries")
|
||||||
f.StringVar(&flags.credentialCachePath, "credential-cache", "", "Path to cluster-specific credentials cache")
|
f.StringVar(&flags.credentialCachePath, "credential-cache", "", "Path to cluster-specific credentials cache")
|
||||||
f.StringVar(&flags.pinnipedCliPath, "pinniped-cli-path", "", "Full path or executable name for the Pinniped CLI binary to be embedded in the resulting kubeconfig output (e.g. 'pinniped') (default: full path of the binary used to execute this command)")
|
|
||||||
f.StringVar(&flags.installHint, "install-hint", "The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli for more details", "This text is shown to the user when the pinniped CLI is not installed.")
|
f.StringVar(&flags.installHint, "install-hint", "The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli for more details", "This text is shown to the user when the pinniped CLI is not installed.")
|
||||||
|
mustMarkHidden(cmd, "oidc-debug-session-cache")
|
||||||
|
|
||||||
mustMarkHidden(cmd,
|
// --oidc-skip-listen is mainly needed for testing. We'll leave it hidden until we have a non-testing use case.
|
||||||
"oidc-debug-session-cache",
|
mustMarkHidden(cmd, "oidc-skip-listen")
|
||||||
"oidc-skip-listen", // --oidc-skip-listen is mainly needed for testing. We'll leave it hidden until we have a non-testing use case.
|
|
||||||
"concierge-namespace",
|
|
||||||
)
|
|
||||||
|
|
||||||
mustMarkDeprecated(cmd, "concierge-namespace", "not needed anymore")
|
mustMarkDeprecated(cmd, "concierge-namespace", "not needed anymore")
|
||||||
|
mustMarkHidden(cmd, "concierge-namespace")
|
||||||
|
|
||||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
if flags.outputPath != "" {
|
if flags.outputPath != "" {
|
||||||
@ -271,12 +268,7 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
|
|||||||
|
|
||||||
execConfig.InstallHint = flags.installHint
|
execConfig.InstallHint = flags.installHint
|
||||||
var err error
|
var err error
|
||||||
execConfig.Command, err = func() (string, error) {
|
execConfig.Command, err = deps.getPathToSelf()
|
||||||
if flags.pinnipedCliPath != "" {
|
|
||||||
return flags.pinnipedCliPath, nil
|
|
||||||
}
|
|
||||||
return deps.getPathToSelf()
|
|
||||||
}()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not determine the Pinniped executable path: %w", err)
|
return nil, fmt.Errorf("could not determine the Pinniped executable path: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,6 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
--oidc-session-cache string Path to OpenID Connect session cache file
|
--oidc-session-cache string Path to OpenID Connect session cache file
|
||||||
--oidc-skip-browser During OpenID Connect login, skip opening the browser (just print the URL)
|
--oidc-skip-browser During OpenID Connect login, skip opening the browser (just print the URL)
|
||||||
-o, --output string Output file path (default: stdout)
|
-o, --output string Output file path (default: stdout)
|
||||||
--pinniped-cli-path string Full path or executable name for the Pinniped CLI binary to be embedded in the resulting kubeconfig output (e.g. 'pinniped') (default: full path of the binary used to execute this command)
|
|
||||||
--skip-validation Skip final validation of the kubeconfig (default: false)
|
--skip-validation Skip final validation of the kubeconfig (default: false)
|
||||||
--static-token string Instead of doing an OIDC-based login, specify a static token
|
--static-token string Instead of doing an OIDC-based login, specify a static token
|
||||||
--static-token-env string Instead of doing an OIDC-based login, read a static token from the environment
|
--static-token-env string Instead of doing an OIDC-based login, read a static token from the environment
|
||||||
@ -1584,6 +1583,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
name: "autodetect nothing, set a bunch of options",
|
name: "autodetect nothing, set a bunch of options",
|
||||||
args: func(issuerCABundle string, issuerURL string) []string {
|
args: func(issuerCABundle string, issuerURL string) []string {
|
||||||
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
|
f := testutil.WriteStringToTempFile(t, "testca-*.pem", issuerCABundle)
|
||||||
@ -1607,7 +1607,6 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
"--skip-validation",
|
"--skip-validation",
|
||||||
"--generated-name-suffix", "-sso",
|
"--generated-name-suffix", "-sso",
|
||||||
"--credential-cache", "/path/to/cache/dir/credentials.yaml",
|
"--credential-cache", "/path/to/cache/dir/credentials.yaml",
|
||||||
"--pinniped-cli-path", "/some/path/to/command-exe",
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||||
@ -1659,7 +1658,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
- --session-cache=/path/to/cache/dir/sessions.yaml
|
- --session-cache=/path/to/cache/dir/sessions.yaml
|
||||||
- --debug-session-cache
|
- --debug-session-cache
|
||||||
- --request-audience=test-audience
|
- --request-audience=test-audience
|
||||||
command: /some/path/to/command-exe
|
command: '.../path/to/pinniped'
|
||||||
env: []
|
env: []
|
||||||
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
|
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
|
||||||
for more details
|
for more details
|
||||||
|
@ -245,14 +245,6 @@ spec:
|
|||||||
effect: NoSchedule
|
effect: NoSchedule
|
||||||
- key: node-role.kubernetes.io/control-plane #! The new name for these nodes as of Kubernetes 1.24.
|
- key: node-role.kubernetes.io/control-plane #! The new name for these nodes as of Kubernetes 1.24.
|
||||||
effect: NoSchedule
|
effect: NoSchedule
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: amd64 #! Allow running on amd64 nodes.
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: arm64 #! Also allow running on arm64 nodes.
|
|
||||||
#! This will help make sure our multiple pods run on different nodes, making
|
#! This will help make sure our multiple pods run on different nodes, making
|
||||||
#! our deployment "more" "HA".
|
#! our deployment "more" "HA".
|
||||||
affinity:
|
affinity:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -76,15 +76,6 @@ spec:
|
|||||||
#! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error.
|
#! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error.
|
||||||
seccompProfile:
|
seccompProfile:
|
||||||
type: "RuntimeDefault"
|
type: "RuntimeDefault"
|
||||||
tolerations:
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: amd64 #! Allow running on amd64 nodes.
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: arm64 #! Also allow running on arm64 nodes.
|
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -190,15 +190,6 @@ spec:
|
|||||||
- name: socket
|
- name: socket
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
#@ end
|
#@ end
|
||||||
tolerations:
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: amd64 #! Allow running on amd64 nodes.
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: arm64 #! Also allow running on arm64 nodes.
|
|
||||||
#! This will help make sure our multiple pods run on different nodes, making
|
#! This will help make sure our multiple pods run on different nodes, making
|
||||||
#! our deployment "more" "HA".
|
#! our deployment "more" "HA".
|
||||||
affinity:
|
affinity:
|
||||||
|
153
generated/1.21/README.adoc
generated
153
generated/1.21/README.adoc
generated
@ -197,7 +197,30 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | SelfLink is a URL representing this object. Populated by the system. Read-only.
|
||||||
|
DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +467,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +476,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +509,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxyservicetype[$$ImpersonationProxyServiceType$$]__ | Type specifies the type of Service to provision for the impersonation proxy. +
|
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +543,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
This field must be non-empty when spec.impersonationProxy.service.type is "None".
|
||||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +607,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +616,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +718,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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-21-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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-21-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +759,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +781,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +927,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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. +
|
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
||||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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. +
|
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +986,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1048,30 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | SelfLink is a URL representing this object. Populated by the system. Read-only.
|
||||||
|
DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1079,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1107,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1178,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1259,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1427,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-21-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
153
generated/1.22/README.adoc
generated
153
generated/1.22/README.adoc
generated
@ -197,7 +197,30 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | SelfLink is a URL representing this object. Populated by the system. Read-only.
|
||||||
|
DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +467,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +476,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +509,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxyservicetype[$$ImpersonationProxyServiceType$$]__ | Type specifies the type of Service to provision for the impersonation proxy. +
|
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +543,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
This field must be non-empty when spec.impersonationProxy.service.type is "None".
|
||||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +607,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +616,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +718,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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-22-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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-22-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +759,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +781,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +927,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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. +
|
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
||||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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. +
|
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +986,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1048,30 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | SelfLink is a URL representing this object. Populated by the system. Read-only.
|
||||||
|
DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1079,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1107,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1178,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1259,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1427,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-22-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
153
generated/1.23/README.adoc
generated
153
generated/1.23/README.adoc
generated
@ -197,7 +197,30 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | SelfLink is a URL representing this object. Populated by the system. Read-only.
|
||||||
|
DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +467,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +476,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +509,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxyservicetype[$$ImpersonationProxyServiceType$$]__ | Type specifies the type of Service to provision for the impersonation proxy. +
|
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +543,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
This field must be non-empty when spec.impersonationProxy.service.type is "None".
|
||||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +607,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +616,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +718,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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-23-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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-23-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +759,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +781,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +927,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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. +
|
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
||||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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. +
|
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +986,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1048,30 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | SelfLink is a URL representing this object. Populated by the system. Read-only.
|
||||||
|
DEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1079,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1107,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1178,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1259,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1427,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-23-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
153
generated/1.24/README.adoc
generated
153
generated/1.24/README.adoc
generated
@ -197,7 +197,30 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | Deprecated: ClusterName is a legacy field that was always cleared by the system and never used; it will be removed completely in 1.25.
|
||||||
|
The name in the go struct is changed to help clients detect accidental use.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +467,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +476,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +509,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxyservicetype[$$ImpersonationProxyServiceType$$]__ | Type specifies the type of Service to provision for the impersonation proxy. +
|
| *`type`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +543,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
This field must be non-empty when spec.impersonationProxy.service.type is "None".
|
||||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-impersonationproxytlsspec[$$ImpersonationProxyTLSSpec$$]__ | TLS contains information about how the Concierge impersonation proxy should serve TLS. +
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +607,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +616,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +718,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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-24-apis-supervisor-config-v1alpha1-federationdomaintlsspec[$$FederationDomainTLSSpec$$]__ | TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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-24-apis-supervisor-config-v1alpha1-federationdomainidentityprovider[$$FederationDomainIdentityProvider$$] array__ | IdentityProviders is the list of identity providers available for use by this FederationDomain. +
|
| *`identityProviders`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +759,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +781,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +927,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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. +
|
| *`allowedGrantTypes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
||||||
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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. +
|
| *`allowedScopes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +986,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1048,30 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`clusterName`* __string__ | Deprecated: ClusterName is a legacy field that was always cleared by the system and never used; it will be removed completely in 1.25.
|
||||||
|
The name in the go struct is changed to help clients detect accidental use.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1079,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1107,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1178,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1259,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1427,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-24-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
149
generated/1.25/README.adoc
generated
149
generated/1.25/README.adoc
generated
@ -197,7 +197,28 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +465,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +474,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +507,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| 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. +
|
| *`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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +541,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
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. +
|
| *`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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +605,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +614,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +716,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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.
|
| *`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. +
|
| *`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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +757,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +779,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +925,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`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. +
|
| *`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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. 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. +
|
| *`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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +984,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1046,28 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1075,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1103,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1174,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1255,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1423,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
4
generated/1.25/apis/go.mod
generated
4
generated/1.25/apis/go.mod
generated
@ -4,6 +4,6 @@ module go.pinniped.dev/generated/1.25/apis
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
k8s.io/api v0.25.14
|
k8s.io/api v0.25.13
|
||||||
k8s.io/apimachinery v0.25.14
|
k8s.io/apimachinery v0.25.13
|
||||||
)
|
)
|
||||||
|
8
generated/1.25/apis/go.sum
generated
8
generated/1.25/apis/go.sum
generated
@ -259,10 +259,10 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
k8s.io/api v0.25.14 h1:HoIR3IorzJkd0LPfCVq1Q3lRwij3+lZWJRmyp7YcL7o=
|
k8s.io/api v0.25.13 h1:nOQWK5/ngLIG2CqmVV7uTFDsPCGkDk4kIGJ26t2AwIo=
|
||||||
k8s.io/api v0.25.14/go.mod h1:goGtHI224Qh0tcHk8gOYPhTyCZNwQFwUMHsdabnSnSs=
|
k8s.io/api v0.25.13/go.mod h1:yGpHyrivZ0enqWqT5s1pN98a4Q834rZkIUEABpleEtw=
|
||||||
k8s.io/apimachinery v0.25.14 h1:SI5uE46G9GAvEHPGDcbiIaKTGHOX2anWKfBtI7/4ScQ=
|
k8s.io/apimachinery v0.25.13 h1:byRHkSinOOVdo0pvjdblauFYfwAnx+JB8Pqi9w9weik=
|
||||||
k8s.io/apimachinery v0.25.14/go.mod h1:IFwbcNi3gKkfDhuy0VYu3+BwbxbiIov3p6FR8ge1Epc=
|
k8s.io/apimachinery v0.25.13/go.mod h1:IFwbcNi3gKkfDhuy0VYu3+BwbxbiIov3p6FR8ge1Epc=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
4
generated/1.25/client/go.mod
generated
4
generated/1.25/client/go.mod
generated
@ -5,8 +5,8 @@ go 1.13
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
go.pinniped.dev/generated/1.25/apis v0.0.0
|
go.pinniped.dev/generated/1.25/apis v0.0.0
|
||||||
k8s.io/apimachinery v0.25.14
|
k8s.io/apimachinery v0.25.13
|
||||||
k8s.io/client-go v0.25.14
|
k8s.io/client-go v0.25.13
|
||||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1
|
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
12
generated/1.25/client/go.sum
generated
12
generated/1.25/client/go.sum
generated
@ -721,12 +721,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.25.14 h1:HoIR3IorzJkd0LPfCVq1Q3lRwij3+lZWJRmyp7YcL7o=
|
k8s.io/api v0.25.13 h1:nOQWK5/ngLIG2CqmVV7uTFDsPCGkDk4kIGJ26t2AwIo=
|
||||||
k8s.io/api v0.25.14/go.mod h1:goGtHI224Qh0tcHk8gOYPhTyCZNwQFwUMHsdabnSnSs=
|
k8s.io/api v0.25.13/go.mod h1:yGpHyrivZ0enqWqT5s1pN98a4Q834rZkIUEABpleEtw=
|
||||||
k8s.io/apimachinery v0.25.14 h1:SI5uE46G9GAvEHPGDcbiIaKTGHOX2anWKfBtI7/4ScQ=
|
k8s.io/apimachinery v0.25.13 h1:byRHkSinOOVdo0pvjdblauFYfwAnx+JB8Pqi9w9weik=
|
||||||
k8s.io/apimachinery v0.25.14/go.mod h1:IFwbcNi3gKkfDhuy0VYu3+BwbxbiIov3p6FR8ge1Epc=
|
k8s.io/apimachinery v0.25.13/go.mod h1:IFwbcNi3gKkfDhuy0VYu3+BwbxbiIov3p6FR8ge1Epc=
|
||||||
k8s.io/client-go v0.25.14 h1:/OdBAeSSlheFUb1i2SsWNo+LLyheJxDuQmWnWkzY4bc=
|
k8s.io/client-go v0.25.13 h1:Wan/8RXVNxSgFI/wMfWwJjmLglRYuLItytMWNiGo9LY=
|
||||||
k8s.io/client-go v0.25.14/go.mod h1:F3dMnLGu/iNIhYxVUsSen5WAIYM/DZPxDKZX/VYzZ7o=
|
k8s.io/client-go v0.25.13/go.mod h1:b2on3RSCwHdmvnUQx4/bkgMAs19M7BlUDze3WJuK0TE=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
149
generated/1.26/README.adoc
generated
149
generated/1.26/README.adoc
generated
@ -197,7 +197,28 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +465,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +474,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +507,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| 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. +
|
| *`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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +541,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
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. +
|
| *`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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +605,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +614,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +716,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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.
|
| *`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. +
|
| *`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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +757,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +779,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +925,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`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. +
|
| *`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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. 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. +
|
| *`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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +984,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1046,28 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1075,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1103,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1174,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1255,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1423,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
4
generated/1.26/apis/go.mod
generated
4
generated/1.26/apis/go.mod
generated
@ -4,6 +4,6 @@ module go.pinniped.dev/generated/1.26/apis
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
k8s.io/api v0.26.9
|
k8s.io/api v0.26.8
|
||||||
k8s.io/apimachinery v0.26.9
|
k8s.io/apimachinery v0.26.8
|
||||||
)
|
)
|
||||||
|
8
generated/1.26/apis/go.sum
generated
8
generated/1.26/apis/go.sum
generated
@ -270,10 +270,10 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
k8s.io/api v0.26.9 h1:s8Y+G1u2JM55b90+Yo2RVb3PGT/hkWNVPN4idPERxJg=
|
k8s.io/api v0.26.8 h1:k2OtFmQPWfDUyAuYAwQPftVygF/vz4BMGSKnd15iddM=
|
||||||
k8s.io/api v0.26.9/go.mod h1:W/W4fEWRVzPD36820LlVUQfNBiSbiq0VPWRFJKwzmUg=
|
k8s.io/api v0.26.8/go.mod h1:QaflR7cmG3V9lIz0VLBM+ylndNN897OAUAoJDcgwiQw=
|
||||||
k8s.io/apimachinery v0.26.9 h1:5yAV9cFR7Z4gIorKcAjWnx4uxtxiFsERwq4Pvmx0CCg=
|
k8s.io/apimachinery v0.26.8 h1:SzpGtRX3/j/Ylg8Eg65Iobpxi9Jz4vOvI0qcBZyPVrM=
|
||||||
k8s.io/apimachinery v0.26.9/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0=
|
k8s.io/apimachinery v0.26.8/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
4
generated/1.26/client/go.mod
generated
4
generated/1.26/client/go.mod
generated
@ -5,8 +5,8 @@ go 1.13
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
go.pinniped.dev/generated/1.26/apis v0.0.0
|
go.pinniped.dev/generated/1.26/apis v0.0.0
|
||||||
k8s.io/apimachinery v0.26.9
|
k8s.io/apimachinery v0.26.8
|
||||||
k8s.io/client-go v0.26.9
|
k8s.io/client-go v0.26.8
|
||||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280
|
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280
|
||||||
)
|
)
|
||||||
|
|
||||||
|
12
generated/1.26/client/go.sum
generated
12
generated/1.26/client/go.sum
generated
@ -564,12 +564,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.26.9 h1:s8Y+G1u2JM55b90+Yo2RVb3PGT/hkWNVPN4idPERxJg=
|
k8s.io/api v0.26.8 h1:k2OtFmQPWfDUyAuYAwQPftVygF/vz4BMGSKnd15iddM=
|
||||||
k8s.io/api v0.26.9/go.mod h1:W/W4fEWRVzPD36820LlVUQfNBiSbiq0VPWRFJKwzmUg=
|
k8s.io/api v0.26.8/go.mod h1:QaflR7cmG3V9lIz0VLBM+ylndNN897OAUAoJDcgwiQw=
|
||||||
k8s.io/apimachinery v0.26.9 h1:5yAV9cFR7Z4gIorKcAjWnx4uxtxiFsERwq4Pvmx0CCg=
|
k8s.io/apimachinery v0.26.8 h1:SzpGtRX3/j/Ylg8Eg65Iobpxi9Jz4vOvI0qcBZyPVrM=
|
||||||
k8s.io/apimachinery v0.26.9/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0=
|
k8s.io/apimachinery v0.26.8/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0=
|
||||||
k8s.io/client-go v0.26.9 h1:TGWi/6guEjIgT0Hg871Gsmx0qFuoGyGFjlFedrk7It0=
|
k8s.io/client-go v0.26.8 h1:pPuTYaVtLlg/7n6rqs3MsKLi4XgNaJ3rTMyS37Y5CKU=
|
||||||
k8s.io/client-go v0.26.9/go.mod h1:tU1FZS0bwAmAFyPYpZycUQrQnUMzQ5MHloop7EbX6ow=
|
k8s.io/client-go v0.26.8/go.mod h1:1sBQqKmdy9rWZYQnoedpc0gnRXG7kU3HrKZvBe2QbGM=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
149
generated/1.27/README.adoc
generated
149
generated/1.27/README.adoc
generated
@ -197,7 +197,28 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +465,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +474,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +507,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| 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. +
|
| *`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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +541,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
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. +
|
| *`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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +605,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +614,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +716,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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.
|
| *`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. +
|
| *`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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +757,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +779,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +925,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`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. +
|
| *`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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. 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. +
|
| *`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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +984,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1046,28 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1075,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1103,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1174,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1255,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1423,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
4
generated/1.27/apis/go.mod
generated
4
generated/1.27/apis/go.mod
generated
@ -4,6 +4,6 @@ module go.pinniped.dev/generated/1.27/apis
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
k8s.io/api v0.27.6
|
k8s.io/api v0.27.5
|
||||||
k8s.io/apimachinery v0.27.6
|
k8s.io/apimachinery v0.27.5
|
||||||
)
|
)
|
||||||
|
8
generated/1.27/apis/go.sum
generated
8
generated/1.27/apis/go.sum
generated
@ -301,10 +301,10 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
k8s.io/api v0.27.6 h1:PBWu/lywJe2qQcshMjubzcBg7+XDZOo7O8JJAWuYtUo=
|
k8s.io/api v0.27.5 h1:49hIzqJNSuOQpA53MMihgAS4YDcQitTy58B9PMFthLc=
|
||||||
k8s.io/api v0.27.6/go.mod h1:AQYj0UsFCp3qJE7bOVnUuy4orCsXVkvHefnbYQiNWgk=
|
k8s.io/api v0.27.5/go.mod h1:zjBZB+c0KDU55Wxb9Bob9WZGxu9zdKHitzHxBtaIVoA=
|
||||||
k8s.io/apimachinery v0.27.6 h1:mGU8jmBq5o8mWBov+mLjdTBcU+etTE19waies4AQ6NE=
|
k8s.io/apimachinery v0.27.5 h1:6Q5HBXYJJPisd6yDVAprLe6FQsmw7a7Cu69dcrpQET8=
|
||||||
k8s.io/apimachinery v0.27.6/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
k8s.io/apimachinery v0.27.5/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
4
generated/1.27/client/go.mod
generated
4
generated/1.27/client/go.mod
generated
@ -5,8 +5,8 @@ go 1.13
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
go.pinniped.dev/generated/1.27/apis v0.0.0
|
go.pinniped.dev/generated/1.27/apis v0.0.0
|
||||||
k8s.io/apimachinery v0.27.6
|
k8s.io/apimachinery v0.27.5
|
||||||
k8s.io/client-go v0.27.6
|
k8s.io/client-go v0.27.5
|
||||||
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f
|
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f
|
||||||
)
|
)
|
||||||
|
|
||||||
|
12
generated/1.27/client/go.sum
generated
12
generated/1.27/client/go.sum
generated
@ -594,12 +594,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.27.6 h1:PBWu/lywJe2qQcshMjubzcBg7+XDZOo7O8JJAWuYtUo=
|
k8s.io/api v0.27.5 h1:49hIzqJNSuOQpA53MMihgAS4YDcQitTy58B9PMFthLc=
|
||||||
k8s.io/api v0.27.6/go.mod h1:AQYj0UsFCp3qJE7bOVnUuy4orCsXVkvHefnbYQiNWgk=
|
k8s.io/api v0.27.5/go.mod h1:zjBZB+c0KDU55Wxb9Bob9WZGxu9zdKHitzHxBtaIVoA=
|
||||||
k8s.io/apimachinery v0.27.6 h1:mGU8jmBq5o8mWBov+mLjdTBcU+etTE19waies4AQ6NE=
|
k8s.io/apimachinery v0.27.5 h1:6Q5HBXYJJPisd6yDVAprLe6FQsmw7a7Cu69dcrpQET8=
|
||||||
k8s.io/apimachinery v0.27.6/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
k8s.io/apimachinery v0.27.5/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
||||||
k8s.io/client-go v0.27.6 h1:vzI8804gpUtpMCNaFjIFyJrifH7u//LJCJPy8fQuYQg=
|
k8s.io/client-go v0.27.5 h1:sH/fkqzk35kuf0GPx+dZuN7fhEswBSAVCrWFq3E1km0=
|
||||||
k8s.io/client-go v0.27.6/go.mod h1:PMsXcDKiJTW7PHJ64oEsIUJF319wm+EFlCj76oE5QXM=
|
k8s.io/client-go v0.27.5/go.mod h1:u+IKnqPZSPw51snIMKiIAV8LQQ+hya5bvxpOOPTUXPI=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
149
generated/1.28/README.adoc
generated
149
generated/1.28/README.adoc
generated
@ -197,7 +197,28 @@ OIDCClientSecretRequest can be used to update the client secrets associated with
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-clientsecret-oidcclientsecretrequestspec[$$OIDCClientSecretRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-clientsecret-oidcclientsecretrequeststatus[$$OIDCClientSecretRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -444,7 +465,7 @@ FrontendType enumerates a type of "frontend" used to provide access to users of
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxyinfo"]
|
||||||
==== ImpersonationProxyInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-struct-endpoint string -json-endpoint- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Endpoint string "json:\"endpoint\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== ImpersonationProxyInfo
|
||||||
|
|
||||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||||
|
|
||||||
@ -453,6 +474,12 @@ ImpersonationProxyInfo describes the parameters for the impersonation proxy on t
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`endpoint`* __string__ | Endpoint is the HTTPS endpoint of the impersonation proxy.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded PEM CA bundle of the impersonation proxy.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxymode"]
|
||||||
@ -480,8 +507,7 @@ ImpersonationProxyServiceSpec describes how the Concierge should provision a Ser
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| 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. +
|
| *`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.
|
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||||
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
| *`loadBalancerIP`* __string__ | LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service. This is not supported on all cloud providers.
|
||||||
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations specifies zero or more key/value pairs to set as annotations on the provisioned Service.
|
||||||
@ -515,11 +541,9 @@ ImpersonationProxySpec describes the intended configuration of the Concierge imp
|
|||||||
| Field | Description
|
| Field | Description
|
||||||
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
| *`mode`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxymode[$$ImpersonationProxyMode$$]__ | Mode configures whether the impersonation proxy should be started: - "disabled" explicitly disables the impersonation proxy. This is the default. - "enabled" explicitly enables the impersonation proxy. - "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||||
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
| *`service`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-impersonationproxyservicespec[$$ImpersonationProxyServiceSpec$$]__ | Service describes the configuration of the Service provisioned to expose the impersonation proxy to clients.
|
||||||
| *`externalEndpoint`* __string__ | ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will be served using the external name of the LoadBalancer service or the cluster service DNS name. +
|
| *`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".
|
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. +
|
| *`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.
|
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -581,7 +605,7 @@ StrategyType enumerates a type of "strategy" used to implement credential access
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-tokencredentialrequestapiinfo"]
|
||||||
==== TokenCredentialRequestAPIInfo (xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-struct-server string -json-server- certificateauthoritydata string -json-certificateauthoritydata-[$$struct{Server string "json:\"server\""; CertificateAuthorityData string "json:\"certificateAuthorityData\""}$$])
|
==== TokenCredentialRequestAPIInfo
|
||||||
|
|
||||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||||
|
|
||||||
@ -590,6 +614,12 @@ TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRe
|
|||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerfrontend[$$CredentialIssuerFrontend$$]
|
||||||
****
|
****
|
||||||
|
|
||||||
|
[cols="25a,75a", options="header"]
|
||||||
|
|===
|
||||||
|
| Field | Description
|
||||||
|
| *`server`* __string__ | Server is the Kubernetes API server URL.
|
||||||
|
| *`certificateAuthorityData`* __string__ | CertificateAuthorityData is the base64-encoded Kubernetes API server CA bundle.
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +716,11 @@ FederationDomainSpec is a struct that describes an OIDC Provider.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is https://example.com/foo, then your authorization endpoint will look like https://example.com/foo/some/path/to/auth/endpoint). +
|
| *`issuer`* __string__ | Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the identifier that it will use for the iss claim in issued JWTs. This field will also be used as the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is 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.
|
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.
|
| *`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. +
|
| *`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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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.
|
||||||
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. In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid accidental conflicts when multiple identity providers have different users with the same username (e.g. "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow 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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
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 provider currently defined. In this backwards compatibility mode, the name of the identity provider resource (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead explicitly list the identity provider using this IdentityProviders field.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -730,14 +757,10 @@ FederationDomainTLSSpec is a struct that describes the TLS configuration for an
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS. +
|
| *`secretName`* __string__ | SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS.
|
||||||
|
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||||
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.
|
||||||
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.
|
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -756,12 +779,9 @@ FederationDomainTransforms defines identity transformations for an identity prov
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
| *`constants`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomaintransformsconstant[$$FederationDomainTransformsConstant$$] array__ | Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||||
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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. +
|
| *`expressions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomaintransformsexpression[$$FederationDomainTransformsExpression$$] array__ | Expressions are an optional list of transforms and policies to be executed in the order given during every authentication attempt, including during every session refresh. 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 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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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.
|
||||||
|
|
||||||
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. Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the username or group names. Each username/v1 transform must return the new username (a string), which can be the same as the old username. Transformations of type username/v1 do not return group names, and therefore cannot change the group names. Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old 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 and group names have been decided for that authentication attempt.
|
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 and group names have been decided for that authentication attempt.
|
||||||
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
| *`examples`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-federationdomaintransformsexample[$$FederationDomainTransformsExample$$] array__ | Examples can optionally be used to ensure that the sequence of transformation expressions are working as expected. Examples define sample input identities which are then run through the expression list, and the results are compared to the expected results. If any example in this list fails, then this identity provider will not be available for use within this FederationDomain, and the error(s) will be added to the FederationDomain status. This can be used to help guard against programming mistakes in the expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||||
|===
|
|===
|
||||||
@ -905,11 +925,9 @@ OIDCClientSpec is a struct that describes an OIDCClient.
|
|||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
| *`allowedRedirectURIs`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-config-v1alpha1-redirecturi[$$RedirectURI$$] array__ | allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this client. Any other uris will be rejected. Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme. Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
| *`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. +
|
| *`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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. This grant must be listed if allowedScopes lists pinniped:request-audience.
|
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. - refresh_token: allows the client to perform refresh grants for the user to extend the user's session. This grant must be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. 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. +
|
| *`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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
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. - offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow. This scope must be listed if allowedGrantTypes lists refresh_token. - pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange, which is a step in the process to be able to get a cluster credential for the user. openid, username and groups scopes must be listed when this scope is present. This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange. - username: The client is allowed to request that ID tokens contain the user's username. Without the username scope being requested and allowed, the ID token will not contain the user's username. - groups: The client is allowed to request that ID tokens contain the user's group membership, if their group membership is discoverable by the Supervisor. Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -966,7 +984,7 @@ Package identity is the internal version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1028,7 +1046,28 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
[cols="25a,75a", options="header"]
|
[cols="25a,75a", options="header"]
|
||||||
|===
|
|===
|
||||||
| Field | Description
|
| Field | Description
|
||||||
| *`ObjectMeta`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#objectmeta-v1-meta[$$ObjectMeta$$]__ |
|
| *`name`* __string__ | Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
|
||||||
|
| *`generateName`* __string__ | GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.
|
||||||
|
If this field is specified and the generated name exists, the server will return a 409.
|
||||||
|
Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
|
||||||
|
| *`namespace`* __string__ | Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.
|
||||||
|
Must be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces
|
||||||
|
| *`selfLink`* __string__ | Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.
|
||||||
|
| *`uid`* __UID__ | UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.
|
||||||
|
Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
|
||||||
|
| *`resourceVersion`* __string__ | An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.
|
||||||
|
Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||||
|
| *`generation`* __integer__ | A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.
|
||||||
|
| *`creationTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#time-v1-meta[$$Time$$]__ | CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.
|
||||||
|
Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionTimestamp`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#time-v1-meta[$$Time$$]__ | DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.
|
||||||
|
Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
| *`deletionGracePeriodSeconds`* __integer__ | Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.
|
||||||
|
| *`labels`* __object (keys:string, values:string)__ | Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
|
||||||
|
| *`annotations`* __object (keys:string, values:string)__ | Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations
|
||||||
|
| *`ownerReferences`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#ownerreference-v1-meta[$$OwnerReference$$] array__ | List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.
|
||||||
|
| *`finalizers`* __string array__ | Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.
|
||||||
|
| *`managedFields`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#managedfieldsentry-v1-meta[$$ManagedFieldsEntry$$] array__ | ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.
|
||||||
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
| *`Spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequestspec[$$WhoAmIRequestSpec$$]__ |
|
||||||
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
| *`Status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequeststatus[$$WhoAmIRequestStatus$$]__ |
|
||||||
|===
|
|===
|
||||||
@ -1036,16 +1075,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-whoamirequeststatus"]
|
||||||
@ -1074,7 +1103,7 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
|||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-v1alpha1-extravalue"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-v1alpha1-extravalue"]
|
||||||
==== ExtraValue (string array)
|
==== ExtraValue
|
||||||
|
|
||||||
ExtraValue masks the value so protobuf can generate
|
ExtraValue masks the value so protobuf can generate
|
||||||
|
|
||||||
@ -1145,16 +1174,6 @@ WhoAmIRequest submits a request to echo back the current authenticated user.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-v1alpha1-whoamirequestspec"]
|
|
||||||
==== WhoAmIRequestSpec
|
|
||||||
|
|
||||||
Spec is always empty for a WhoAmIRequest.
|
|
||||||
|
|
||||||
.Appears In:
|
|
||||||
****
|
|
||||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-v1alpha1-whoamirequest[$$WhoAmIRequest$$]
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-identity-v1alpha1-whoamirequeststatus"]
|
||||||
@ -1236,12 +1255,9 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
|||||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@ -1407,12 +1423,9 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
|||||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the value of an attribute of the user entry found as a result of the user search. Which attribute's value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter. For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||||
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
| *`userAttributeForFilter`* __string__ | UserAttributeForFilter specifies which attribute's value from the user entry found as a result of the user search will be used to replace the "{}" placeholder(s) in the group search Filter. For example, specifying "uid" as the UserAttributeForFilter while specifying "&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing the "{}" placeholder in the Filter with the value of the user's "uid" attribute. Optional. When not specified, the default will act as if "dn" were specified. For example, leaving UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider. +
|
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||||
|
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||||
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.
|
||||||
|
|
||||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login. +
|
|
||||||
|
|
||||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
4
generated/1.28/apis/go.mod
generated
4
generated/1.28/apis/go.mod
generated
@ -4,6 +4,6 @@ module go.pinniped.dev/generated/1.28/apis
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
k8s.io/api v0.28.2
|
k8s.io/api v0.28.1
|
||||||
k8s.io/apimachinery v0.28.2
|
k8s.io/apimachinery v0.28.1
|
||||||
)
|
)
|
||||||
|
10
generated/1.28/apis/go.sum
generated
10
generated/1.28/apis/go.sum
generated
@ -9,7 +9,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
@ -277,10 +277,10 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
|
k8s.io/api v0.28.1 h1:i+0O8k2NPBCPYaMB+uCkseEbawEt/eFaiRqUx8aB108=
|
||||||
k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg=
|
k8s.io/api v0.28.1/go.mod h1:uBYwID+66wiL28Kn2tBjBYQdEU0Xk0z5qF8bIBqk/Dg=
|
||||||
k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
|
k8s.io/apimachinery v0.28.1 h1:EJD40og3GizBSV3mkIoXQBsws32okPOy+MkRyzh6nPY=
|
||||||
k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU=
|
k8s.io/apimachinery v0.28.1/go.mod h1:X0xh/chESs2hP9koe+SdIAcXWcQ+RM5hy0ZynB+yEvw=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
4
generated/1.28/client/go.mod
generated
4
generated/1.28/client/go.mod
generated
@ -5,8 +5,8 @@ go 1.13
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
go.pinniped.dev/generated/1.28/apis v0.0.0
|
go.pinniped.dev/generated/1.28/apis v0.0.0
|
||||||
k8s.io/apimachinery v0.28.2
|
k8s.io/apimachinery v0.28.1
|
||||||
k8s.io/client-go v0.28.2
|
k8s.io/client-go v0.28.1
|
||||||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9
|
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9
|
||||||
)
|
)
|
||||||
|
|
||||||
|
16
generated/1.28/client/go.sum
generated
16
generated/1.28/client/go.sum
generated
@ -12,8 +12,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
|
github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
|
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
@ -316,12 +316,12 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
|
k8s.io/api v0.28.1 h1:i+0O8k2NPBCPYaMB+uCkseEbawEt/eFaiRqUx8aB108=
|
||||||
k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg=
|
k8s.io/api v0.28.1/go.mod h1:uBYwID+66wiL28Kn2tBjBYQdEU0Xk0z5qF8bIBqk/Dg=
|
||||||
k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
|
k8s.io/apimachinery v0.28.1 h1:EJD40og3GizBSV3mkIoXQBsws32okPOy+MkRyzh6nPY=
|
||||||
k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU=
|
k8s.io/apimachinery v0.28.1/go.mod h1:X0xh/chESs2hP9koe+SdIAcXWcQ+RM5hy0ZynB+yEvw=
|
||||||
k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY=
|
k8s.io/client-go v0.28.1 h1:pRhMzB8HyLfVwpngWKE8hDcXRqifh1ga2Z/PU9SXVK8=
|
||||||
k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY=
|
k8s.io/client-go v0.28.1/go.mod h1:pEZA3FqOsVkCc07pFVzK076R+P/eXqsgx5zuuRWukNE=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
56
go.mod
56
go.mod
@ -10,23 +10,23 @@ replace k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230717233707-2695361
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
||||||
github.com/chromedp/cdproto v0.0.0-20231025043423-5615e204d422
|
github.com/chromedp/cdproto v0.0.0-20230914224007-a15a36ccbc2e
|
||||||
github.com/chromedp/chromedp v0.9.3
|
github.com/chromedp/chromedp v0.9.2
|
||||||
github.com/coreos/go-oidc/v3 v3.7.0
|
github.com/coreos/go-oidc/v3 v3.6.0
|
||||||
github.com/coreos/go-semver v0.3.1
|
github.com/coreos/go-semver v0.3.1
|
||||||
github.com/creack/pty v1.1.20
|
github.com/creack/pty v1.1.18
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/felixge/httpsnoop v1.0.3
|
github.com/felixge/httpsnoop v1.0.3
|
||||||
github.com/go-ldap/ldap/v3 v3.4.6
|
github.com/go-ldap/ldap/v3 v3.4.6
|
||||||
github.com/go-logr/logr v1.3.0
|
github.com/go-logr/logr v1.2.4
|
||||||
github.com/go-logr/stdr v1.2.2
|
github.com/go-logr/stdr v1.2.2
|
||||||
github.com/go-logr/zapr v1.2.4
|
github.com/go-logr/zapr v1.2.4
|
||||||
github.com/gofrs/flock v0.8.1
|
github.com/gofrs/flock v0.8.1
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/google/cel-go v0.18.1
|
github.com/google/cel-go v0.18.1
|
||||||
github.com/google/go-cmp v0.6.0
|
github.com/google/go-cmp v0.5.9
|
||||||
github.com/google/gofuzz v1.2.0
|
github.com/google/gofuzz v1.2.0
|
||||||
github.com/google/uuid v1.4.0
|
github.com/google/uuid v1.3.1
|
||||||
github.com/gorilla/securecookie v1.1.1
|
github.com/gorilla/securecookie v1.1.1
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531
|
github.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531
|
||||||
@ -38,27 +38,27 @@ require (
|
|||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/tdewolff/minify/v2 v2.20.1
|
github.com/tdewolff/minify/v2 v2.12.9
|
||||||
go.uber.org/zap v1.26.0
|
go.uber.org/zap v1.26.0
|
||||||
golang.org/x/crypto v0.14.0
|
golang.org/x/crypto v0.13.0
|
||||||
golang.org/x/net v0.17.0
|
golang.org/x/net v0.15.0
|
||||||
golang.org/x/oauth2 v0.13.0
|
golang.org/x/oauth2 v0.12.0
|
||||||
golang.org/x/sync v0.4.0
|
golang.org/x/sync v0.3.0
|
||||||
golang.org/x/term v0.13.0
|
golang.org/x/term v0.12.0
|
||||||
golang.org/x/text v0.13.0
|
golang.org/x/text v0.13.0
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0
|
gopkg.in/square/go-jose.v2 v2.6.0
|
||||||
k8s.io/api v0.28.3
|
k8s.io/api v0.28.2
|
||||||
k8s.io/apiextensions-apiserver v0.28.3
|
k8s.io/apiextensions-apiserver v0.28.2
|
||||||
k8s.io/apimachinery v0.28.3
|
k8s.io/apimachinery v0.28.2
|
||||||
k8s.io/apiserver v0.28.3
|
k8s.io/apiserver v0.28.2
|
||||||
k8s.io/client-go v0.28.3
|
k8s.io/client-go v0.28.2
|
||||||
k8s.io/component-base v0.28.3
|
k8s.io/component-base v0.28.2
|
||||||
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01
|
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01
|
||||||
k8s.io/klog/v2 v2.100.1
|
k8s.io/klog/v2 v2.100.1
|
||||||
k8s.io/kube-aggregator v0.28.3
|
k8s.io/kube-aggregator v0.28.2
|
||||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00
|
k8s.io/kube-openapi v0.0.0-20230928205116-a78145627833
|
||||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
|
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@ -81,7 +81,7 @@ require (
|
|||||||
github.com/ecordell/optgen v0.0.6 // indirect
|
github.com/ecordell/optgen v0.0.6 // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
||||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
|
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
|
||||||
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
|
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||||
@ -89,7 +89,7 @@ require (
|
|||||||
github.com/go-openapi/swag v0.22.3 // indirect
|
github.com/go-openapi/swag v0.22.3 // indirect
|
||||||
github.com/gobwas/httphead v0.1.0 // indirect
|
github.com/gobwas/httphead v0.1.0 // indirect
|
||||||
github.com/gobwas/pool v0.2.1 // indirect
|
github.com/gobwas/pool v0.2.1 // indirect
|
||||||
github.com/gobwas/ws v1.3.0 // indirect
|
github.com/gobwas/ws v1.2.1 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/glog v1.1.0 // indirect
|
github.com/golang/glog v1.1.0 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
@ -132,7 +132,7 @@ require (
|
|||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||||
github.com/subosito/gotenv v1.4.0 // indirect
|
github.com/subosito/gotenv v1.4.0 // indirect
|
||||||
github.com/tdewolff/parse/v2 v2.7.1 // indirect
|
github.com/tdewolff/parse/v2 v2.6.8 // indirect
|
||||||
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
|
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
|
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
|
||||||
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
|
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
|
||||||
@ -149,10 +149,10 @@ require (
|
|||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
|
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
|
||||||
golang.org/x/mod v0.10.0 // indirect
|
golang.org/x/mod v0.10.0 // indirect
|
||||||
golang.org/x/sys v0.13.0 // indirect
|
golang.org/x/sys v0.12.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.8.0 // indirect
|
golang.org/x/tools v0.8.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect
|
google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||||
@ -163,7 +163,7 @@ require (
|
|||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/kms v0.28.3 // indirect
|
k8s.io/kms v0.28.2 // indirect
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||||
|
109
go.sum
109
go.sum
@ -73,11 +73,11 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
|||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chromedp/cdproto v0.0.0-20231011050154-1d073bb38998/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
||||||
github.com/chromedp/cdproto v0.0.0-20231025043423-5615e204d422 h1:9d05eR3+VAcQqH5qiKbpMFa83XFK7jVDfAXIindFPbU=
|
github.com/chromedp/cdproto v0.0.0-20230914224007-a15a36ccbc2e h1:BfDqq+EHA0HP037qWakDtYxIg9erpn2aZfZlrtnB35E=
|
||||||
github.com/chromedp/cdproto v0.0.0-20231025043423-5615e204d422/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
github.com/chromedp/cdproto v0.0.0-20230914224007-a15a36ccbc2e/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
||||||
github.com/chromedp/chromedp v0.9.3 h1:Wq58e0dZOdHsxaj9Owmfcf+ibtpYN1N0FWVbaxa/esg=
|
github.com/chromedp/chromedp v0.9.2 h1:dKtNz4kApb06KuSXoTQIyUC2TrA0fhGDwNZf3bcgfKw=
|
||||||
github.com/chromedp/chromedp v0.9.3/go.mod h1:NipeUkUcuzIdFbBP8eNNvl9upcceOfWzoJn6cRe4ksA=
|
github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=
|
||||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
@ -97,8 +97,8 @@ github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE
|
|||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||||
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||||
github.com/coreos/go-oidc/v3 v3.7.0 h1:FTdj0uexT4diYIPlF4yoFVI5MRO1r5+SEcIpEw9vC0o=
|
github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o=
|
||||||
github.com/coreos/go-oidc/v3 v3.7.0/go.mod h1:yQzSCqBnK3e6Fs5l+f5i0F8Kwf0zpH9bPEsbY00KanM=
|
github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc=
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||||
@ -110,8 +110,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/creack/pty v1.1.20 h1:VIPb/a2s17qNeQgDnkfZC35RScx+blkKF8GV68n80J4=
|
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||||
github.com/creack/pty v1.1.20/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||||
github.com/cristalhq/jwt/v4 v4.0.2 h1:g/AD3h0VicDamtlM70GWGElp8kssQEv+5wYd7L9WOhU=
|
github.com/cristalhq/jwt/v4 v4.0.2 h1:g/AD3h0VicDamtlM70GWGElp8kssQEv+5wYd7L9WOhU=
|
||||||
github.com/cristalhq/jwt/v4 v4.0.2/go.mod h1:HnYraSNKDRag1DZP92rYHyrjyQHnVEHPNqesmzs+miQ=
|
github.com/cristalhq/jwt/v4 v4.0.2/go.mod h1:HnYraSNKDRag1DZP92rYHyrjyQHnVEHPNqesmzs+miQ=
|
||||||
github.com/dave/jennifer v1.4.0 h1:tNJFJmLDVTLu+v05mVZ88RINa3vQqnyyWkTKWYz0CwE=
|
github.com/dave/jennifer v1.4.0 h1:tNJFJmLDVTLu+v05mVZ88RINa3vQqnyyWkTKWYz0CwE=
|
||||||
@ -150,8 +150,8 @@ github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
|||||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
|
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||||
@ -168,9 +168,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
|||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
|
||||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
|
github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
|
||||||
@ -187,8 +186,8 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU
|
|||||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
github.com/gobwas/ws v1.3.0 h1:sbeU3Y4Qzlb+MOzIe6mQGf7QR4Hkv6ZD0qhGkBFL2O0=
|
github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk=
|
||||||
github.com/gobwas/ws v1.3.0/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
|
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
@ -252,9 +251,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
@ -277,9 +275,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
|||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
|
||||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||||
@ -482,12 +479,12 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
|
|||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
|
github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
|
||||||
github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
|
github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
|
||||||
github.com/tdewolff/minify/v2 v2.20.1 h1:ARmlyj4gJYXNrPtdatTR9gMusp3AciwZA5o/qYtFbow=
|
github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA=
|
||||||
github.com/tdewolff/minify/v2 v2.20.1/go.mod h1:spLa6hfzR2CXXPV92kcHpziPsOobxB7IFov+8k5l5NY=
|
github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU=
|
||||||
github.com/tdewolff/parse/v2 v2.7.1 h1:gdImkv0sIupYr/cXAu5s+CxfVpxMdYZX2Qr+5Q+RdF8=
|
github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA=
|
||||||
github.com/tdewolff/parse/v2 v2.7.1/go.mod h1:9p2qMIHpjRSTr1qnFxQr+igogyTUTlwvf9awHSm84h8=
|
github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM=
|
||||||
github.com/tdewolff/test v1.0.10 h1:uWiheaLgLcNFqHcdWveum7PQfMnIUTf9Kl3bFxrIoew=
|
github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0=
|
||||||
github.com/tdewolff/test v1.0.10/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
@ -562,9 +559,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
|||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
|
||||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -643,8 +639,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
|||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -655,8 +651,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ
|
|||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
|
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
||||||
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
|
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -670,8 +666,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -717,19 +713,18 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
||||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
|
||||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -738,7 +733,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
@ -836,9 +830,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
|||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
|
||||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
@ -958,27 +951,27 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
|
k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
|
||||||
k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc=
|
k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg=
|
||||||
k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
|
k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU=
|
||||||
k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
|
k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg=
|
||||||
k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A=
|
k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
|
||||||
k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8=
|
k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU=
|
||||||
k8s.io/apiserver v0.28.3 h1:8Ov47O1cMyeDzTXz0rwcfIIGAP/dP7L8rWbEljRcg5w=
|
k8s.io/apiserver v0.28.2 h1:rBeYkLvF94Nku9XfXyUIirsVzCzJBs6jMn3NWeHieyI=
|
||||||
k8s.io/apiserver v0.28.3/go.mod h1:YIpM+9wngNAv8Ctt0rHG4vQuX/I5rvkEMtZtsxW2rNM=
|
k8s.io/apiserver v0.28.2/go.mod h1:f7D5e8wH8MWcKD7azq6Csw9UN+CjdtXIVQUyUhrtb+E=
|
||||||
k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4=
|
k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY=
|
||||||
k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo=
|
k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY=
|
||||||
k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI=
|
k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E=
|
||||||
k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8=
|
k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc=
|
||||||
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks=
|
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks=
|
||||||
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||||
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||||
k8s.io/kms v0.28.3 h1:jYwwAe96XELNjYWv1G4kNzizcFoZ50OOElvPansbw70=
|
k8s.io/kms v0.28.2 h1:KhG63LHopCdzs1oKA1j+NWleuIXudgOyCqJo4yi3GaM=
|
||||||
k8s.io/kms v0.28.3/go.mod h1:kSMjU2tg7vjqqoWVVCcmPmNZ/CofPsoTbSxAipCvZuE=
|
k8s.io/kms v0.28.2/go.mod h1:iAjgIqBrV2+8kmsjbbgUkAyKSuYq5g1dW9knpt6OhaE=
|
||||||
k8s.io/kube-aggregator v0.28.3 h1:CVbj3+cpshSHR5dWPzLYx3sVpIDEPLlzMSxY/lAc9cM=
|
k8s.io/kube-aggregator v0.28.2 h1:tCjAfB1p/v18yD2NpegNQRuahzyA/szFfcRARnpjDeo=
|
||||||
k8s.io/kube-aggregator v0.28.3/go.mod h1:5DyLevbRTcWnT1f9b+lB3BfbXC1w7gDa/OtB6kKInCw=
|
k8s.io/kube-aggregator v0.28.2/go.mod h1:g4hZVjC4KhJtZHV2pyiRBiU6AdBA/sAjh9Y9GJC/SbU=
|
||||||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
|
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
|
||||||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
|
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
|
||||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
||||||
@ -993,5 +986,5 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h6
|
|||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||||
|
@ -15,30 +15,22 @@
|
|||||||
# hidden behind a `GOEXPERIMENT=boringcrypto` env var.
|
# hidden behind a `GOEXPERIMENT=boringcrypto` env var.
|
||||||
# See https://go.googlesource.com/go/+/dev.boringcrypto/README.boringcrypto.md
|
# See https://go.googlesource.com/go/+/dev.boringcrypto/README.boringcrypto.md
|
||||||
# and https://kupczynski.info/posts/fips-golang/ for details.
|
# and https://kupczynski.info/posts/fips-golang/ for details.
|
||||||
|
FROM golang:1.21.1 as build-env
|
||||||
# This is not currently using --platform to prepare to cross-compile because we use gcc below to build
|
|
||||||
# platform-specific GCO code. This makes multi-arch builds slow due to target platform emulation.
|
|
||||||
FROM golang:1.21.3 as build-env
|
|
||||||
|
|
||||||
WORKDIR /work
|
WORKDIR /work
|
||||||
|
COPY . .
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
|
|
||||||
ARG KUBE_GIT_VERSION
|
|
||||||
ENV KUBE_GIT_VERSION=$KUBE_GIT_VERSION
|
|
||||||
|
|
||||||
# These will be set by buildkit automatically, e.g. TARGETOS set to "linux" and TARGETARCH set to "amd64" or "arm64".
|
|
||||||
# Useful for building multi-arch container images.
|
|
||||||
ARG TARGETOS
|
|
||||||
ARG TARGETARCH
|
|
||||||
|
|
||||||
# Build the executable binary (CGO_ENABLED=1 is required for go boring).
|
# Build the executable binary (CGO_ENABLED=1 is required for go boring).
|
||||||
# Even though we need cgo to call the boring crypto C functions, these
|
# Even though we need cgo to call the boring crypto C functions, these
|
||||||
# functions are statically linked into the binary. We also want to statically
|
# functions are statically linked into the binary. We also want to statically
|
||||||
# link any libc bits hence we pass "-linkmode=external -extldflags -static"
|
# link any libc bits hence we pass "-linkmode=external -extldflags -static"
|
||||||
# to the ldflags directive. We do not pass "-s" to ldflags because we do
|
# to the ldflags directive. We do not pass "-s" to ldflags because we do
|
||||||
# not want to strip symbols - those are used to verify if we compiled correctly.
|
# not want to strip symbols - those are used to verify if we compiled correctly.
|
||||||
# Since we use gcc as the C compiler, the following warning is emitted:
|
# We do not pass in GOCACHE (build cache) and GOMODCACHE (module cache)
|
||||||
|
# because there have been bugs in the Go compiler caching when using cgo
|
||||||
|
# (it will sometimes use cached artifiacts when it should not). Since we
|
||||||
|
# use gcc as the C compiler, the following warning is emitted:
|
||||||
# /boring/boringssl/build/../crypto/bio/socket_helper.c:55: warning:
|
# /boring/boringssl/build/../crypto/bio/socket_helper.c:55: warning:
|
||||||
# Using 'getaddrinfo' in statically linked applications requires at
|
# Using 'getaddrinfo' in statically linked applications requires at
|
||||||
# runtime the shared libraries from the glibc version used for linking
|
# runtime the shared libraries from the glibc version used for linking
|
||||||
@ -51,11 +43,13 @@ ARG TARGETARCH
|
|||||||
# The osusergo and netgo tags are used to make sure that the Go implementations of these
|
# The osusergo and netgo tags are used to make sure that the Go implementations of these
|
||||||
# standard library packages are used instead of the libc based versions.
|
# standard library packages are used instead of the libc based versions.
|
||||||
# We want to have no reliance on any C code other than the boring crypto bits.
|
# We want to have no reliance on any C code other than the boring crypto bits.
|
||||||
|
# Setting GOOS=linux GOARCH=amd64 is a hard requirment for boring crypto:
|
||||||
|
# https://github.com/golang/go/blob/9d6ab825f6fe125f7ce630e103b887e580403802/misc/boring/README.md?plain=1#L95
|
||||||
|
# Thus trying to compile the pinniped CLI with boring crypto is meaningless
|
||||||
|
# since we would not be able to ship windows and macOS binaries.
|
||||||
RUN \
|
RUN \
|
||||||
--mount=target=. \
|
mkdir out && \
|
||||||
--mount=type=cache,target=/cache/gocache \
|
export CGO_ENABLED=1 GOOS=linux GOARCH=amd64 GOEXPERIMENT=boringcrypto && \
|
||||||
--mount=type=cache,target=/cache/gomodcache \
|
|
||||||
export GOCACHE=/cache/gocache GOMODCACHE=/cache/gomodcache CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH GOEXPERIMENT=boringcrypto && \
|
|
||||||
go build -tags fips_strict,osusergo,netgo -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -linkmode=external -extldflags -static" -o /usr/local/bin/pinniped-concierge-kube-cert-agent ./cmd/pinniped-concierge-kube-cert-agent/... && \
|
go build -tags fips_strict,osusergo,netgo -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -linkmode=external -extldflags -static" -o /usr/local/bin/pinniped-concierge-kube-cert-agent ./cmd/pinniped-concierge-kube-cert-agent/... && \
|
||||||
go build -tags fips_strict,osusergo,netgo -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -linkmode=external -extldflags -static" -o /usr/local/bin/pinniped-server ./cmd/pinniped-server/... && \
|
go build -tags fips_strict,osusergo,netgo -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -linkmode=external -extldflags -static" -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-concierge && \
|
||||||
@ -63,9 +57,6 @@ RUN \
|
|||||||
ln -s /usr/local/bin/pinniped-server /usr/local/bin/local-user-authenticator
|
ln -s /usr/local/bin/pinniped-server /usr/local/bin/local-user-authenticator
|
||||||
|
|
||||||
# Use a distroless runtime image with CA certificates, timezone data, and not much else.
|
# Use a distroless runtime image with CA certificates, timezone data, and not much else.
|
||||||
# Note that we are not using --platform here, so it will choose the base image for the target platform, not the build platform.
|
|
||||||
# By using "distroless/static" instead of "distroless/static-debianXX" we can float on the latest stable version of debian.
|
|
||||||
# See https://github.com/GoogleContainerTools/distroless#base-operating-system
|
|
||||||
FROM gcr.io/distroless/static:nonroot@sha256:2a9e2b4fa771d31fe3346a873be845bfc2159695b9f90ca08e950497006ccc2e
|
FROM gcr.io/distroless/static:nonroot@sha256:2a9e2b4fa771d31fe3346a873be845bfc2159695b9f90ca08e950497006ccc2e
|
||||||
|
|
||||||
# Copy the server binary from the build-env stage.
|
# Copy the server binary from the build-env stage.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
1.28.2
|
1.28.1
|
||||||
1.27.6
|
1.27.5
|
||||||
1.26.9
|
1.26.8
|
||||||
1.25.14
|
1.25.13
|
||||||
1.24.17
|
1.24.17
|
||||||
1.23.17
|
1.23.17
|
||||||
1.22.17
|
1.22.17
|
||||||
|
@ -484,6 +484,7 @@ PINNIPED_TEST_CLUSTER_CAPABILITY_YAML_EOF
|
|||||||
export PINNIPED_TEST_CLUSTER_CAPABILITY_YAML
|
export PINNIPED_TEST_CLUSTER_CAPABILITY_YAML
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Print instructions for next steps.
|
# Print instructions for next steps.
|
||||||
#
|
#
|
||||||
|
@ -442,11 +442,8 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Test that the federation domain is working before we proceed.
|
# Test that the federation domain is working before we proceed.
|
||||||
echo "Fetching FederationDomain discovery info via command:" \
|
echo "Fetching FederationDomain discovery info via command: ${proxy_env_vars}curl -fLsS --cacert \"$root_ca_crt_path\" \"$issuer/.well-known/openid-configuration\""
|
||||||
"${proxy_env_vars}curl -fLsS --retry-all-errors --retry 5 --cacert \"$root_ca_crt_path\" \"$issuer/.well-known/openid-configuration\""
|
https_proxy="$proxy_server" no_proxy="$proxy_except" curl -fLsS --cacert "$root_ca_crt_path" "$issuer/.well-known/openid-configuration" | jq .
|
||||||
https_proxy="$proxy_server" no_proxy="$proxy_except" curl -fLsS \
|
|
||||||
--retry-all-errors --retry 5 --cacert "$root_ca_crt_path" \
|
|
||||||
"$issuer/.well-known/openid-configuration" | jq .
|
|
||||||
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
certificateAuthorityData=$(cat "$root_ca_crt_path" | base64)
|
certificateAuthorityData=$(cat "$root_ca_crt_path" | base64)
|
||||||
|
@ -2,4 +2,4 @@ module go.pinniped.dev/update-go-mod
|
|||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require golang.org/x/mod v0.13.0
|
require golang.org/x/mod v0.12.0
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
@ -89,19 +89,6 @@ func NewHandler(
|
|||||||
// oidcapi.AuthorizeUpstreamIDPTypeParamName query (or form) params to request a certain upstream IDP.
|
// oidcapi.AuthorizeUpstreamIDPTypeParamName query (or form) params to request a certain upstream IDP.
|
||||||
// The Pinniped CLI has been sending these params since v0.9.0.
|
// The Pinniped CLI has been sending these params since v0.9.0.
|
||||||
idpNameQueryParamValue := r.Form.Get(oidcapi.AuthorizeUpstreamIDPNameParamName)
|
idpNameQueryParamValue := r.Form.Get(oidcapi.AuthorizeUpstreamIDPNameParamName)
|
||||||
|
|
||||||
// Check if we are in a special case where we should inject an interstitial page to ask the user
|
|
||||||
// which IDP they would like to use.
|
|
||||||
if shouldShowIDPChooser(idpFinder, idpNameQueryParamValue, requestedBrowserlessFlow) {
|
|
||||||
// Redirect to the IDP chooser page with all the same query/form params. When the user chooses an IDP,
|
|
||||||
// it will redirect back to here with all the same params again, with the pinniped_idp_name param added.
|
|
||||||
http.Redirect(w, r,
|
|
||||||
fmt.Sprintf("%s%s?%s", downstreamIssuer, oidc.ChooseIDPEndpointPath, r.Form.Encode()),
|
|
||||||
http.StatusSeeOther,
|
|
||||||
)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
oidcUpstream, ldapUpstream, err := chooseUpstreamIDP(idpNameQueryParamValue, idpFinder)
|
oidcUpstream, ldapUpstream, err := chooseUpstreamIDP(idpNameQueryParamValue, idpFinder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
oidc.WriteAuthorizeError(r, w,
|
oidc.WriteAuthorizeError(r, w,
|
||||||
@ -166,20 +153,6 @@ func NewHandler(
|
|||||||
return securityheader.WrapWithCustomCSP(handler, formposthtml.ContentSecurityPolicy())
|
return securityheader.WrapWithCustomCSP(handler, formposthtml.ContentSecurityPolicy())
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldShowIDPChooser(
|
|
||||||
idpFinder federationdomainproviders.FederationDomainIdentityProvidersFinderI,
|
|
||||||
idpNameQueryParamValue string,
|
|
||||||
requestedBrowserlessFlow bool,
|
|
||||||
) bool {
|
|
||||||
clientDidNotRequestSpecificIDP := len(idpNameQueryParamValue) == 0
|
|
||||||
clientRequestedBrowserBasedFlow := !requestedBrowserlessFlow
|
|
||||||
inBackwardsCompatMode := idpFinder.HasDefaultIDP()
|
|
||||||
federationDomainSpecHasSomeValidIDPs := idpFinder.IDPCount() > 0
|
|
||||||
|
|
||||||
return clientDidNotRequestSpecificIDP && clientRequestedBrowserBasedFlow &&
|
|
||||||
!inBackwardsCompatMode && federationDomainSpecHasSomeValidIDPs
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleAuthRequestForLDAPUpstreamCLIFlow(
|
func handleAuthRequestForLDAPUpstreamCLIFlow(
|
||||||
r *http.Request,
|
r *http.Request,
|
||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
|
@ -731,25 +731,6 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
|
|||||||
wantUpstreamStateParamInLocationHeader: true,
|
wantUpstreamStateParamInLocationHeader: true,
|
||||||
wantBodyStringWithLocationInHref: true,
|
wantBodyStringWithLocationInHref: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "with multiple IDPs available, request does not choose which IDP to use",
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()).
|
|
||||||
WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
|
|
||||||
generateCSRF: happyCSRFGenerator,
|
|
||||||
generatePKCE: happyPKCEGenerator,
|
|
||||||
generateNonce: happyNonceGenerator,
|
|
||||||
stateEncoder: happyStateEncoder,
|
|
||||||
cookieEncoder: happyCookieEncoder,
|
|
||||||
method: http.MethodGet,
|
|
||||||
path: happyGetRequestPath, // does not include pinniped_idp_name param
|
|
||||||
wantStatus: http.StatusSeeOther,
|
|
||||||
wantContentType: htmlContentType,
|
|
||||||
wantCSRFValueInCookieHeader: "", // there should not be a CSRF cookie set on the response
|
|
||||||
wantLocationHeader: urlWithQuery(downstreamIssuer+"/choose_identity_provider", happyGetRequestQueryMap),
|
|
||||||
wantUpstreamStateParamInLocationHeader: false, // it should copy the params of the original request, not add a new state param
|
|
||||||
wantBodyStringWithLocationInHref: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "with multiple IDPs available, request chooses to use OIDC browser flow",
|
name: "with multiple IDPs available, request chooses to use OIDC browser flow",
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
@ -3322,17 +3303,6 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
|
|||||||
wantContentType: plainContentType,
|
wantContentType: plainContentType,
|
||||||
wantBodyString: `{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. 'pinniped_idp_name' param error: did not find IDP with name 'some-ldap-idp'"}`,
|
wantBodyString: `{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. 'pinniped_idp_name' param error: did not find IDP with name 'some-ldap-idp'"}`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "with multiple IDPs, when using browserless flow, when pinniped_idp_name param is not specified, should be an error (browerless flows do not use IDP chooser page)",
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().WithAllowPasswordGrant(true).Build()),
|
|
||||||
method: http.MethodGet,
|
|
||||||
path: happyGetRequestPath,
|
|
||||||
customUsernameHeader: ptr.To(oidcUpstreamUsername),
|
|
||||||
customPasswordHeader: ptr.To(oidcUpstreamPassword),
|
|
||||||
wantStatus: http.StatusBadRequest,
|
|
||||||
wantContentType: plainContentType,
|
|
||||||
wantBodyString: `{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. 'pinniped_idp_name' param error: identity provider not found: this federation domain does not have a default identity provider"}`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "post with invalid form in the body",
|
name: "post with invalid form in the body",
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()),
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()),
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package chooseidp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"go.pinniped.dev/generated/latest/apis/supervisor/oidc"
|
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/chooseidp/chooseidphtml"
|
|
||||||
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
|
|
||||||
"go.pinniped.dev/internal/httputil/httperr"
|
|
||||||
"go.pinniped.dev/internal/httputil/securityheader"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewHandler returns a http.Handler that serves an IDP chooser web page. The authorization endpoint may redirect
|
|
||||||
// to this page, copying all the same parameters from the original authorization request. Each button on this page
|
|
||||||
// simply adds the IDP's name as an additional request parameter to the original authorization request's parameters,
|
|
||||||
// and sends the user back to the authorization endpoint, where the authorization flow can start from scratch using
|
|
||||||
// the original params with the extra pinniped_idp_name param added.
|
|
||||||
func NewHandler(authURL string, upstreamIDPs federationdomainproviders.FederationDomainIdentityProvidersListerI) http.Handler {
|
|
||||||
handler := httperr.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
return httperr.Newf(http.StatusMethodNotAllowed, "%s (try GET)", r.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is just a sanity check that it appears to be an authorize request.
|
|
||||||
// Actual enforcement of parameters will happen at the authorization endpoint.
|
|
||||||
query := r.URL.Query()
|
|
||||||
if !(query.Has("client_id") && query.Has("redirect_uri") && query.Has("scope") && query.Has("response_type")) {
|
|
||||||
return httperr.New(http.StatusBadRequest, "missing required query params (must include client_id, redirect_uri, scope, and response_type)")
|
|
||||||
}
|
|
||||||
|
|
||||||
newIDPForPageData := func(displayName string) chooseidphtml.IdentityProvider {
|
|
||||||
return chooseidphtml.IdentityProvider{
|
|
||||||
DisplayName: displayName,
|
|
||||||
URL: fmt.Sprintf("%s?%s&%s=%s",
|
|
||||||
authURL, r.URL.Query().Encode(), oidc.AuthorizeUpstreamIDPNameParamName, url.QueryEscape(displayName)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var idps []chooseidphtml.IdentityProvider
|
|
||||||
for _, p := range upstreamIDPs.GetOIDCIdentityProviders() {
|
|
||||||
idps = append(idps, newIDPForPageData(p.DisplayName))
|
|
||||||
}
|
|
||||||
for _, p := range upstreamIDPs.GetLDAPIdentityProviders() {
|
|
||||||
idps = append(idps, newIDPForPageData(p.DisplayName))
|
|
||||||
}
|
|
||||||
for _, p := range upstreamIDPs.GetActiveDirectoryIdentityProviders() {
|
|
||||||
idps = append(idps, newIDPForPageData(p.DisplayName))
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.SliceStable(idps, func(i, j int) bool {
|
|
||||||
return idps[i].DisplayName < idps[j].DisplayName
|
|
||||||
})
|
|
||||||
|
|
||||||
if len(idps) == 0 {
|
|
||||||
// This shouldn't normally happen in practice because the auth endpoint would not have redirected to here.
|
|
||||||
return httperr.New(http.StatusInternalServerError,
|
|
||||||
"please check the server's configuration: no valid identity providers found for this FederationDomain")
|
|
||||||
}
|
|
||||||
|
|
||||||
return chooseidphtml.Template().Execute(w, &chooseidphtml.PageData{IdentityProviders: idps})
|
|
||||||
})
|
|
||||||
|
|
||||||
return wrapSecurityHeaders(handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func wrapSecurityHeaders(handler http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
wrapped := securityheader.WrapWithCustomCSP(handler, chooseidphtml.ContentSecurityPolicy())
|
|
||||||
wrapped.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,150 +0,0 @@
|
|||||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package chooseidp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/chooseidp/chooseidphtml"
|
|
||||||
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
|
|
||||||
"go.pinniped.dev/internal/federationdomain/oidc"
|
|
||||||
"go.pinniped.dev/internal/testutil"
|
|
||||||
"go.pinniped.dev/internal/testutil/oidctestutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestChooseIDPHandler(t *testing.T) {
|
|
||||||
const testIssuer = "https://pinniped.dev/issuer"
|
|
||||||
|
|
||||||
testReqQuery := url.Values{
|
|
||||||
"client_id": []string{"foo"},
|
|
||||||
"redirect_uri": []string{"bar"},
|
|
||||||
"scope": []string{"baz"},
|
|
||||||
"response_type": []string{"bat"},
|
|
||||||
}
|
|
||||||
testIssuerWithTestReqQuery := testIssuer + "?" + testReqQuery.Encode()
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
|
|
||||||
method string
|
|
||||||
reqTarget string
|
|
||||||
idps federationdomainproviders.FederationDomainIdentityProvidersListerI
|
|
||||||
|
|
||||||
wantStatus int
|
|
||||||
wantContentType string
|
|
||||||
wantBodyString string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "happy path",
|
|
||||||
method: http.MethodGet,
|
|
||||||
reqTarget: "/some/path" + oidc.ChooseIDPEndpointPath + "?" + testReqQuery.Encode(),
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().WithName("oidc2").Build()).
|
|
||||||
WithLDAP(oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().WithName("ldap1").Build()).
|
|
||||||
WithActiveDirectory(oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().WithName("z-ad1").Build()).
|
|
||||||
WithLDAP(oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().WithName("ldap2").Build()).
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().WithName("oidc1").Build()).
|
|
||||||
WithActiveDirectory(oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().WithName("ad2").Build()).
|
|
||||||
BuildFederationDomainIdentityProvidersListerFinder(),
|
|
||||||
wantStatus: http.StatusOK,
|
|
||||||
wantContentType: "text/html; charset=utf-8",
|
|
||||||
wantBodyString: testutil.ExpectedChooseIDPPageHTML(chooseidphtml.CSS(), chooseidphtml.JS(), []testutil.ChooseIDPPageExpectedValue{
|
|
||||||
// Should be sorted alphabetically by displayName.
|
|
||||||
{DisplayName: "ad2", URL: testIssuerWithTestReqQuery + "&pinniped_idp_name=ad2"},
|
|
||||||
{DisplayName: "ldap1", URL: testIssuerWithTestReqQuery + "&pinniped_idp_name=ldap1"},
|
|
||||||
{DisplayName: "ldap2", URL: testIssuerWithTestReqQuery + "&pinniped_idp_name=ldap2"},
|
|
||||||
{DisplayName: "oidc1", URL: testIssuerWithTestReqQuery + "&pinniped_idp_name=oidc1"},
|
|
||||||
{DisplayName: "oidc2", URL: testIssuerWithTestReqQuery + "&pinniped_idp_name=oidc2"},
|
|
||||||
{DisplayName: "z-ad1", URL: testIssuerWithTestReqQuery + "&pinniped_idp_name=z-ad1"},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "happy path when there are special characters in the IDP name",
|
|
||||||
method: http.MethodGet,
|
|
||||||
reqTarget: "/some/path" + oidc.ChooseIDPEndpointPath + "?" + testReqQuery.Encode(),
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().WithName(`This is Ryan's IDP 👍\~!@#$%^&*()-+[]{}\|;'"<>,.?`).Build()).
|
|
||||||
WithLDAP(oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().WithName(`This is Josh's IDP 🦭`).Build()).
|
|
||||||
BuildFederationDomainIdentityProvidersListerFinder(),
|
|
||||||
wantStatus: http.StatusOK,
|
|
||||||
wantContentType: "text/html; charset=utf-8",
|
|
||||||
wantBodyString: testutil.ExpectedChooseIDPPageHTML(chooseidphtml.CSS(), chooseidphtml.JS(), []testutil.ChooseIDPPageExpectedValue{
|
|
||||||
// Should be sorted alphabetically by displayName.
|
|
||||||
{
|
|
||||||
DisplayName: `This is Josh's IDP 🦭`,
|
|
||||||
URL: testIssuerWithTestReqQuery + `&pinniped_idp_name=` + url.QueryEscape(`This is Josh's IDP 🦭`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
DisplayName: `This is Ryan's IDP 👍\~!@#$%^&*()-+[]{}\|;'"<>,.?`,
|
|
||||||
URL: testIssuerWithTestReqQuery + `&pinniped_idp_name=` + url.QueryEscape(`This is Ryan's IDP 👍\~!@#$%^&*()-+[]{}\|;'"<>,.?`),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "no valid IDPs are configured on the FederationDomain",
|
|
||||||
method: http.MethodGet,
|
|
||||||
reqTarget: "/some/path" + oidc.ChooseIDPEndpointPath + "?" + testReqQuery.Encode(),
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
BuildFederationDomainIdentityProvidersListerFinder(),
|
|
||||||
wantStatus: http.StatusInternalServerError,
|
|
||||||
wantContentType: "text/plain; charset=utf-8",
|
|
||||||
wantBodyString: "Internal Server Error: please check the server's configuration: no valid identity providers found for this FederationDomain\n",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "no query params on the request",
|
|
||||||
method: http.MethodGet,
|
|
||||||
reqTarget: "/some/path" + oidc.ChooseIDPEndpointPath,
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().WithName("x-some-idp").Build()).
|
|
||||||
BuildFederationDomainIdentityProvidersListerFinder(),
|
|
||||||
wantStatus: http.StatusBadRequest,
|
|
||||||
wantContentType: "text/plain; charset=utf-8",
|
|
||||||
wantBodyString: "Bad Request: missing required query params (must include client_id, redirect_uri, scope, and response_type)\n",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "missing required query param(s) on the request",
|
|
||||||
method: http.MethodGet,
|
|
||||||
reqTarget: "/some/path" + oidc.ChooseIDPEndpointPath + "?client_id=foo",
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().WithName("x-some-idp").Build()).
|
|
||||||
BuildFederationDomainIdentityProvidersListerFinder(),
|
|
||||||
wantStatus: http.StatusBadRequest,
|
|
||||||
wantContentType: "text/plain; charset=utf-8",
|
|
||||||
wantBodyString: "Bad Request: missing required query params (must include client_id, redirect_uri, scope, and response_type)\n",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bad request method",
|
|
||||||
method: http.MethodPost,
|
|
||||||
reqTarget: oidc.ChooseIDPEndpointPath,
|
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().WithName("x-some-idp").Build()).
|
|
||||||
BuildFederationDomainIdentityProvidersListerFinder(),
|
|
||||||
wantStatus: http.StatusMethodNotAllowed,
|
|
||||||
wantContentType: "text/plain; charset=utf-8",
|
|
||||||
wantBodyString: "Method Not Allowed: POST (try GET)\n",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
test := test
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
handler := NewHandler(testIssuer, test.idps)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(test.method, test.reqTarget, nil)
|
|
||||||
rsp := httptest.NewRecorder()
|
|
||||||
handler.ServeHTTP(rsp, req)
|
|
||||||
|
|
||||||
require.Equal(t, test.wantStatus, rsp.Code)
|
|
||||||
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
|
|
||||||
require.Equal(t, test.wantBodyString, rsp.Body.String())
|
|
||||||
testutil.RequireSecurityHeadersWithIDPChooserPageCSPs(t, rsp)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
/* Copyright 2023 the Pinniped contributors. All Rights Reserved. */
|
|
||||||
/* SPDX-License-Identifier: Apache-2.0 */
|
|
||||||
|
|
||||||
html {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The form for this page is styled to be the same as the form from login_form.css */
|
|
||||||
body {
|
|
||||||
font-family: "Metropolis-Light", Helvetica, sans-serif;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column wrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
/* subtle gradient make the login box stand out */
|
|
||||||
background: linear-gradient(to top, #f8f8f8, white);
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 20px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
border-radius: 4px;
|
|
||||||
border-color: #ddd;
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
width: 400px;
|
|
||||||
padding:30px 30px 0;
|
|
||||||
margin: 60px 20px 0;
|
|
||||||
background: white;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buttons for this page are styled to be the same as the form submit button in login_form.css */
|
|
||||||
button {
|
|
||||||
color: inherit;
|
|
||||||
font: inherit;
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
outline: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-field {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-field button {
|
|
||||||
width: 100%;
|
|
||||||
padding: 1em;
|
|
||||||
background-color: #218fcf; /* this is a color from the Pinniped logo :) */
|
|
||||||
color: #eee;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all .3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-field button:focus, .form-field button:hover {
|
|
||||||
background-color: #1abfd3; /* this is a color from the Pinniped logo :) */
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-field button:active {
|
|
||||||
transform: scale(.99);
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
window.onload = () => {
|
|
||||||
Array.from(document.querySelectorAll('button')).forEach(btn => {
|
|
||||||
btn.onclick = () => window.location.href = btn.dataset.url;
|
|
||||||
});
|
|
||||||
// Initially hidden to allow noscript tag to be the only visible content in the form in case Javascript is disabled.
|
|
||||||
// Make it visible whenever Javascript is enabled.
|
|
||||||
document.getElementById("choose-idp-form-buttons").hidden = false;
|
|
||||||
};
|
|
@ -1,74 +0,0 @@
|
|||||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package chooseidphtml
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "embed" // Needed to trigger //go:embed directives below.
|
|
||||||
"html/template"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/tdewolff/minify/v2/minify"
|
|
||||||
|
|
||||||
"go.pinniped.dev/internal/federationdomain/csp"
|
|
||||||
)
|
|
||||||
|
|
||||||
//nolint:gochecknoglobals // This package uses globals to ensure that all parsing and minifying happens at init.
|
|
||||||
var (
|
|
||||||
//go:embed choose_idp.css
|
|
||||||
rawCSS string
|
|
||||||
minifiedCSS = panicOnError(minify.CSS(rawCSS))
|
|
||||||
|
|
||||||
//go:embed choose_idp.js
|
|
||||||
rawJS string
|
|
||||||
minifiedJS = panicOnError(minify.JS(rawJS))
|
|
||||||
|
|
||||||
//go:embed choose_idp.gohtml
|
|
||||||
rawHTMLTemplate string
|
|
||||||
|
|
||||||
// Parse the Go templated HTML and inject functions providing the minified inline CSS and JS.
|
|
||||||
parsedHTMLTemplate = template.Must(template.New("choose_idp.gohtml").Funcs(template.FuncMap{
|
|
||||||
"minifiedCSS": func() template.CSS { return template.CSS(CSS()) },
|
|
||||||
"minifiedJS": func() template.JS { return template.JS(JS()) }, //nolint:gosec // This is 100% static input, not attacker-controlled.
|
|
||||||
}).Parse(rawHTMLTemplate))
|
|
||||||
|
|
||||||
// Generate the CSP header value once since it's effectively constant.
|
|
||||||
cspValue = strings.Join([]string{
|
|
||||||
`default-src 'none'`,
|
|
||||||
`script-src '` + csp.Hash(minifiedJS) + `'`,
|
|
||||||
`style-src '` + csp.Hash(minifiedCSS) + `'`,
|
|
||||||
`img-src data:`,
|
|
||||||
`frame-ancestors 'none'`,
|
|
||||||
}, "; ")
|
|
||||||
)
|
|
||||||
|
|
||||||
func panicOnError(s string, err error) string {
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContentSecurityPolicy returns the Content-Security-Policy header value to make the Template() operate correctly.
|
|
||||||
//
|
|
||||||
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy.
|
|
||||||
func ContentSecurityPolicy() string { return cspValue }
|
|
||||||
|
|
||||||
// Template returns the html/template.Template for rendering the login page.
|
|
||||||
func Template() *template.Template { return parsedHTMLTemplate }
|
|
||||||
|
|
||||||
// CSS returns the minified CSS that will be embedded into the page template.
|
|
||||||
func CSS() string { return minifiedCSS }
|
|
||||||
|
|
||||||
// JS returns the minified JS that will be embedded into the page template.
|
|
||||||
func JS() string { return minifiedJS }
|
|
||||||
|
|
||||||
type IdentityProvider struct {
|
|
||||||
DisplayName string
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageData represents the inputs to the template.
|
|
||||||
type PageData struct {
|
|
||||||
IdentityProviders []IdentityProvider
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package chooseidphtml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"go.pinniped.dev/internal/testutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
testExpectedCSS = `html{height:100%}body{font-family:metropolis-light,Helvetica,sans-serif;display:flex;flex-flow:column wrap;justify-content:flex-start;align-items:center;background:linear-gradient(to top,#f8f8f8,white);min-height:100%}h1{font-size:20px;margin:0}.box{display:flex;flex-direction:column;flex-wrap:nowrap;border-radius:4px;border-color:#ddd;border-width:1px;border-style:solid;width:400px;padding:30px 30px 0;margin:60px 20px 0;background:#fff;font-size:14px}button{color:inherit;font:inherit;border:0;margin:0;outline:0;padding:0}.form-field{display:flex;margin-bottom:30px}.form-field button{width:100%;padding:1em;background-color:#218fcf;color:#eee;font-weight:700;cursor:pointer;transition:all .3s}.form-field button:focus,.form-field button:hover{background-color:#1abfd3}.form-field button:active{transform:scale(.99)}`
|
|
||||||
|
|
||||||
testExpectedJS = `window.onload=()=>{Array.from(document.querySelectorAll("button")).forEach(e=>{e.onclick=()=>window.location.href=e.dataset.url}),document.getElementById("choose-idp-form-buttons").hidden=!1}`
|
|
||||||
|
|
||||||
// It's okay if this changes in the future, but this gives us a chance to eyeball the formatting.
|
|
||||||
// Our browser-based integration tests should find any incompatibilities.
|
|
||||||
testExpectedCSP = `default-src 'none'; ` +
|
|
||||||
`script-src 'sha256-eyuE+qQfuMn4WbDizGOp1wSGReaMYRYmRMXpyEo+8ps='; ` +
|
|
||||||
`style-src 'sha256-SgeTG5HEbHNFgjH+EvLrC+VKZRZQ6iAI3oFnW7i/Tm4='; ` +
|
|
||||||
`img-src data:; ` +
|
|
||||||
`frame-ancestors 'none'`
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTemplate(t *testing.T) {
|
|
||||||
const (
|
|
||||||
testUpstreamName1 = "test-idp-name1"
|
|
||||||
testUpstreamName2 = "test-idp-name2"
|
|
||||||
testURL1 = "https://pinniped.dev/path1?query=value"
|
|
||||||
testURL2 = "https://pinniped.dev/path2?query=value"
|
|
||||||
)
|
|
||||||
|
|
||||||
pageInputs := &PageData{
|
|
||||||
IdentityProviders: []IdentityProvider{
|
|
||||||
{DisplayName: testUpstreamName1, URL: testURL1},
|
|
||||||
{DisplayName: testUpstreamName2, URL: testURL2},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedHTML := testutil.ExpectedChooseIDPPageHTML(testExpectedCSS, testExpectedJS, []testutil.ChooseIDPPageExpectedValue{
|
|
||||||
{DisplayName: testUpstreamName1, URL: testURL1},
|
|
||||||
{DisplayName: testUpstreamName2, URL: testURL2},
|
|
||||||
})
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
require.NoError(t, Template().Execute(&buf, pageInputs))
|
|
||||||
require.Equal(t, expectedHTML, buf.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContentSecurityPolicy(t *testing.T) {
|
|
||||||
require.Equal(t, testExpectedCSP, ContentSecurityPolicy())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCSS(t *testing.T) {
|
|
||||||
require.Equal(t, testExpectedCSS, CSS())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJS(t *testing.T) {
|
|
||||||
require.Equal(t, testExpectedJS, JS())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHelpers(t *testing.T) {
|
|
||||||
require.Equal(t, "test", panicOnError("test", nil))
|
|
||||||
require.PanicsWithError(t, "some error", func() { panicOnError("", fmt.Errorf("some error")) })
|
|
||||||
}
|
|
@ -15,7 +15,6 @@ import (
|
|||||||
"go.pinniped.dev/internal/federationdomain/dynamiccodec"
|
"go.pinniped.dev/internal/federationdomain/dynamiccodec"
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/auth"
|
"go.pinniped.dev/internal/federationdomain/endpoints/auth"
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/callback"
|
"go.pinniped.dev/internal/federationdomain/endpoints/callback"
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/chooseidp"
|
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/discovery"
|
"go.pinniped.dev/internal/federationdomain/endpoints/discovery"
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/idpdiscovery"
|
"go.pinniped.dev/internal/federationdomain/endpoints/idpdiscovery"
|
||||||
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
|
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
|
||||||
@ -153,11 +152,6 @@ func (m *Manager) SetFederationDomains(federationDomains ...*federationdomainpro
|
|||||||
issuerURL+oidc.CallbackEndpointPath,
|
issuerURL+oidc.CallbackEndpointPath,
|
||||||
)
|
)
|
||||||
|
|
||||||
m.providerHandlers[(issuerHostWithPath + oidc.ChooseIDPEndpointPath)] = chooseidp.NewHandler(
|
|
||||||
issuerURL+oidc.AuthorizationEndpointPath,
|
|
||||||
idpLister,
|
|
||||||
)
|
|
||||||
|
|
||||||
m.providerHandlers[(issuerHostWithPath + oidc.TokenEndpointPath)] = token.NewHandler(
|
m.providerHandlers[(issuerHostWithPath + oidc.TokenEndpointPath)] = token.NewHandler(
|
||||||
idpLister,
|
idpLister,
|
||||||
oauthHelperWithKubeStorage,
|
oauthHelperWithKubeStorage,
|
||||||
|
@ -123,32 +123,6 @@ func TestManager(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
requirePinnipedIDPChooserRequestToBeHandled := func(requestIssuer string, expectedIDPNames []string) {
|
|
||||||
recorder := httptest.NewRecorder()
|
|
||||||
|
|
||||||
requiredParams := url.Values{
|
|
||||||
"client_id": []string{"foo"},
|
|
||||||
"redirect_uri": []string{"bar"},
|
|
||||||
"scope": []string{"baz"},
|
|
||||||
"response_type": []string{"bat"},
|
|
||||||
}
|
|
||||||
|
|
||||||
subject.ServeHTTP(recorder, newGetRequest(requestIssuer+oidc.ChooseIDPEndpointPath+"?"+requiredParams.Encode()))
|
|
||||||
|
|
||||||
r.False(fallbackHandlerWasCalled)
|
|
||||||
|
|
||||||
// Minimal check to ensure that the right endpoint was called
|
|
||||||
r.Equal(http.StatusOK, recorder.Code, "unexpected response:", recorder)
|
|
||||||
r.Equal("text/html; charset=utf-8", recorder.Header().Get("Content-Type"))
|
|
||||||
responseBody, err := io.ReadAll(recorder.Body)
|
|
||||||
r.NoError(err)
|
|
||||||
// Should have some buttons whose URLs include the pinniped_idp_name param.
|
|
||||||
r.Contains(string(responseBody), "<button ")
|
|
||||||
for _, expectedIDPName := range expectedIDPNames {
|
|
||||||
r.Contains(string(responseBody), fmt.Sprintf("pinniped_idp_name=%s", url.QueryEscape(expectedIDPName)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requireAuthorizationRequestToBeHandled := func(requestIssuer, requestURLSuffix, expectedRedirectLocationPrefix string) (string, string) {
|
requireAuthorizationRequestToBeHandled := func(requestIssuer, requestURLSuffix, expectedRedirectLocationPrefix string) (string, string) {
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
@ -403,11 +377,6 @@ func TestManager(t *testing.T) {
|
|||||||
requireJWKSRequestToBeHandled(issuer2DifferentCaseHostname, "", issuer2KeyID)
|
requireJWKSRequestToBeHandled(issuer2DifferentCaseHostname, "", issuer2KeyID)
|
||||||
requireJWKSRequestToBeHandled(issuer2DifferentCaseHostname, "?some=query", issuer2KeyID)
|
requireJWKSRequestToBeHandled(issuer2DifferentCaseHostname, "?some=query", issuer2KeyID)
|
||||||
|
|
||||||
requirePinnipedIDPChooserRequestToBeHandled(issuer1, []string{upstreamIDPDisplayName1, upstreamIDPDisplayName2})
|
|
||||||
requirePinnipedIDPChooserRequestToBeHandled(issuer2, []string{upstreamIDPDisplayName1, upstreamIDPDisplayName2})
|
|
||||||
requirePinnipedIDPChooserRequestToBeHandled(issuer1DifferentCaseHostname, []string{upstreamIDPDisplayName1, upstreamIDPDisplayName2})
|
|
||||||
requirePinnipedIDPChooserRequestToBeHandled(issuer2DifferentCaseHostname, []string{upstreamIDPDisplayName1, upstreamIDPDisplayName2})
|
|
||||||
|
|
||||||
authRequestParamsIDP1 := "?" + url.Values{
|
authRequestParamsIDP1 := "?" + url.Values{
|
||||||
"pinniped_idp_name": []string{upstreamIDPDisplayName1},
|
"pinniped_idp_name": []string{upstreamIDPDisplayName1},
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
|
@ -36,9 +36,6 @@ type FederationDomainIdentityProvidersFinderI interface {
|
|||||||
*resolvedprovider.FederationDomainResolvedLDAPIdentityProvider,
|
*resolvedprovider.FederationDomainResolvedLDAPIdentityProvider,
|
||||||
error,
|
error,
|
||||||
)
|
)
|
||||||
|
|
||||||
HasDefaultIDP() bool
|
|
||||||
IDPCount() int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type FederationDomainIdentityProvidersListerI interface {
|
type FederationDomainIdentityProvidersListerI interface {
|
||||||
@ -74,10 +71,8 @@ type FederationDomainIdentityProvidersListerFinder struct {
|
|||||||
// federationDomainIssuer parameter's IdentityProviders() list must have a unique DisplayName.
|
// federationDomainIssuer parameter's IdentityProviders() list must have a unique DisplayName.
|
||||||
// Note that a single underlying IDP UID may be used by multiple FederationDomainIdentityProvider in the parameter.
|
// Note that a single underlying IDP UID may be used by multiple FederationDomainIdentityProvider in the parameter.
|
||||||
// The wrapped lister should contain all valid upstream providers that are defined in the Supervisor, and is expected to
|
// The wrapped lister should contain all valid upstream providers that are defined in the Supervisor, and is expected to
|
||||||
// be thread-safe and to change its contents over time. (Note that it should not contain any invalid or unready identity
|
// be thread-safe and to change its contents over time. The FederationDomainIdentityProvidersListerFinder will filter out the
|
||||||
// providers because the controllers that fill this cache should not put invalid or unready providers into the cache.)
|
// ones that don't apply to this federation domain.
|
||||||
// The FederationDomainIdentityProvidersListerFinder will filter out the ones that don't apply to this federation
|
|
||||||
// domain.
|
|
||||||
func NewFederationDomainIdentityProvidersListerFinder(
|
func NewFederationDomainIdentityProvidersListerFinder(
|
||||||
federationDomainIssuer *FederationDomainIssuer,
|
federationDomainIssuer *FederationDomainIssuer,
|
||||||
wrappedLister idplister.UpstreamIdentityProvidersLister,
|
wrappedLister idplister.UpstreamIdentityProvidersLister,
|
||||||
@ -104,10 +99,6 @@ func NewFederationDomainIdentityProvidersListerFinder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *FederationDomainIdentityProvidersListerFinder) IDPCount() int {
|
|
||||||
return len(u.GetOIDCIdentityProviders()) + len(u.GetLDAPIdentityProviders()) + len(u.GetActiveDirectoryIdentityProviders())
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindUpstreamIDPByDisplayName selects either an OIDC, LDAP, or ActiveDirectory IDP, or returns an error.
|
// FindUpstreamIDPByDisplayName selects either an OIDC, LDAP, or ActiveDirectory IDP, or returns an error.
|
||||||
// It only considers the allowed IDPs while doing the lookup by display name.
|
// It only considers the allowed IDPs while doing the lookup by display name.
|
||||||
// Note that ActiveDirectory and LDAP IDPs both return the same type, but with different SessionProviderType values.
|
// Note that ActiveDirectory and LDAP IDPs both return the same type, but with different SessionProviderType values.
|
||||||
@ -140,10 +131,6 @@ func (u *FederationDomainIdentityProvidersListerFinder) FindUpstreamIDPByDisplay
|
|||||||
return nil, nil, fmt.Errorf("identity provider not available: %q", upstreamIDPDisplayName)
|
return nil, nil, fmt.Errorf("identity provider not available: %q", upstreamIDPDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *FederationDomainIdentityProvidersListerFinder) HasDefaultIDP() bool {
|
|
||||||
return u.defaultIdentityProvider != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindDefaultIDP works like FindUpstreamIDPByDisplayName, but finds the default IDP instead of finding by name.
|
// FindDefaultIDP works like FindUpstreamIDPByDisplayName, but finds the default IDP instead of finding by name.
|
||||||
// If there is no default IDP for this federation domain, then FindDefaultIDP will return an error.
|
// If there is no default IDP for this federation domain, then FindDefaultIDP will return an error.
|
||||||
// This can be used to handle the backwards compatibility mode where an authorization request could be made
|
// This can be used to handle the backwards compatibility mode where an authorization request could be made
|
||||||
@ -154,7 +141,7 @@ func (u *FederationDomainIdentityProvidersListerFinder) FindDefaultIDP() (
|
|||||||
*resolvedprovider.FederationDomainResolvedLDAPIdentityProvider,
|
*resolvedprovider.FederationDomainResolvedLDAPIdentityProvider,
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
if !u.HasDefaultIDP() {
|
if u.defaultIdentityProvider == nil {
|
||||||
return nil, nil, fmt.Errorf("identity provider not found: this federation domain does not have a default identity provider")
|
return nil, nil, fmt.Errorf("identity provider not found: this federation domain does not have a default identity provider")
|
||||||
}
|
}
|
||||||
return u.FindUpstreamIDPByDisplayName(u.defaultIdentityProvider.DisplayName)
|
return u.FindUpstreamIDPByDisplayName(u.defaultIdentityProvider.DisplayName)
|
||||||
|
@ -99,7 +99,7 @@ func TestFederationDomainIdentityProvidersListerFinder(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fdIssuerWithIDPWithLostUID, err := NewFederationDomainIssuer(fakeIssuerURL, []*FederationDomainIdentityProvider{
|
fdIssuerWithIDPwithLostUID, err := NewFederationDomainIssuer(fakeIssuerURL, []*FederationDomainIdentityProvider{
|
||||||
{DisplayName: "my-idp", UID: "you-cant-find-my-uid"},
|
{DisplayName: "my-idp", UID: "you-cant-find-my-uid"},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -244,7 +244,7 @@ func TestFederationDomainIdentityProvidersListerFinder(t *testing.T) {
|
|||||||
findIDPByDisplayName: "my-idp",
|
findIDPByDisplayName: "my-idp",
|
||||||
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
BuildDynamicUpstreamIDPProvider(),
|
BuildDynamicUpstreamIDPProvider(),
|
||||||
federationDomainIssuer: fdIssuerWithIDPWithLostUID,
|
federationDomainIssuer: fdIssuerWithIDPwithLostUID,
|
||||||
wantError: `identity provider not available: "my-idp"`,
|
wantError: `identity provider not available: "my-idp"`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -263,10 +263,10 @@ func TestFederationDomainIdentityProvidersListerFinder(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
if tt.wantOIDCIDPByDisplayName != nil {
|
if tt.wantOIDCIDPByDisplayName != nil {
|
||||||
require.Equal(t, tt.wantOIDCIDPByDisplayName, foundOIDCIDP)
|
require.Equal(t, foundOIDCIDP, tt.wantOIDCIDPByDisplayName)
|
||||||
}
|
}
|
||||||
if tt.wantLDAPIDPByDisplayName != nil {
|
if tt.wantLDAPIDPByDisplayName != nil {
|
||||||
require.Equal(t, tt.wantLDAPIDPByDisplayName, foundLDAPIDP)
|
require.Equal(t, foundLDAPIDP, tt.wantLDAPIDPByDisplayName)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -339,10 +339,10 @@ func TestFederationDomainIdentityProvidersListerFinder(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
if tt.wantDefaultOIDCIDP != nil {
|
if tt.wantDefaultOIDCIDP != nil {
|
||||||
require.Equal(t, tt.wantDefaultOIDCIDP, foundOIDCIDP)
|
require.Equal(t, foundOIDCIDP, tt.wantDefaultOIDCIDP)
|
||||||
}
|
}
|
||||||
if tt.wantDefaultLDAPIDP != nil {
|
if tt.wantDefaultLDAPIDP != nil {
|
||||||
require.Equal(t, tt.wantDefaultLDAPIDP, foundLDAPIDP)
|
require.Equal(t, foundLDAPIDP, tt.wantDefaultLDAPIDP)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -406,7 +406,7 @@ func TestFederationDomainIdentityProvidersListerFinder(t *testing.T) {
|
|||||||
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
||||||
idps := subject.GetOIDCIdentityProviders()
|
idps := subject.GetOIDCIdentityProviders()
|
||||||
|
|
||||||
require.Equal(t, tt.wantIDPs, idps)
|
require.Equal(t, idps, tt.wantIDPs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,7 +467,7 @@ func TestFederationDomainIdentityProvidersListerFinder(t *testing.T) {
|
|||||||
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
||||||
idps := subject.GetLDAPIdentityProviders()
|
idps := subject.GetLDAPIdentityProviders()
|
||||||
|
|
||||||
require.Equal(t, tt.wantIDPs, idps)
|
require.Equal(t, idps, tt.wantIDPs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,110 +529,7 @@ func TestFederationDomainIdentityProvidersListerFinder(t *testing.T) {
|
|||||||
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
||||||
idps := subject.GetActiveDirectoryIdentityProviders()
|
idps := subject.GetActiveDirectoryIdentityProviders()
|
||||||
|
|
||||||
require.Equal(t, tt.wantIDPs, idps)
|
require.Equal(t, idps, tt.wantIDPs)
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
testIDPCount := []struct {
|
|
||||||
name string
|
|
||||||
wrappedLister idplister.UpstreamIdentityProvidersLister
|
|
||||||
federationDomainIssuer *FederationDomainIssuer
|
|
||||||
wantCount int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "IDPCount when there are none to be found",
|
|
||||||
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
BuildDynamicUpstreamIDPProvider(),
|
|
||||||
federationDomainIssuer: fdIssuerWithOIDCAndLDAPAndADIDPs,
|
|
||||||
wantCount: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "IDPCount when there are various types of IDP to be found",
|
|
||||||
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(myOIDCIDP1).
|
|
||||||
WithOIDC(myOIDCIDP2).
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().
|
|
||||||
WithName("my-oidc-idp-that-isnt-in-fd-issuer").
|
|
||||||
WithResourceUID("my-oidc-idp-that-isnt-in-fd-issuer").
|
|
||||||
Build()).
|
|
||||||
WithLDAP(myLDAPIDP1).
|
|
||||||
WithLDAP(oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
|
||||||
WithName("my-ldap-idp-that-isnt-in-fd-issuer").
|
|
||||||
WithResourceUID("my-ldap-idp-that-isnt-in-fd-issuer").
|
|
||||||
Build()).
|
|
||||||
WithActiveDirectory(myADIDP1).
|
|
||||||
WithActiveDirectory(myADIDP2).
|
|
||||||
WithActiveDirectory(oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
|
||||||
WithName("my-ad-idp-that-isnt-in-fd-issuer").
|
|
||||||
WithResourceUID("my-ad-idp-that-isnt-in-fd-issuer").
|
|
||||||
Build()).
|
|
||||||
BuildDynamicUpstreamIDPProvider(),
|
|
||||||
federationDomainIssuer: fdIssuerWithOIDCAndLDAPAndADIDPs,
|
|
||||||
wantCount: 5,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range testIDPCount {
|
|
||||||
tt := tt
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
|
||||||
|
|
||||||
require.Equal(t, tt.wantCount, subject.IDPCount())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
testHasDefaultIDP := []struct {
|
|
||||||
name string
|
|
||||||
wrappedLister idplister.UpstreamIdentityProvidersLister
|
|
||||||
federationDomainIssuer *FederationDomainIssuer
|
|
||||||
wantHasDefaultIDP bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "HasDefaultIDP when there is an OIDC provider set as default",
|
|
||||||
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(myDefaultOIDCIDP).
|
|
||||||
BuildDynamicUpstreamIDPProvider(),
|
|
||||||
federationDomainIssuer: fdIssuerWithDefaultOIDCIDP,
|
|
||||||
wantHasDefaultIDP: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "HasDefaultIDP when there is an LDAP provider set as default",
|
|
||||||
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithLDAP(myDefaultLDAPIDP).
|
|
||||||
BuildDynamicUpstreamIDPProvider(),
|
|
||||||
federationDomainIssuer: fdIssuerWithDefaultLDAPIDP,
|
|
||||||
wantHasDefaultIDP: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "HasDefaultIDP when there is one set even if it cannot be found",
|
|
||||||
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
WithOIDC(oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder().
|
|
||||||
WithName("my-oidc-idp-that-isnt-in-fd-issuer").
|
|
||||||
WithResourceUID("my-oidc-idp-that-isnt-in-fd-issuer").
|
|
||||||
Build()).
|
|
||||||
BuildDynamicUpstreamIDPProvider(),
|
|
||||||
federationDomainIssuer: fdIssuerWithDefaultOIDCIDP,
|
|
||||||
wantHasDefaultIDP: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "HasDefaultIDP when there is none set",
|
|
||||||
wrappedLister: oidctestutil.NewUpstreamIDPListerBuilder().
|
|
||||||
BuildDynamicUpstreamIDPProvider(),
|
|
||||||
federationDomainIssuer: fdIssuerWithOIDCAndLDAPAndADIDPs,
|
|
||||||
wantHasDefaultIDP: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range testHasDefaultIDP {
|
|
||||||
tt := tt
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
subject := NewFederationDomainIdentityProvidersListerFinder(tt.federationDomainIssuer, tt.wrappedLister)
|
|
||||||
|
|
||||||
require.Equal(t, tt.wantHasDefaultIDP, subject.HasDefaultIDP())
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,10 +67,6 @@ code {
|
|||||||
background-image: url("data:image/svg+xml,%3Csvg version='1.1' width='36' height='36' viewBox='0 0 36 36' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Ecopy-to-clipboard-line%3C/title%3E%3Cpath d='M22.6,4H21.55a3.89,3.89,0,0,0-7.31,0H13.4A2.41,2.41,0,0,0,11,6.4V10H25V6.4A2.41,2.41,0,0,0,22.6,4ZM23,8H13V6.25A.25.25,0,0,1,13.25,6h2.69l.12-1.11A1.24,1.24,0,0,1,16.61,4a2,2,0,0,1,3.15,1.18l.09.84h2.9a.25.25,0,0,1,.25.25Z' class='clr-i-outline clr-i-outline-path-1'%3E%3C/path%3E%3Cpath d='M33.25,18.06H21.33l2.84-2.83a1,1,0,1,0-1.42-1.42L17.5,19.06l5.25,5.25a1,1,0,0,0,.71.29,1,1,0,0,0,.71-1.7l-2.84-2.84H33.25a1,1,0,0,0,0-2Z' class='clr-i-outline clr-i-outline-path-2'%3E%3C/path%3E%3Cpath d='M29,16h2V6.68A1.66,1.66,0,0,0,29.35,5H27.08V7H29Z' class='clr-i-outline clr-i-outline-path-3'%3E%3C/path%3E%3Cpath d='M29,31H7V7H9V5H6.64A1.66,1.66,0,0,0,5,6.67V31.32A1.66,1.66,0,0,0,6.65,33H29.36A1.66,1.66,0,0,0,31,31.33V22.06H29Z' class='clr-i-outline clr-i-outline-path-4'%3E%3C/path%3E%3Crect x='0' y='0' width='36' height='36' fill-opacity='0'/%3E%3C/svg%3E");
|
background-image: url("data:image/svg+xml,%3Csvg version='1.1' width='36' height='36' viewBox='0 0 36 36' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Ecopy-to-clipboard-line%3C/title%3E%3Cpath d='M22.6,4H21.55a3.89,3.89,0,0,0-7.31,0H13.4A2.41,2.41,0,0,0,11,6.4V10H25V6.4A2.41,2.41,0,0,0,22.6,4ZM23,8H13V6.25A.25.25,0,0,1,13.25,6h2.69l.12-1.11A1.24,1.24,0,0,1,16.61,4a2,2,0,0,1,3.15,1.18l.09.84h2.9a.25.25,0,0,1,.25.25Z' class='clr-i-outline clr-i-outline-path-1'%3E%3C/path%3E%3Cpath d='M33.25,18.06H21.33l2.84-2.83a1,1,0,1,0-1.42-1.42L17.5,19.06l5.25,5.25a1,1,0,0,0,.71.29,1,1,0,0,0,.71-1.7l-2.84-2.84H33.25a1,1,0,0,0,0-2Z' class='clr-i-outline clr-i-outline-path-2'%3E%3C/path%3E%3Cpath d='M29,16h2V6.68A1.66,1.66,0,0,0,29.35,5H27.08V7H29Z' class='clr-i-outline clr-i-outline-path-3'%3E%3C/path%3E%3Cpath d='M29,31H7V7H9V5H6.64A1.66,1.66,0,0,0,5,6.67V31.32A1.66,1.66,0,0,0,6.65,33H29.36A1.66,1.66,0,0,0,31,31.33V22.06H29Z' class='clr-i-outline clr-i-outline-path-4'%3E%3C/path%3E%3Crect x='0' y='0' width='36' height='36' fill-opacity='0'/%3E%3C/svg%3E");
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes loader {
|
@keyframes loader {
|
||||||
to {
|
to {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
|
@ -30,10 +30,5 @@ SPDX-License-Identifier: Apache-2.0
|
|||||||
<code id="manual-auth-code">{{ .Parameters.Get "code" }}</code>
|
<code id="manual-auth-code">{{ .Parameters.Get "code" }}</code>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="error" class="state" data-favicon="⛔" data-title="Error during login" hidden>
|
|
||||||
<h1>Error during login</h1>
|
|
||||||
<p id="message" class="error"></p>
|
|
||||||
<p>Please try again.</p>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -2,12 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
const transitionToState = (id, message) => {
|
const transitionToState = (id) => {
|
||||||
// For the error state, there is also a message to show.
|
|
||||||
if (id === 'error') {
|
|
||||||
document.getElementById('message').innerText = message
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide all the other ".state" <div>s.
|
// Hide all the other ".state" <div>s.
|
||||||
Array.from(document.querySelectorAll('.state')).forEach(e => e.hidden = true);
|
Array.from(document.querySelectorAll('.state')).forEach(e => e.hidden = true);
|
||||||
|
|
||||||
@ -49,31 +44,22 @@ window.onload = () => {
|
|||||||
responseParams['redirect_uri'].value,
|
responseParams['redirect_uri'].value,
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
mode: 'cors', // Using 'cors' is required to get actual response status codes.
|
mode: 'no-cors', // in the future, we could change this to "cors" (see comment below)
|
||||||
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
|
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
|
||||||
body: responseParams['encoded_params'].value,
|
body: responseParams['encoded_params'].value,
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
if (response.ok) {
|
// Requests made using "no-cors" mode will hide the real response.status by making it 0
|
||||||
// Got 2XX http response status, so the user has logged in successfully.
|
// and the real response.ok by making it false.
|
||||||
|
// If the real response was success, then we would like to show the success state.
|
||||||
|
// If the real response was an error, then we wish we could do something else (maybe show the error?),
|
||||||
|
// but we have no way to know the real response as long as we are making "no-cors" requests.
|
||||||
|
// For now, show the success status for all responses.
|
||||||
|
// In the future, we could make this request in "cors" mode once old versions of our CLI
|
||||||
|
// which did not handle CORS are upgraded out by our users. That would allow us to use
|
||||||
|
// a conditional statement based on response.ok here to decide which state to transition into.
|
||||||
transitionToState('success');
|
transitionToState('success');
|
||||||
} else {
|
|
||||||
// Got non-2XX http response status. Show the error after trying to read the response body.
|
|
||||||
// These are not recoverable errors. The CLI stop listening and is no longer prompting for authcode.
|
|
||||||
response.text()
|
|
||||||
.then(function (text) {
|
|
||||||
transitionToState('error', response.status + ": " + text);
|
|
||||||
})
|
})
|
||||||
.catch((reason) => {
|
|
||||||
console.error("error while reading response.text()", reason);
|
|
||||||
transitionToState('error', response.status + ": [could not read response body]");
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// A network error is encountered or CORS is misconfigured on the server-side.
|
|
||||||
// This could happen in the case where the CLI is running on a different machine (e.g. ssh jumphost).
|
|
||||||
// This always happens in Safari because that browser always prevents an https (TLS) web site from making
|
|
||||||
// fetch calls to an http (non-TLS) localhost site (see https://bugs.webkit.org/show_bug.cgi?id=171934).
|
|
||||||
.catch(() => transitionToState('manual'));
|
.catch(() => transitionToState('manual'));
|
||||||
};
|
};
|
||||||
|
@ -29,8 +29,8 @@ var (
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<style>body{font-family:metropolis-light,Helvetica,sans-serif}h1{font-size:20px}.state{position:absolute;top:100px;left:50%;width:400px;height:80px;margin-top:-40px;margin-left:-200px;font-size:14px;line-height:24px}button{margin:-10px;padding:10px;text-align:left;width:100%;display:inline;border:none;background:0 0;cursor:pointer;transition:all .1s}button:hover{background-color:#eee;transform:scale(1.01)}button:active{background-color:#ddd;transform:scale(.99)}code{display:block;word-wrap:break-word;word-break:break-all;font-size:12px;font-family:monospace;color:#333}.copy-icon{float:left;width:36px;height:36px;margin-top:-3px;margin-right:10px;background-size:contain;background-repeat:no-repeat;background-image:url("data:image/svg+xml,%3Csvg version='1.1' width='36' height='36' viewBox='0 0 36 36' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Ecopy-to-clipboard-line%3C/title%3E%3Cpath d='M22.6,4H21.55a3.89,3.89,0,0,0-7.31,0H13.4A2.41,2.41,0,0,0,11,6.4V10H25V6.4A2.41,2.41,0,0,0,22.6,4ZM23,8H13V6.25A.25.25,0,0,1,13.25,6h2.69l.12-1.11A1.24,1.24,0,0,1,16.61,4a2,2,0,0,1,3.15,1.18l.09.84h2.9a.25.25,0,0,1,.25.25Z' class='clr-i-outline clr-i-outline-path-1'%3E%3C/path%3E%3Cpath d='M33.25,18.06H21.33l2.84-2.83a1,1,0,1,0-1.42-1.42L17.5,19.06l5.25,5.25a1,1,0,0,0,.71.29,1,1,0,0,0,.71-1.7l-2.84-2.84H33.25a1,1,0,0,0,0-2Z' class='clr-i-outline clr-i-outline-path-2'%3E%3C/path%3E%3Cpath d='M29,16h2V6.68A1.66,1.66,0,0,0,29.35,5H27.08V7H29Z' class='clr-i-outline clr-i-outline-path-3'%3E%3C/path%3E%3Cpath d='M29,31H7V7H9V5H6.64A1.66,1.66,0,0,0,5,6.67V31.32A1.66,1.66,0,0,0,6.65,33H29.36A1.66,1.66,0,0,0,31,31.33V22.06H29Z' class='clr-i-outline clr-i-outline-path-4'%3E%3C/path%3E%3Crect x='0' y='0' width='36' height='36' fill-opacity='0'/%3E%3C/svg%3E")}.error{font-family:monospace}@keyframes loader{to{transform:rotate(360deg)}}#loading{content:'';box-sizing:border-box;width:80px;height:80px;margin-top:-40px;margin-left:-40px;border-radius:50%;border:2px solid #fff;border-top-color:#1b3951;animation:loader .6s linear infinite}</style>
|
<style>body{font-family:metropolis-light,Helvetica,sans-serif}h1{font-size:20px}.state{position:absolute;top:100px;left:50%;width:400px;height:80px;margin-top:-40px;margin-left:-200px;font-size:14px;line-height:24px}button{margin:-10px;padding:10px;text-align:left;width:100%;display:inline;border:none;background:0 0;cursor:pointer;transition:all .1s}button:hover{background-color:#eee;transform:scale(1.01)}button:active{background-color:#ddd;transform:scale(.99)}code{display:block;word-wrap:break-word;word-break:break-all;font-size:12px;font-family:monospace;color:#333}.copy-icon{float:left;width:36px;height:36px;margin-top:-3px;margin-right:10px;background-size:contain;background-repeat:no-repeat;background-image:url("data:image/svg+xml,%3Csvg version='1.1' width='36' height='36' viewBox='0 0 36 36' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Ecopy-to-clipboard-line%3C/title%3E%3Cpath d='M22.6,4H21.55a3.89,3.89,0,0,0-7.31,0H13.4A2.41,2.41,0,0,0,11,6.4V10H25V6.4A2.41,2.41,0,0,0,22.6,4ZM23,8H13V6.25A.25.25,0,0,1,13.25,6h2.69l.12-1.11A1.24,1.24,0,0,1,16.61,4a2,2,0,0,1,3.15,1.18l.09.84h2.9a.25.25,0,0,1,.25.25Z' class='clr-i-outline clr-i-outline-path-1'%3E%3C/path%3E%3Cpath d='M33.25,18.06H21.33l2.84-2.83a1,1,0,1,0-1.42-1.42L17.5,19.06l5.25,5.25a1,1,0,0,0,.71.29,1,1,0,0,0,.71-1.7l-2.84-2.84H33.25a1,1,0,0,0,0-2Z' class='clr-i-outline clr-i-outline-path-2'%3E%3C/path%3E%3Cpath d='M29,16h2V6.68A1.66,1.66,0,0,0,29.35,5H27.08V7H29Z' class='clr-i-outline clr-i-outline-path-3'%3E%3C/path%3E%3Cpath d='M29,31H7V7H9V5H6.64A1.66,1.66,0,0,0,5,6.67V31.32A1.66,1.66,0,0,0,6.65,33H29.36A1.66,1.66,0,0,0,31,31.33V22.06H29Z' class='clr-i-outline clr-i-outline-path-4'%3E%3C/path%3E%3Crect x='0' y='0' width='36' height='36' fill-opacity='0'/%3E%3C/svg%3E")}@keyframes loader{to{transform:rotate(360deg)}}#loading{content:'';box-sizing:border-box;width:80px;height:80px;margin-top:-40px;margin-left:-40px;border-radius:50%;border:2px solid #fff;border-top-color:#1b3951;animation:loader .6s linear infinite}</style>
|
||||||
<script>window.onload=()=>{const e=(e,t)=>{e==="error"&&(document.getElementById("message").innerText=t),Array.from(document.querySelectorAll(".state")).forEach(e=>e.hidden=!0);const n=document.getElementById(e);n.hidden=!1,document.title=n.dataset.title,document.getElementById("favicon").setAttribute("href","data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>"+n.dataset.favicon+"</text></svg>")};e("loading"),window.history.replaceState(null,"","./"),document.getElementById("manual-copy-button").onclick=()=>{const e=document.getElementById("manual-copy-button").innerText;navigator.clipboard.writeText(e).then(()=>console.info("copied authorization code "+e+" to clipboard")).catch(t=>console.error("failed to copy code "+e+" to clipboard: "+t))};const n=setTimeout(()=>e("manual"),2e3),t=document.forms[0].elements;fetch(t.redirect_uri.value,{method:"POST",mode:"cors",headers:{"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8"},body:t.encoded_params.value}).then(t=>{clearTimeout(n),t.ok?e("success"):t.text().then(function(n){e("error",t.status+": "+n)}).catch(n=>{console.error("error while reading response.text()",n),e("error",t.status+": [could not read response body]")})}).catch(()=>e("manual"))}</script>
|
<script>window.onload=()=>{const e=e=>{Array.from(document.querySelectorAll(".state")).forEach(e=>e.hidden=!0);const t=document.getElementById(e);t.hidden=!1,document.title=t.dataset.title,document.getElementById("favicon").setAttribute("href","data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>"+t.dataset.favicon+"</text></svg>")};e("loading"),window.history.replaceState(null,"","./"),document.getElementById("manual-copy-button").onclick=()=>{const e=document.getElementById("manual-copy-button").innerText;navigator.clipboard.writeText(e).then(()=>console.info("copied authorization code "+e+" to clipboard")).catch(t=>console.error("failed to copy code "+e+" to clipboard: "+t))};const n=setTimeout(()=>e("manual"),2e3),t=document.forms[0].elements;fetch(t.redirect_uri.value,{method:"POST",mode:"no-cors",headers:{"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8"},body:t.encoded_params.value}).then(t=>{clearTimeout(n),e("success")}).catch(()=>e("manual"))}</script>
|
||||||
<link id="favicon" rel="icon"/>
|
<link id="favicon" rel="icon"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -54,11 +54,6 @@ var (
|
|||||||
<code id="manual-auth-code">test-S629KHsCCBYV0PQ6FDSrn6iEXtVImQRBh7NCAk.JezyUSdCiSslYjtUmv7V5VAgiCz3ZkES9mYldg9GhqU</code>
|
<code id="manual-auth-code">test-S629KHsCCBYV0PQ6FDSrn6iEXtVImQRBh7NCAk.JezyUSdCiSslYjtUmv7V5VAgiCz3ZkES9mYldg9GhqU</code>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="error" class="state" data-favicon="⛔" data-title="Error during login" hidden>
|
|
||||||
<h1>Error during login</h1>
|
|
||||||
<p id="message" class="error"></p>
|
|
||||||
<p>Please try again.</p>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`)
|
`)
|
||||||
@ -66,8 +61,8 @@ var (
|
|||||||
// It's okay if this changes in the future, but this gives us a chance to eyeball the formatting.
|
// It's okay if this changes in the future, but this gives us a chance to eyeball the formatting.
|
||||||
// Our browser-based integration tests should find any incompatibilities.
|
// Our browser-based integration tests should find any incompatibilities.
|
||||||
testExpectedCSP = `default-src 'none'; ` +
|
testExpectedCSP = `default-src 'none'; ` +
|
||||||
`script-src 'sha256-fiAdxAQHPoodG4cbENki/1TI+cjBOXxw+ADCoCtepQo='; ` +
|
`script-src 'sha256-uIWC0J7wd7tWtcXmugZCkKsQpqOsQzqBI/mfQMtUde0='; ` +
|
||||||
`style-src 'sha256-p+fPKq5SYyVeT46EkDVZx28MRQ6wlWHdDm3o3qZFGTA='; ` +
|
`style-src 'sha256-kXh6OrB2z7wkx7v1N3ay9deQhV5edwuogARaUtvNYN4='; ` +
|
||||||
`img-src data:; ` +
|
`img-src data:; ` +
|
||||||
`connect-src *; ` +
|
`connect-src *; ` +
|
||||||
`frame-ancestors 'none'`
|
`frame-ancestors 'none'`
|
||||||
|
@ -37,7 +37,6 @@ const (
|
|||||||
AuthorizationEndpointPath = "/oauth2/authorize"
|
AuthorizationEndpointPath = "/oauth2/authorize"
|
||||||
TokenEndpointPath = "/oauth2/token" //nolint:gosec // ignore lint warning that this is a credential
|
TokenEndpointPath = "/oauth2/token" //nolint:gosec // ignore lint warning that this is a credential
|
||||||
CallbackEndpointPath = "/callback"
|
CallbackEndpointPath = "/callback"
|
||||||
ChooseIDPEndpointPath = "/choose_identity_provider"
|
|
||||||
JWKSEndpointPath = "/jwks.json"
|
JWKSEndpointPath = "/jwks.json"
|
||||||
PinnipedIDPsPathV1Alpha1 = "/v1alpha1/pinniped_identity_providers"
|
PinnipedIDPsPathV1Alpha1 = "/v1alpha1/pinniped_identity_providers"
|
||||||
PinnipedLoginPath = "/login"
|
PinnipedLoginPath = "/login"
|
||||||
@ -144,10 +143,7 @@ func FositeOauth2Helper(
|
|||||||
RefreshTokenLifespan: timeoutsConfiguration.RefreshTokenLifespan,
|
RefreshTokenLifespan: timeoutsConfiguration.RefreshTokenLifespan,
|
||||||
|
|
||||||
ScopeStrategy: fosite.ExactScopeStrategy,
|
ScopeStrategy: fosite.ExactScopeStrategy,
|
||||||
// The only public client is pinniped-cli, so this combination of PKCE settings requires PKCE for the
|
EnforcePKCE: true,
|
||||||
// pinniped-cli client and does not require PKCE for any dynamically configured OIDCClients.
|
|
||||||
EnforcePKCE: false,
|
|
||||||
EnforcePKCEForPublicClients: true,
|
|
||||||
|
|
||||||
// "offline_access" as per https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
// "offline_access" as per https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
||||||
RefreshTokenScopes: []string{oidcapi.ScopeOfflineAccess},
|
RefreshTokenScopes: []string{oidcapi.ScopeOfflineAccess},
|
||||||
|
@ -233,7 +233,7 @@ func TestPlog(t *testing.T) {
|
|||||||
testAllPlogMethods(l.withDepth(-2))
|
testAllPlogMethods(l.withDepth(-2))
|
||||||
},
|
},
|
||||||
want: `
|
want: `
|
||||||
{"level":"error","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Error","message":"e","panda":2,"error":"some err"}
|
{"level":"error","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Error","message":"e","panda":2,"error":"some err"}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.warningDepth","message":"w","warning":true,"panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.warningDepth","message":"w","warning":true,"panda":2}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.warningDepth","message":"we","warning":true,"error":"some err","panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.warningDepth","message":"we","warning":true,"error":"some err","panda":2}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.infoDepth","message":"i","panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.infoDepth","message":"i","panda":2}
|
||||||
@ -242,8 +242,8 @@ func TestPlog(t *testing.T) {
|
|||||||
{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.debugDepth","message":"de","error":"some err","panda":2}
|
{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.debugDepth","message":"de","error":"some err","panda":2}
|
||||||
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.traceDepth","message":"t","panda":2}
|
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.traceDepth","message":"t","panda":2}
|
||||||
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.traceDepth","message":"te","error":"some err","panda":2}
|
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"plog/plog.go:<line>$plog.pLogger.traceDepth","message":"te","error":"some err","panda":2}
|
||||||
{"level":"all","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"all","panda":2}
|
{"level":"all","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"all","panda":2}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"always","panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"always","panda":2}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -253,14 +253,14 @@ func TestPlog(t *testing.T) {
|
|||||||
},
|
},
|
||||||
want: `
|
want: `
|
||||||
{"level":"error","timestamp":"2099-08-08T13:57:36.123456Z","caller":"zapr@v1.2.4/zapr.go:<line>$zapr.(*zapLogger).Error","message":"e","panda":2,"error":"some err"}
|
{"level":"error","timestamp":"2099-08-08T13:57:36.123456Z","caller":"zapr@v1.2.4/zapr.go:<line>$zapr.(*zapLogger).Error","message":"e","panda":2,"error":"some err"}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"w","warning":true,"panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"w","warning":true,"panda":2}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"we","warning":true,"error":"some err","panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"we","warning":true,"error":"some err","panda":2}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"i","panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"i","panda":2}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"ie","error":"some err","panda":2}
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"ie","error":"some err","panda":2}
|
||||||
{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"d","panda":2}
|
{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"d","panda":2}
|
||||||
{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"de","error":"some err","panda":2}
|
{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"de","error":"some err","panda":2}
|
||||||
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"t","panda":2}
|
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"t","panda":2}
|
||||||
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.3.0/logr.go:<line>$logr.Logger.Info","message":"te","error":"some err","panda":2}
|
{"level":"trace","timestamp":"2099-08-08T13:57:36.123456Z","caller":"logr@v1.2.4/logr.go:<line>$logr.Logger.Info","message":"te","error":"some err","panda":2}
|
||||||
{"level":"all","timestamp":"2099-08-08T13:57:36.123456Z","caller":"zapr@v1.2.4/zapr.go:<line>$zapr.(*zapLogger).Info","message":"all","panda":2}
|
{"level":"all","timestamp":"2099-08-08T13:57:36.123456Z","caller":"zapr@v1.2.4/zapr.go:<line>$zapr.(*zapLogger).Info","message":"all","panda":2}
|
||||||
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"zapr@v1.2.4/zapr.go:<line>$zapr.(*zapLogger).Info","message":"always","panda":2}`,
|
{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","caller":"zapr@v1.2.4/zapr.go:<line>$zapr.(*zapLogger).Info","message":"always","panda":2}`,
|
||||||
},
|
},
|
||||||
|
@ -99,19 +99,6 @@ func RequireSecurityHeadersWithLoginPageCSPs(t *testing.T, response *httptest.Re
|
|||||||
requireSecurityHeaders(t, response)
|
requireSecurityHeaders(t, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RequireSecurityHeadersWithIDPChooserPageCSPs(t *testing.T, response *httptest.ResponseRecorder) {
|
|
||||||
// Loosely confirm that the unique CSPs needed for the login page were used.
|
|
||||||
cspHeader := response.Header().Get("Content-Security-Policy")
|
|
||||||
require.Contains(t, cspHeader, "style-src '") // loose assertion
|
|
||||||
require.Contains(t, cspHeader, "script-src '") // loose assertion
|
|
||||||
require.Contains(t, cspHeader, "style-src '") // loose assertion
|
|
||||||
require.Contains(t, cspHeader, "img-src data:")
|
|
||||||
require.NotContains(t, cspHeader, "connect-src *") // only needed by form_post page
|
|
||||||
|
|
||||||
// Also require all the usual security headers.
|
|
||||||
requireSecurityHeaders(t, response)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RequireSecurityHeadersWithoutCustomCSPs(t *testing.T, response *httptest.ResponseRecorder) {
|
func RequireSecurityHeadersWithoutCustomCSPs(t *testing.T, response *httptest.ResponseRecorder) {
|
||||||
// Confirm that the unique CSPs needed for the form_post or login page were NOT used.
|
// Confirm that the unique CSPs needed for the form_post or login page were NOT used.
|
||||||
cspHeader := response.Header().Get("Content-Security-Policy")
|
cspHeader := response.Header().Get("Content-Security-Policy")
|
||||||
|
File diff suppressed because one or more lines are too long
@ -467,14 +467,6 @@ type TestFederationDomainIdentityProvidersListerFinder struct {
|
|||||||
defaultIDPDisplayName string
|
defaultIDPDisplayName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestFederationDomainIdentityProvidersListerFinder) HasDefaultIDP() bool {
|
|
||||||
return t.defaultIDPDisplayName != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestFederationDomainIdentityProvidersListerFinder) IDPCount() int {
|
|
||||||
return len(t.upstreamOIDCIdentityProviders) + len(t.upstreamLDAPIdentityProviders) + len(t.upstreamActiveDirectoryIdentityProviders)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestFederationDomainIdentityProvidersListerFinder) GetOIDCIdentityProviders() []*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider {
|
func (t *TestFederationDomainIdentityProvidersListerFinder) GetOIDCIdentityProviders() []*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider {
|
||||||
fdIDPs := make([]*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider, len(t.upstreamOIDCIdentityProviders))
|
fdIDPs := make([]*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider, len(t.upstreamOIDCIdentityProviders))
|
||||||
for i, testIDP := range t.upstreamOIDCIdentityProviders {
|
for i, testIDP := range t.upstreamOIDCIdentityProviders {
|
||||||
|
@ -56,8 +56,8 @@ const (
|
|||||||
// we set this to be relatively long.
|
// we set this to be relatively long.
|
||||||
overallTimeout = 90 * time.Minute
|
overallTimeout = 90 * time.Minute
|
||||||
|
|
||||||
usernamePrompt = "Username: "
|
defaultLDAPUsernamePrompt = "Username: "
|
||||||
passwordPrompt = "Password: "
|
defaultLDAPPasswordPrompt = "Password: "
|
||||||
|
|
||||||
// For CLI-based auth, such as with LDAP upstream identity providers, the user may use these environment variables
|
// For CLI-based auth, such as with LDAP upstream identity providers, the user may use these environment variables
|
||||||
// to avoid getting interactively prompted for username and password.
|
// to avoid getting interactively prompted for username and password.
|
||||||
@ -78,7 +78,6 @@ type handlerState struct {
|
|||||||
clientID string
|
clientID string
|
||||||
scopes []string
|
scopes []string
|
||||||
cache SessionCache
|
cache SessionCache
|
||||||
out io.Writer
|
|
||||||
|
|
||||||
upstreamIdentityProviderName string
|
upstreamIdentityProviderName string
|
||||||
upstreamIdentityProviderType string
|
upstreamIdentityProviderType string
|
||||||
@ -110,8 +109,8 @@ type handlerState struct {
|
|||||||
isTTY func(int) bool
|
isTTY func(int) bool
|
||||||
getProvider func(*oauth2.Config, *coreosoidc.Provider, *http.Client) upstreamprovider.UpstreamOIDCIdentityProviderI
|
getProvider func(*oauth2.Config, *coreosoidc.Provider, *http.Client) upstreamprovider.UpstreamOIDCIdentityProviderI
|
||||||
validateIDToken func(ctx context.Context, provider *coreosoidc.Provider, audience string, token string) (*coreosoidc.IDToken, error)
|
validateIDToken func(ctx context.Context, provider *coreosoidc.Provider, audience string, token string) (*coreosoidc.IDToken, error)
|
||||||
promptForValue func(ctx context.Context, promptLabel string, out io.Writer) (string, error)
|
promptForValue func(ctx context.Context, promptLabel string) (string, error)
|
||||||
promptForSecret func(promptLabel string, out io.Writer) (string, error)
|
promptForSecret func(promptLabel string) (string, error)
|
||||||
|
|
||||||
callbacks chan callbackResult
|
callbacks chan callbackResult
|
||||||
}
|
}
|
||||||
@ -293,7 +292,6 @@ func Login(issuer string, clientID string, opts ...Option) (*oidctypes.Token, er
|
|||||||
},
|
},
|
||||||
promptForValue: promptForValue,
|
promptForValue: promptForValue,
|
||||||
promptForSecret: promptForSecret,
|
promptForSecret: promptForSecret,
|
||||||
out: os.Stderr,
|
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
if err := opt(&h); err != nil {
|
if err := opt(&h); err != nil {
|
||||||
@ -513,13 +511,9 @@ func (h *handlerState) cliBasedAuth(authorizeOptions *[]oauth2.AuthCodeOption) (
|
|||||||
func (h *handlerState) getUsernameAndPassword() (string, string, error) {
|
func (h *handlerState) getUsernameAndPassword() (string, string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if h.upstreamIdentityProviderName != "" {
|
|
||||||
_, _ = fmt.Fprintf(h.out, "\nLog in to %s\n\n", h.upstreamIdentityProviderName)
|
|
||||||
}
|
|
||||||
|
|
||||||
username := h.getEnv(defaultUsernameEnvVarName)
|
username := h.getEnv(defaultUsernameEnvVarName)
|
||||||
if username == "" {
|
if username == "" {
|
||||||
username, err = h.promptForValue(h.ctx, usernamePrompt, h.out)
|
username, err = h.promptForValue(h.ctx, defaultLDAPUsernamePrompt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("error prompting for username: %w", err)
|
return "", "", fmt.Errorf("error prompting for username: %w", err)
|
||||||
}
|
}
|
||||||
@ -529,7 +523,7 @@ func (h *handlerState) getUsernameAndPassword() (string, string, error) {
|
|||||||
|
|
||||||
password := h.getEnv(defaultPasswordEnvVarName)
|
password := h.getEnv(defaultPasswordEnvVarName)
|
||||||
if password == "" {
|
if password == "" {
|
||||||
password, err = h.promptForSecret(passwordPrompt, h.out)
|
password, err = h.promptForSecret(defaultLDAPPasswordPrompt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("error prompting for password: %w", err)
|
return "", "", fmt.Errorf("error prompting for password: %w", err)
|
||||||
}
|
}
|
||||||
@ -587,7 +581,7 @@ func (h *handlerState) webBrowserBasedAuth(authorizeOptions *[]oauth2.AuthCodeOp
|
|||||||
|
|
||||||
// Prompt the user to visit the authorize URL, and to paste a manually-copied auth code (if possible).
|
// Prompt the user to visit the authorize URL, and to paste a manually-copied auth code (if possible).
|
||||||
ctx, cancel := context.WithCancel(h.ctx)
|
ctx, cancel := context.WithCancel(h.ctx)
|
||||||
cleanupPrompt := h.promptForWebLogin(ctx, authorizeURL)
|
cleanupPrompt := h.promptForWebLogin(ctx, authorizeURL, os.Stderr)
|
||||||
defer func() {
|
defer func() {
|
||||||
cancel()
|
cancel()
|
||||||
cleanupPrompt()
|
cleanupPrompt()
|
||||||
@ -605,8 +599,8 @@ func (h *handlerState) webBrowserBasedAuth(authorizeOptions *[]oauth2.AuthCodeOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handlerState) promptForWebLogin(ctx context.Context, authorizeURL string) func() {
|
func (h *handlerState) promptForWebLogin(ctx context.Context, authorizeURL string, out io.Writer) func() {
|
||||||
_, _ = fmt.Fprintf(h.out, "Log in by visiting this link:\n\n %s\n\n", authorizeURL)
|
_, _ = fmt.Fprintf(out, "Log in by visiting this link:\n\n %s\n\n", authorizeURL)
|
||||||
|
|
||||||
// If stdin is not a TTY, print the URL but don't prompt for the manual paste,
|
// If stdin is not a TTY, print the URL but don't prompt for the manual paste,
|
||||||
// since we have no way of reading it.
|
// since we have no way of reading it.
|
||||||
@ -627,15 +621,15 @@ func (h *handlerState) promptForWebLogin(ctx context.Context, authorizeURL strin
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
// Always emit a newline so the kubectl output is visually separated from the login prompts.
|
// Always emit a newline so the kubectl output is visually separated from the login prompts.
|
||||||
_, _ = fmt.Fprintln(h.out)
|
_, _ = fmt.Fprintln(os.Stderr)
|
||||||
|
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
code, err := h.promptForValue(ctx, " Optionally, paste your authorization code: ", h.out)
|
code, err := h.promptForValue(ctx, " Optionally, paste your authorization code: ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Print a visual marker to show the the prompt is no longer waiting for user input, plus a trailing
|
// Print a visual marker to show the the prompt is no longer waiting for user input, plus a trailing
|
||||||
// newline that simulates the user having pressed "enter".
|
// newline that simulates the user having pressed "enter".
|
||||||
_, _ = fmt.Fprint(h.out, "[...]\n")
|
_, _ = fmt.Fprint(os.Stderr, "[...]\n")
|
||||||
|
|
||||||
h.callbacks <- callbackResult{err: fmt.Errorf("failed to prompt for manual authorization code: %v", err)}
|
h.callbacks <- callbackResult{err: fmt.Errorf("failed to prompt for manual authorization code: %v", err)}
|
||||||
return
|
return
|
||||||
@ -648,11 +642,11 @@ func (h *handlerState) promptForWebLogin(ctx context.Context, authorizeURL strin
|
|||||||
return wg.Wait
|
return wg.Wait
|
||||||
}
|
}
|
||||||
|
|
||||||
func promptForValue(ctx context.Context, promptLabel string, out io.Writer) (string, error) {
|
func promptForValue(ctx context.Context, promptLabel string) (string, error) {
|
||||||
if !term.IsTerminal(stdin()) {
|
if !term.IsTerminal(stdin()) {
|
||||||
return "", errors.New("stdin is not connected to a terminal")
|
return "", errors.New("stdin is not connected to a terminal")
|
||||||
}
|
}
|
||||||
_, err := fmt.Fprint(out, promptLabel)
|
_, err := fmt.Fprint(os.Stderr, promptLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not print prompt to stderr: %w", err)
|
return "", fmt.Errorf("could not print prompt to stderr: %w", err)
|
||||||
}
|
}
|
||||||
@ -680,11 +674,11 @@ func promptForValue(ctx context.Context, promptLabel string, out io.Writer) (str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func promptForSecret(promptLabel string, out io.Writer) (string, error) {
|
func promptForSecret(promptLabel string) (string, error) {
|
||||||
if !term.IsTerminal(stdin()) {
|
if !term.IsTerminal(stdin()) {
|
||||||
return "", errors.New("stdin is not connected to a terminal")
|
return "", errors.New("stdin is not connected to a terminal")
|
||||||
}
|
}
|
||||||
_, err := fmt.Fprint(out, promptLabel)
|
_, err := fmt.Fprint(os.Stderr, promptLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not print prompt to stderr: %w", err)
|
return "", fmt.Errorf("could not print prompt to stderr: %w", err)
|
||||||
}
|
}
|
||||||
@ -695,7 +689,7 @@ func promptForSecret(promptLabel string, out io.Writer) (string, error) {
|
|||||||
// term.ReadPassword swallows the newline that was typed by the user, so to
|
// term.ReadPassword swallows the newline that was typed by the user, so to
|
||||||
// avoid the next line of output from happening on same line as the password
|
// avoid the next line of output from happening on same line as the password
|
||||||
// prompt, we need to print a newline.
|
// prompt, we need to print a newline.
|
||||||
_, err = fmt.Fprint(out, "\n")
|
_, err = fmt.Fprint(os.Stderr, "\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not print newline to stderr: %w", err)
|
return "", fmt.Errorf("could not print newline to stderr: %w", err)
|
||||||
}
|
}
|
||||||
@ -928,7 +922,7 @@ func (h *handlerState) handleAuthCodeCallback(w http.ResponseWriter, r *http.Req
|
|||||||
w.Header().Set("Access-Control-Allow-Origin", allowOrigin)
|
w.Header().Set("Access-Control-Allow-Origin", allowOrigin)
|
||||||
w.Header().Set("Vary", "*") // supposed to use Vary when Access-Control-Allow-Origin is a specific host
|
w.Header().Set("Vary", "*") // supposed to use Vary when Access-Control-Allow-Origin is a specific host
|
||||||
} else {
|
} else {
|
||||||
// When we are not using form_post, then return HTTP 405 for anything that's not a GET.
|
// Return HTTP 405 for anything that's not a GET.
|
||||||
if r.Method != http.MethodGet {
|
if r.Method != http.MethodGet {
|
||||||
h.logger.V(plog.KlogLevelDebug).Info("Pinniped: Got unexpected request on callback listener", "method", r.Method)
|
h.logger.V(plog.KlogLevelDebug).Info("Pinniped: Got unexpected request on callback listener", "method", r.Method)
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
@ -939,9 +933,6 @@ func (h *handlerState) handleAuthCodeCallback(w http.ResponseWriter, r *http.Req
|
|||||||
params = r.URL.Query()
|
params = r.URL.Query()
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, it doesn't matter if we got the params from a form_post POST request or a regular GET request.
|
|
||||||
// Next, validate the params, and if we got an authcode then try to use it to complete the login.
|
|
||||||
|
|
||||||
// Validate OAuth2 state and fail if it's incorrect (to block CSRF).
|
// Validate OAuth2 state and fail if it's incorrect (to block CSRF).
|
||||||
if err := h.state.Validate(params.Get("state")); err != nil {
|
if err := h.state.Validate(params.Get("state")); err != nil {
|
||||||
return httperr.New(http.StatusForbidden, "missing or invalid state parameter")
|
return httperr.New(http.StatusForbidden, "missing or invalid state parameter")
|
||||||
|
@ -15,8 +15,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
@ -79,11 +77,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
time1Unix := int64(2075807775)
|
time1Unix := int64(2075807775)
|
||||||
require.Equal(t, time1Unix, time1.Add(2*time.Minute).Unix())
|
require.Equal(t, time1Unix, time1.Add(2*time.Minute).Unix())
|
||||||
|
|
||||||
// This is the PKCE challenge which is calculated as base64(sha256("test-pkce")). For example:
|
|
||||||
// $ echo -n test-pkce | shasum -a 256 | cut -d" " -f1 | xxd -r -p | base64 | cut -d"=" -f1
|
|
||||||
// VVaezYqum7reIhoavCHD1n2d+piN3r/mywoYj7fCR7g
|
|
||||||
const testCodeChallenge = "VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g"
|
|
||||||
|
|
||||||
testToken := oidctypes.Token{
|
testToken := oidctypes.Token{
|
||||||
AccessToken: &oidctypes.AccessToken{Token: "test-access-token", Expiry: metav1.NewTime(time1.Add(1 * time.Minute))},
|
AccessToken: &oidctypes.AccessToken{Token: "test-access-token", Expiry: metav1.NewTime(time1.Add(1 * time.Minute))},
|
||||||
RefreshToken: &oidctypes.RefreshToken{Token: "test-refresh-token"},
|
RefreshToken: &oidctypes.RefreshToken{Token: "test-refresh-token"},
|
||||||
@ -323,10 +316,8 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
h.generateState = func() (state.State, error) { return "test-state", nil }
|
h.generateState = func() (state.State, error) { return "test-state", nil }
|
||||||
h.generatePKCE = func() (pkce.Code, error) { return "test-pkce", nil }
|
h.generatePKCE = func() (pkce.Code, error) { return "test-pkce", nil }
|
||||||
h.generateNonce = func() (nonce.Nonce, error) { return "test-nonce", nil }
|
h.generateNonce = func() (nonce.Nonce, error) { return "test-nonce", nil }
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) { return "some-upstream-username", nil }
|
||||||
return "some-upstream-username", nil
|
h.promptForSecret = func(_ string) (string, error) { return "some-upstream-password", nil }
|
||||||
}
|
|
||||||
h.promptForSecret = func(_ string, _ io.Writer) (string, error) { return "some-upstream-password", nil }
|
|
||||||
|
|
||||||
cache := &mockSessionCache{t: t, getReturnsToken: nil}
|
cache := &mockSessionCache{t: t, getReturnsToken: nil}
|
||||||
cacheKey := SessionCacheKey{
|
cacheKey := SessionCacheKey{
|
||||||
@ -368,7 +359,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
wantErr string
|
wantErr string
|
||||||
wantToken *oidctypes.Token
|
wantToken *oidctypes.Token
|
||||||
wantLogs []string
|
wantLogs []string
|
||||||
wantStdErr string
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "option error",
|
name: "option error",
|
||||||
@ -709,9 +699,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
name: "listening disabled and manual prompt fails",
|
name: "listening disabled and manual prompt fails",
|
||||||
opt: func(t *testing.T) Option {
|
opt: func(t *testing.T) Option {
|
||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
h.generateState = func() (state.State, error) { return "test-state", nil }
|
|
||||||
h.generatePKCE = func() (pkce.Code, error) { return "test-pkce", nil }
|
|
||||||
h.generateNonce = func() (nonce.Nonce, error) { return "test-nonce", nil }
|
|
||||||
require.NoError(t, WithClient(newClientForServer(formPostSuccessServer))(h))
|
require.NoError(t, WithClient(newClientForServer(formPostSuccessServer))(h))
|
||||||
require.NoError(t, WithSkipListen()(h))
|
require.NoError(t, WithSkipListen()(h))
|
||||||
h.isTTY = func(fd int) bool { return true }
|
h.isTTY = func(fd int) bool { return true }
|
||||||
@ -722,7 +709,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
require.Equal(t, "form_post", parsed.Query().Get("response_mode"))
|
require.Equal(t, "form_post", parsed.Query().Get("response_mode"))
|
||||||
return fmt.Errorf("some browser open error")
|
return fmt.Errorf("some browser open error")
|
||||||
}
|
}
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
return "", fmt.Errorf("some prompt error")
|
return "", fmt.Errorf("some prompt error")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -733,24 +720,12 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
`"level"=4 "msg"="Pinniped: Performing OIDC discovery" "issuer"="` + formPostSuccessServer.URL + `"`,
|
`"level"=4 "msg"="Pinniped: Performing OIDC discovery" "issuer"="` + formPostSuccessServer.URL + `"`,
|
||||||
`"msg"="could not open browser" "error"="some browser open error"`,
|
`"msg"="could not open browser" "error"="some browser open error"`,
|
||||||
},
|
},
|
||||||
wantStdErr: "^" +
|
|
||||||
regexp.QuoteMeta("Log in by visiting this link:\n\n") +
|
|
||||||
regexp.QuoteMeta(" https://127.0.0.1:") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("/authorize?access_type=offline&client_id=&code_challenge="+testCodeChallenge+
|
|
||||||
"&code_challenge_method=S256&nonce=test-nonce&redirect_uri=http%3A%2F%2F127.0.0.1%3A0%2Fcallback"+
|
|
||||||
"&response_mode=form_post&response_type=code&scope=test-scope&state=test-state") +
|
|
||||||
regexp.QuoteMeta("\n\n[...]\n\n") +
|
|
||||||
"$",
|
|
||||||
wantErr: "error handling callback: failed to prompt for manual authorization code: some prompt error",
|
wantErr: "error handling callback: failed to prompt for manual authorization code: some prompt error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "listen success and manual prompt succeeds",
|
name: "listen success and manual prompt succeeds",
|
||||||
opt: func(t *testing.T) Option {
|
opt: func(t *testing.T) Option {
|
||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
h.generateState = func() (state.State, error) { return "test-state", nil }
|
|
||||||
h.generatePKCE = func() (pkce.Code, error) { return "test-pkce", nil }
|
|
||||||
h.generateNonce = func() (nonce.Nonce, error) { return "test-nonce", nil }
|
|
||||||
require.NoError(t, WithClient(newClientForServer(formPostSuccessServer))(h))
|
require.NoError(t, WithClient(newClientForServer(formPostSuccessServer))(h))
|
||||||
h.listen = func(string, string) (net.Listener, error) { return nil, fmt.Errorf("some listen error") }
|
h.listen = func(string, string) (net.Listener, error) { return nil, fmt.Errorf("some listen error") }
|
||||||
h.isTTY = func(fd int) bool { return true }
|
h.isTTY = func(fd int) bool { return true }
|
||||||
@ -761,7 +736,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
require.Equal(t, "form_post", parsed.Query().Get("response_mode"))
|
require.Equal(t, "form_post", parsed.Query().Get("response_mode"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
return "", fmt.Errorf("some prompt error")
|
return "", fmt.Errorf("some prompt error")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -772,25 +747,12 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
`"level"=4 "msg"="Pinniped: Performing OIDC discovery" "issuer"="` + formPostSuccessServer.URL + `"`,
|
`"level"=4 "msg"="Pinniped: Performing OIDC discovery" "issuer"="` + formPostSuccessServer.URL + `"`,
|
||||||
`"msg"="could not open callback listener" "error"="some listen error"`,
|
`"msg"="could not open callback listener" "error"="some listen error"`,
|
||||||
},
|
},
|
||||||
wantStdErr: "^" +
|
|
||||||
regexp.QuoteMeta("Log in by visiting this link:\n\n") +
|
|
||||||
regexp.QuoteMeta(" https://127.0.0.1:") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("/authorize?access_type=offline&client_id=&code_challenge="+testCodeChallenge+
|
|
||||||
"&code_challenge_method=S256&nonce=test-nonce&redirect_uri=http%3A%2F%2F127.0.0.1%3A0%2Fcallback"+
|
|
||||||
"&response_mode=form_post&response_type=code&scope=test-scope&state=test-state") +
|
|
||||||
regexp.QuoteMeta("\n\n[...]\n\n") +
|
|
||||||
"$",
|
|
||||||
wantErr: "error handling callback: failed to prompt for manual authorization code: some prompt error",
|
wantErr: "error handling callback: failed to prompt for manual authorization code: some prompt error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "timeout waiting for callback",
|
name: "timeout waiting for callback",
|
||||||
opt: func(t *testing.T) Option {
|
opt: func(t *testing.T) Option {
|
||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
h.generateState = func() (state.State, error) { return "test-state", nil }
|
|
||||||
h.generatePKCE = func() (pkce.Code, error) { return "test-pkce", nil }
|
|
||||||
h.generateNonce = func() (nonce.Nonce, error) { return "test-nonce", nil }
|
|
||||||
|
|
||||||
require.NoError(t, WithClient(newClientForServer(successServer))(h))
|
require.NoError(t, WithClient(newClientForServer(successServer))(h))
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(h.ctx)
|
ctx, cancel := context.WithCancel(h.ctx)
|
||||||
@ -805,25 +767,12 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^" +
|
|
||||||
regexp.QuoteMeta("Log in by visiting this link:\n\n") +
|
|
||||||
regexp.QuoteMeta(" https://127.0.0.1:") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("/authorize?access_type=offline&client_id=&code_challenge="+testCodeChallenge+
|
|
||||||
"&code_challenge_method=S256&nonce=test-nonce&redirect_uri=http%3A%2F%2F127.0.0.1%3A") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("%2Fcallback&response_type=code&scope=test-scope&state=test-state") +
|
|
||||||
regexp.QuoteMeta("\n\n") +
|
|
||||||
"$",
|
|
||||||
wantErr: "timed out waiting for token callback: context canceled",
|
wantErr: "timed out waiting for token callback: context canceled",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "callback returns error",
|
name: "callback returns error",
|
||||||
opt: func(t *testing.T) Option {
|
opt: func(t *testing.T) Option {
|
||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
h.generateState = func() (state.State, error) { return "test-state", nil }
|
|
||||||
h.generatePKCE = func() (pkce.Code, error) { return "test-pkce", nil }
|
|
||||||
h.generateNonce = func() (nonce.Nonce, error) { return "test-nonce", nil }
|
|
||||||
require.NoError(t, WithClient(newClientForServer(successServer))(h))
|
require.NoError(t, WithClient(newClientForServer(successServer))(h))
|
||||||
h.openURL = func(_ string) error {
|
h.openURL = func(_ string) error {
|
||||||
go func() {
|
go func() {
|
||||||
@ -836,16 +785,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^" +
|
|
||||||
regexp.QuoteMeta("Log in by visiting this link:\n\n") +
|
|
||||||
regexp.QuoteMeta(" https://127.0.0.1:") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("/authorize?access_type=offline&client_id=&code_challenge="+testCodeChallenge+
|
|
||||||
"&code_challenge_method=S256&nonce=test-nonce&redirect_uri=http%3A%2F%2F127.0.0.1%3A") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("%2Fcallback&response_type=code&scope=test-scope&state=test-state") +
|
|
||||||
regexp.QuoteMeta("\n\n") +
|
|
||||||
"$",
|
|
||||||
wantErr: "error handling callback: some callback error",
|
wantErr: "error handling callback: some callback error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -884,7 +823,10 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
actualParams.Del("redirect_uri")
|
actualParams.Del("redirect_uri")
|
||||||
|
|
||||||
require.Equal(t, url.Values{
|
require.Equal(t, url.Values{
|
||||||
"code_challenge": []string{testCodeChallenge},
|
// This is the PKCE challenge which is calculated as base64(sha256("test-pkce")). For example:
|
||||||
|
// $ echo -n test-pkce | shasum -a 256 | cut -d" " -f1 | xxd -r -p | base64 | cut -d"=" -f1
|
||||||
|
// VVaezYqum7reIhoavCHD1n2d+piN3r/mywoYj7fCR7g
|
||||||
|
"code_challenge": []string{"VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g"},
|
||||||
"code_challenge_method": []string{"S256"},
|
"code_challenge_method": []string{"S256"},
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
"scope": []string{"test-scope"},
|
"scope": []string{"test-scope"},
|
||||||
@ -907,16 +849,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^" +
|
|
||||||
regexp.QuoteMeta("Log in by visiting this link:\n\n") +
|
|
||||||
regexp.QuoteMeta(" https://127.0.0.1:") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("/authorize?access_type=offline&client_id=test-client-id&code_challenge="+testCodeChallenge+
|
|
||||||
"&code_challenge_method=S256&nonce=test-nonce&redirect_uri=http%3A%2F%2F127.0.0.1%3A") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("%2Fcallback&response_type=code&scope=test-scope&state=test-state") +
|
|
||||||
regexp.QuoteMeta("\n\n") +
|
|
||||||
"$",
|
|
||||||
wantToken: &testToken,
|
wantToken: &testToken,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -955,7 +887,10 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
actualParams.Del("redirect_uri")
|
actualParams.Del("redirect_uri")
|
||||||
|
|
||||||
require.Equal(t, url.Values{
|
require.Equal(t, url.Values{
|
||||||
"code_challenge": []string{testCodeChallenge},
|
// This is the PKCE challenge which is calculated as base64(sha256("test-pkce")). For example:
|
||||||
|
// $ echo -n test-pkce | shasum -a 256 | cut -d" " -f1 | xxd -r -p | base64 | cut -d"=" -f1
|
||||||
|
// VVaezYqum7reIhoavCHD1n2d+piN3r/mywoYj7fCR7g
|
||||||
|
"code_challenge": []string{"VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g"},
|
||||||
"code_challenge_method": []string{"S256"},
|
"code_challenge_method": []string{"S256"},
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
"response_mode": []string{"form_post"},
|
"response_mode": []string{"form_post"},
|
||||||
@ -979,16 +914,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: formPostSuccessServer.URL,
|
issuer: formPostSuccessServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + formPostSuccessServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + formPostSuccessServer.URL + "\""},
|
||||||
wantStdErr: "^" +
|
|
||||||
regexp.QuoteMeta("Log in by visiting this link:\n\n") +
|
|
||||||
regexp.QuoteMeta(" https://127.0.0.1:") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("/authorize?access_type=offline&client_id=test-client-id&code_challenge="+testCodeChallenge+
|
|
||||||
"&code_challenge_method=S256&nonce=test-nonce&redirect_uri=http%3A%2F%2F127.0.0.1%3A") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("%2Fcallback&response_mode=form_post&response_type=code&scope=test-scope&state=test-state") +
|
|
||||||
regexp.QuoteMeta("\n\n") +
|
|
||||||
"$",
|
|
||||||
wantToken: &testToken,
|
wantToken: &testToken,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1029,7 +954,10 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
actualParams.Del("redirect_uri")
|
actualParams.Del("redirect_uri")
|
||||||
|
|
||||||
require.Equal(t, url.Values{
|
require.Equal(t, url.Values{
|
||||||
"code_challenge": []string{testCodeChallenge},
|
// This is the PKCE challenge which is calculated as base64(sha256("test-pkce")). For example:
|
||||||
|
// $ echo -n test-pkce | shasum -a 256 | cut -d" " -f1 | xxd -r -p | base64 | cut -d"=" -f1
|
||||||
|
// VVaezYqum7reIhoavCHD1n2d+piN3r/mywoYj7fCR7g
|
||||||
|
"code_challenge": []string{"VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g"},
|
||||||
"code_challenge_method": []string{"S256"},
|
"code_challenge_method": []string{"S256"},
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
"scope": []string{"test-scope"},
|
"scope": []string{"test-scope"},
|
||||||
@ -1054,17 +982,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^" +
|
|
||||||
regexp.QuoteMeta("Log in by visiting this link:\n\n") +
|
|
||||||
regexp.QuoteMeta(" https://127.0.0.1:") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("/authorize?access_type=offline&client_id=test-client-id&code_challenge="+testCodeChallenge+
|
|
||||||
"&code_challenge_method=S256&nonce=test-nonce&pinniped_idp_name=some-upstream-name&pinniped_idp_type=oidc"+
|
|
||||||
"&redirect_uri=http%3A%2F%2F127.0.0.1%3A") +
|
|
||||||
"[0-9]+" + // random port
|
|
||||||
regexp.QuoteMeta("%2Fcallback&response_type=code&scope=test-scope&state=test-state") +
|
|
||||||
regexp.QuoteMeta("\n\n") +
|
|
||||||
"$",
|
|
||||||
wantToken: &testToken,
|
wantToken: &testToken,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1073,7 +990,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
opt: func(t *testing.T) Option {
|
opt: func(t *testing.T) Option {
|
||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
_ = defaultLDAPTestOpts(t, h, nil, nil)
|
_ = defaultLDAPTestOpts(t, h, nil, nil)
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
require.Equal(t, "Username: ", promptLabel)
|
require.Equal(t, "Username: ", promptLabel)
|
||||||
return "", errors.New("some prompt error")
|
return "", errors.New("some prompt error")
|
||||||
}
|
}
|
||||||
@ -1082,7 +999,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: "error prompting for username: some prompt error",
|
wantErr: "error prompting for username: some prompt error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1091,13 +1007,12 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
opt: func(t *testing.T) Option {
|
opt: func(t *testing.T) Option {
|
||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
_ = defaultLDAPTestOpts(t, h, nil, nil)
|
_ = defaultLDAPTestOpts(t, h, nil, nil)
|
||||||
h.promptForSecret = func(_ string, _ io.Writer) (string, error) { return "", errors.New("some prompt error") }
|
h.promptForSecret = func(_ string) (string, error) { return "", errors.New("some prompt error") }
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: "error prompting for password: some prompt error",
|
wantErr: "error prompting for password: some prompt error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1153,12 +1068,8 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: `authorization response error: Get "https://` + successServer.Listener.Addr().String() +
|
wantErr: `authorization response error: Get "https://` + successServer.Listener.Addr().String() +
|
||||||
`/authorize?access_type=offline&client_id=test-client-id&code_challenge=` + testCodeChallenge +
|
`/authorize?access_type=offline&client_id=test-client-id&code_challenge=VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g&code_challenge_method=S256&nonce=test-nonce&pinniped_idp_name=some-upstream-name&pinniped_idp_type=ldap&redirect_uri=http%3A%2F%2F127.0.0.1%3A0%2Fcallback&response_type=code&scope=test-scope&state=test-state": some error fetching authorize endpoint`,
|
||||||
`&code_challenge_method=S256&nonce=test-nonce&pinniped_idp_name=some-upstream-name&` +
|
|
||||||
`pinniped_idp_type=ldap&redirect_uri=http%3A%2F%2F127.0.0.1%3A0%2Fcallback&response_type=code` +
|
|
||||||
`&scope=test-scope&state=test-state": some error fetching authorize endpoint`,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ldap login when the OIDC provider authorization endpoint returns something other than a redirect",
|
name: "ldap login when the OIDC provider authorization endpoint returns something other than a redirect",
|
||||||
@ -1170,7 +1081,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: `error getting authorization: expected to be redirected, but response status was 502 Bad Gateway`,
|
wantErr: `error getting authorization: expected to be redirected, but response status was 502 Bad Gateway`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1188,7 +1098,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: `login failed with code "access_denied": optional-error-description`,
|
wantErr: `login failed with code "access_denied": optional-error-description`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1206,7 +1115,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: `error getting authorization: redirected to the wrong location: http://other-server.example.com/callback?code=foo&state=test-state`,
|
wantErr: `error getting authorization: redirected to the wrong location: http://other-server.example.com/callback?code=foo&state=test-state`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1224,7 +1132,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: `login failed with code "access_denied"`,
|
wantErr: `login failed with code "access_denied"`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1240,7 +1147,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: `missing or invalid state parameter in authorization response: http://127.0.0.1:0/callback?code=foo&state=wrong-state`,
|
wantErr: `missing or invalid state parameter in authorization response: http://127.0.0.1:0/callback?code=foo&state=wrong-state`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1268,7 +1174,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantErr: "could not complete authorization code exchange: some authcode exchange or token validation error",
|
wantErr: "could not complete authorization code exchange: some authcode exchange or token validation error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1293,11 +1198,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
h.getEnv = func(_ string) string {
|
h.getEnv = func(_ string) string {
|
||||||
return "" // asking for any env var returns empty as if it were unset
|
return "" // asking for any env var returns empty as if it were unset
|
||||||
}
|
}
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
require.Equal(t, "Username: ", promptLabel)
|
require.Equal(t, "Username: ", promptLabel)
|
||||||
return "some-upstream-username", nil
|
return "some-upstream-username", nil
|
||||||
}
|
}
|
||||||
h.promptForSecret = func(promptLabel string, _ io.Writer) (string, error) {
|
h.promptForSecret = func(promptLabel string) (string, error) {
|
||||||
require.Equal(t, "Password: ", promptLabel)
|
require.Equal(t, "Password: ", promptLabel)
|
||||||
return "some-upstream-password", nil
|
return "some-upstream-password", nil
|
||||||
}
|
}
|
||||||
@ -1337,7 +1242,10 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
require.Equal(t, "some-upstream-username", req.Header.Get("Pinniped-Username"))
|
require.Equal(t, "some-upstream-username", req.Header.Get("Pinniped-Username"))
|
||||||
require.Equal(t, "some-upstream-password", req.Header.Get("Pinniped-Password"))
|
require.Equal(t, "some-upstream-password", req.Header.Get("Pinniped-Password"))
|
||||||
require.Equal(t, url.Values{
|
require.Equal(t, url.Values{
|
||||||
"code_challenge": []string{testCodeChallenge},
|
// This is the PKCE challenge which is calculated as base64(sha256("test-pkce")). For example:
|
||||||
|
// $ echo -n test-pkce | shasum -a 256 | cut -d" " -f1 | xxd -r -p | base64 | cut -d"=" -f1
|
||||||
|
// VVaezYqum7reIhoavCHD1n2d+piN3r/mywoYj7fCR7g
|
||||||
|
"code_challenge": []string{"VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g"},
|
||||||
"code_challenge_method": []string{"S256"},
|
"code_challenge_method": []string{"S256"},
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
"scope": []string{"test-scope"},
|
"scope": []string{"test-scope"},
|
||||||
@ -1367,7 +1275,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
},
|
},
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
wantLogs: []string{"\"level\"=4 \"msg\"=\"Pinniped: Performing OIDC discovery\" \"issuer\"=\"" + successServer.URL + "\""},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantToken: &testToken,
|
wantToken: &testToken,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1399,11 +1306,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
return "" // all other env vars are treated as if they are unset
|
return "" // all other env vars are treated as if they are unset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
h.promptForSecret = func(promptLabel string, _ io.Writer) (string, error) {
|
h.promptForSecret = func(promptLabel string) (string, error) {
|
||||||
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
@ -1414,6 +1321,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
ClientID: "test-client-id",
|
ClientID: "test-client-id",
|
||||||
Scopes: []string{"test-scope"},
|
Scopes: []string{"test-scope"},
|
||||||
RedirectURI: "http://localhost:0/callback",
|
RedirectURI: "http://localhost:0/callback",
|
||||||
|
UpstreamProviderName: "some-upstream-name",
|
||||||
}
|
}
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
require.Equal(t, []SessionCacheKey{cacheKey}, cache.sawGetKeys)
|
require.Equal(t, []SessionCacheKey{cacheKey}, cache.sawGetKeys)
|
||||||
@ -1422,6 +1330,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
})
|
})
|
||||||
require.NoError(t, WithSessionCache(cache)(h))
|
require.NoError(t, WithSessionCache(cache)(h))
|
||||||
require.NoError(t, WithCLISendingCredentials()(h))
|
require.NoError(t, WithCLISendingCredentials()(h))
|
||||||
|
require.NoError(t, WithUpstreamIdentityProvider("some-upstream-name", "ldap")(h))
|
||||||
|
|
||||||
discoveryRequestWasMade := false
|
discoveryRequestWasMade := false
|
||||||
authorizeRequestWasMade := false
|
authorizeRequestWasMade := false
|
||||||
@ -1441,7 +1350,10 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
require.Equal(t, "some-upstream-username", req.Header.Get("Pinniped-Username"))
|
require.Equal(t, "some-upstream-username", req.Header.Get("Pinniped-Username"))
|
||||||
require.Equal(t, "some-upstream-password", req.Header.Get("Pinniped-Password"))
|
require.Equal(t, "some-upstream-password", req.Header.Get("Pinniped-Password"))
|
||||||
require.Equal(t, url.Values{
|
require.Equal(t, url.Values{
|
||||||
"code_challenge": []string{testCodeChallenge},
|
// This is the PKCE challenge which is calculated as base64(sha256("test-pkce")). For example:
|
||||||
|
// $ echo -n test-pkce | shasum -a 256 | cut -d" " -f1 | xxd -r -p | base64 | cut -d"=" -f1
|
||||||
|
// VVaezYqum7reIhoavCHD1n2d+piN3r/mywoYj7fCR7g
|
||||||
|
"code_challenge": []string{"VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g"},
|
||||||
"code_challenge_method": []string{"S256"},
|
"code_challenge_method": []string{"S256"},
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
"scope": []string{"test-scope"},
|
"scope": []string{"test-scope"},
|
||||||
@ -1450,6 +1362,8 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
"access_type": []string{"offline"},
|
"access_type": []string{"offline"},
|
||||||
"client_id": []string{"test-client-id"},
|
"client_id": []string{"test-client-id"},
|
||||||
"redirect_uri": []string{"http://127.0.0.1:0/callback"},
|
"redirect_uri": []string{"http://127.0.0.1:0/callback"},
|
||||||
|
"pinniped_idp_name": []string{"some-upstream-name"},
|
||||||
|
"pinniped_idp_type": []string{"ldap"},
|
||||||
}, req.URL.Query())
|
}, req.URL.Query())
|
||||||
return &http.Response{
|
return &http.Response{
|
||||||
StatusCode: http.StatusFound,
|
StatusCode: http.StatusFound,
|
||||||
@ -1504,11 +1418,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
return "" // all other env vars are treated as if they are unset
|
return "" // all other env vars are treated as if they are unset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
h.promptForSecret = func(promptLabel string, _ io.Writer) (string, error) {
|
h.promptForSecret = func(promptLabel string) (string, error) {
|
||||||
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
require.FailNow(t, fmt.Sprintf("saw unexpected prompt from the CLI: %q", promptLabel))
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
@ -1548,7 +1462,10 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
require.Equal(t, "some-upstream-username", req.Header.Get("Pinniped-Username"))
|
require.Equal(t, "some-upstream-username", req.Header.Get("Pinniped-Username"))
|
||||||
require.Equal(t, "some-upstream-password", req.Header.Get("Pinniped-Password"))
|
require.Equal(t, "some-upstream-password", req.Header.Get("Pinniped-Password"))
|
||||||
require.Equal(t, url.Values{
|
require.Equal(t, url.Values{
|
||||||
"code_challenge": []string{testCodeChallenge},
|
// This is the PKCE challenge which is calculated as base64(sha256("test-pkce")). For example:
|
||||||
|
// $ echo -n test-pkce | shasum -a 256 | cut -d" " -f1 | xxd -r -p | base64 | cut -d"=" -f1
|
||||||
|
// VVaezYqum7reIhoavCHD1n2d+piN3r/mywoYj7fCR7g
|
||||||
|
"code_challenge": []string{"VVaezYqum7reIhoavCHD1n2d-piN3r_mywoYj7fCR7g"},
|
||||||
"code_challenge_method": []string{"S256"},
|
"code_challenge_method": []string{"S256"},
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
"scope": []string{"test-scope"},
|
"scope": []string{"test-scope"},
|
||||||
@ -1582,7 +1499,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
"\"level\"=4 \"msg\"=\"Pinniped: Read username from environment variable\" \"name\"=\"PINNIPED_USERNAME\"",
|
"\"level\"=4 \"msg\"=\"Pinniped: Read username from environment variable\" \"name\"=\"PINNIPED_USERNAME\"",
|
||||||
"\"level\"=4 \"msg\"=\"Pinniped: Read password from environment variable\" \"name\"=\"PINNIPED_PASSWORD\"",
|
"\"level\"=4 \"msg\"=\"Pinniped: Read password from environment variable\" \"name\"=\"PINNIPED_PASSWORD\"",
|
||||||
},
|
},
|
||||||
wantStdErr: "^\nLog in to some-upstream-name\n\n$",
|
|
||||||
wantToken: &testToken,
|
wantToken: &testToken,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1982,7 +1898,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
testLogger := testlogger.NewLegacy(t) //nolint:staticcheck // old test with lots of log statements
|
testLogger := testlogger.NewLegacy(t) //nolint:staticcheck // old test with lots of log statements
|
||||||
klog.SetLogger(testLogger.Logger)
|
klog.SetLogger(testLogger.Logger)
|
||||||
|
|
||||||
buffer := bytes.Buffer{}
|
|
||||||
tok, err := Login(tt.issuer, tt.clientID,
|
tok, err := Login(tt.issuer, tt.clientID,
|
||||||
WithContext(context.Background()),
|
WithContext(context.Background()),
|
||||||
WithListenPort(0),
|
WithListenPort(0),
|
||||||
@ -1990,17 +1905,8 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
WithSkipBrowserOpen(),
|
WithSkipBrowserOpen(),
|
||||||
tt.opt(t),
|
tt.opt(t),
|
||||||
WithLogger(testLogger.Logger),
|
WithLogger(testLogger.Logger),
|
||||||
withOutWriter(t, &buffer),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
testLogger.Expect(tt.wantLogs)
|
testLogger.Expect(tt.wantLogs)
|
||||||
|
|
||||||
if tt.wantStdErr == "" {
|
|
||||||
require.Empty(t, buffer.String())
|
|
||||||
} else {
|
|
||||||
require.Regexp(t, tt.wantStdErr, buffer.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
if tt.wantErr != "" {
|
if tt.wantErr != "" {
|
||||||
require.EqualError(t, err, tt.wantErr)
|
require.EqualError(t, err, tt.wantErr)
|
||||||
require.Nil(t, tok)
|
require.Nil(t, tok)
|
||||||
@ -2034,15 +1940,6 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withOutWriter(t *testing.T, out io.Writer) Option {
|
|
||||||
return func(h *handlerState) error {
|
|
||||||
// Ensure that the proper default value has been set in the handlerState prior to overriding it for tests.
|
|
||||||
require.Equal(t, os.Stderr, h.out)
|
|
||||||
h.out = out
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandlePasteCallback(t *testing.T) {
|
func TestHandlePasteCallback(t *testing.T) {
|
||||||
const testRedirectURI = "http://127.0.0.1:12324/callback"
|
const testRedirectURI = "http://127.0.0.1:12324/callback"
|
||||||
|
|
||||||
@ -2080,7 +1977,7 @@ func TestHandlePasteCallback(t *testing.T) {
|
|||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
h.isTTY = func(fd int) bool { return true }
|
h.isTTY = func(fd int) bool { return true }
|
||||||
h.useFormPost = true
|
h.useFormPost = true
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
assert.Equal(t, " Optionally, paste your authorization code: ", promptLabel)
|
assert.Equal(t, " Optionally, paste your authorization code: ", promptLabel)
|
||||||
return "", fmt.Errorf("some prompt error")
|
return "", fmt.Errorf("some prompt error")
|
||||||
}
|
}
|
||||||
@ -2097,7 +1994,7 @@ func TestHandlePasteCallback(t *testing.T) {
|
|||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
h.isTTY = func(fd int) bool { return true }
|
h.isTTY = func(fd int) bool { return true }
|
||||||
h.useFormPost = true
|
h.useFormPost = true
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
return "invalid", nil
|
return "invalid", nil
|
||||||
}
|
}
|
||||||
h.oauth2Config = &oauth2.Config{RedirectURL: testRedirectURI}
|
h.oauth2Config = &oauth2.Config{RedirectURL: testRedirectURI}
|
||||||
@ -2121,7 +2018,7 @@ func TestHandlePasteCallback(t *testing.T) {
|
|||||||
return func(h *handlerState) error {
|
return func(h *handlerState) error {
|
||||||
h.isTTY = func(fd int) bool { return true }
|
h.isTTY = func(fd int) bool { return true }
|
||||||
h.useFormPost = true
|
h.useFormPost = true
|
||||||
h.promptForValue = func(_ context.Context, promptLabel string, _ io.Writer) (string, error) {
|
h.promptForValue = func(_ context.Context, promptLabel string) (string, error) {
|
||||||
return "valid", nil
|
return "valid", nil
|
||||||
}
|
}
|
||||||
h.oauth2Config = &oauth2.Config{RedirectURL: testRedirectURI}
|
h.oauth2Config = &oauth2.Config{RedirectURL: testRedirectURI}
|
||||||
@ -2145,13 +2042,11 @@ func TestHandlePasteCallback(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
h := &handlerState{
|
h := &handlerState{
|
||||||
callbacks: make(chan callbackResult, 1),
|
callbacks: make(chan callbackResult, 1),
|
||||||
state: state.State("test-state"),
|
state: state.State("test-state"),
|
||||||
pkce: pkce.Code("test-pkce"),
|
pkce: pkce.Code("test-pkce"),
|
||||||
nonce: nonce.Nonce("test-nonce"),
|
nonce: nonce.Nonce("test-nonce"),
|
||||||
out: buf,
|
|
||||||
}
|
}
|
||||||
if tt.opt != nil {
|
if tt.opt != nil {
|
||||||
require.NoError(t, tt.opt(t)(h))
|
require.NoError(t, tt.opt(t)(h))
|
||||||
@ -2159,7 +2054,8 @@ func TestHandlePasteCallback(t *testing.T) {
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
h.promptForWebLogin(ctx, "https://test-authorize-url/")
|
var buf bytes.Buffer
|
||||||
|
h.promptForWebLogin(ctx, "https://test-authorize-url/", &buf)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
"Log in by visiting this link:\n\n https://test-authorize-url/\n\n",
|
"Log in by visiting this link:\n\n https://test-authorize-url/\n\n",
|
||||||
buf.String(),
|
buf.String(),
|
||||||
|
@ -7,7 +7,7 @@ params:
|
|||||||
github_url: "https://github.com/vmware-tanzu/pinniped"
|
github_url: "https://github.com/vmware-tanzu/pinniped"
|
||||||
slack_url: "https://go.pinniped.dev/community/slack"
|
slack_url: "https://go.pinniped.dev/community/slack"
|
||||||
community_url: "https://go.pinniped.dev/community"
|
community_url: "https://go.pinniped.dev/community"
|
||||||
latest_version: v0.27.0
|
latest_version: v0.26.0
|
||||||
latest_codegen_version: 1.28
|
latest_codegen_version: 1.28
|
||||||
pygmentsCodefences: true
|
pygmentsCodefences: true
|
||||||
pygmentsStyle: "pygments"
|
pygmentsStyle: "pygments"
|
||||||
|
@ -46,16 +46,11 @@ framework (e.g. Spring, Rails, Django, etc.) to implement authentication. The Su
|
|||||||
- Clients must use `query` as the
|
- Clients must use `query` as the
|
||||||
[response_mode](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) at the authorization endpoint,
|
[response_mode](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) at the authorization endpoint,
|
||||||
or not specify the `response_mode` param, which defaults to `query`.
|
or not specify the `response_mode` param, which defaults to `query`.
|
||||||
- The client may optionally send an extra parameter on the initial authorization request to indicate which identity
|
- If the Supervisor's FederationDomain was configured with explicit `identityProviders` in its spec, then the
|
||||||
provider the user would like to use when authenticating. This parameter is called `pinniped_idp_name` and the value
|
client must send an extra parameter on the initial authorization request to indicate which identity provider
|
||||||
|
the user would like to use when authenticating. This parameter is called `pinniped_idp_name` and the value
|
||||||
of the parameter should be set to the `displayName` of the identity provider as it was configured on the
|
of the parameter should be set to the `displayName` of the identity provider as it was configured on the
|
||||||
FederationDomain. When this parameter is not included, and when the FederationDomain was configured with explicit
|
FederationDomain.
|
||||||
`identityProviders` in its spec, then the user will be prompted to choose an identity provider from the list of
|
|
||||||
available identity providers by an interstitial web page during their login flow. The value of this parameter
|
|
||||||
should be considered a hint and not a hard requirement, since the user could choose to alter or remove this
|
|
||||||
query param from the authorization URL, and thus could use a different available identity provider from the
|
|
||||||
FederationDomain to log in. This is not a security concern, since any successful login using any available identity
|
|
||||||
provider from the FederationDomain's configuration is a valid and allowed user.
|
|
||||||
|
|
||||||
Most web application frameworks offer all these capabilities in their OAuth2/OIDC libraries.
|
Most web application frameworks offer all these capabilities in their OAuth2/OIDC libraries.
|
||||||
|
|
||||||
|
@ -24,16 +24,13 @@ Use [Homebrew](https://brew.sh/) to install from the Pinniped [tap](https://gith
|
|||||||
Find the appropriate binary for your platform from the [latest release](https://github.com/vmware-tanzu/pinniped/releases/latest):
|
Find the appropriate binary for your platform from the [latest release](https://github.com/vmware-tanzu/pinniped/releases/latest):
|
||||||
|
|
||||||
{{< buttonlink filename="pinniped-cli-darwin-amd64" >}}Download {{< latestversion >}} for macOS/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
{{< buttonlink filename="pinniped-cli-darwin-amd64" >}}Download {{< latestversion >}} for macOS/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
||||||
{{< buttonlink filename="pinniped-cli-darwin-arm64" >}}Download {{< latestversion >}} for macOS/arm64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
|
||||||
|
|
||||||
{{< buttonlink filename="pinniped-cli-linux-amd64" >}}Download {{< latestversion >}} for Linux/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
{{< buttonlink filename="pinniped-cli-linux-amd64" >}}Download {{< latestversion >}} for Linux/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
||||||
{{< buttonlink filename="pinniped-cli-linux-arm64" >}}Download {{< latestversion >}} for Linux/arm64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
|
||||||
|
|
||||||
{{< buttonlink filename="pinniped-cli-windows-amd64.exe" >}}Download {{< latestversion >}} for Windows/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
{{< buttonlink filename="pinniped-cli-windows-amd64.exe" >}}Download {{< latestversion >}} for Windows/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
||||||
{{< buttonlink filename="pinniped-cli-windows-arm64.exe" >}}Download {{< latestversion >}} for Windows/arm64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
|
||||||
|
|
||||||
You should put the command-line tool somewhere on your `$PATH`, such as `/usr/local/bin` on macOS/Linux.
|
You should put the command-line tool somewhere on your `$PATH`, such as `/usr/local/bin` on macOS/Linux.
|
||||||
You'll also need to mark the file as executable, e.g. `chmod +x pinniped` on macOS/Linux.
|
You'll also need to mark the file as executable.
|
||||||
|
|
||||||
To find specific versions or view all available platforms and architectures, visit the [releases page](https://github.com/vmware-tanzu/pinniped/releases/).
|
To find specific versions or view all available platforms and architectures, visit the [releases page](https://github.com/vmware-tanzu/pinniped/releases/).
|
||||||
|
|
||||||
|
@ -90,10 +90,6 @@ Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/)
|
|||||||
|
|
||||||
- `ytt --file . --file site/dev-env.yaml | kapp deploy --app pinniped-concierge --file -`
|
- `ytt --file . --file site/dev-env.yaml | kapp deploy --app pinniped-concierge --file -`
|
||||||
|
|
||||||
## Supported Node Architectures
|
|
||||||
|
|
||||||
The Pinniped Concierge can be installed on Kubernetes clusters with available `amd64` or `arm64` linux nodes.
|
|
||||||
|
|
||||||
## Other notes
|
## Other notes
|
||||||
|
|
||||||
_Important:_ Configure Kubernetes authorization policies (i.e. RBAC) to prevent non-admin users from reading the
|
_Important:_ Configure Kubernetes authorization policies (i.e. RBAC) to prevent non-admin users from reading the
|
||||||
|
@ -91,10 +91,6 @@ Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/)
|
|||||||
|
|
||||||
`ytt --file . --file site/dev-env.yaml | kapp deploy --app pinniped-supervisor --file -`
|
`ytt --file . --file site/dev-env.yaml | kapp deploy --app pinniped-supervisor --file -`
|
||||||
|
|
||||||
## Supported Node Architectures
|
|
||||||
|
|
||||||
The Pinniped Supervisor can be installed on Kubernetes clusters with available `amd64` or `arm64` linux nodes.
|
|
||||||
|
|
||||||
## Other notes
|
## Other notes
|
||||||
|
|
||||||
_Important:_ Configure Kubernetes authorization policies (i.e. RBAC) to prevent non-admin users from reading the
|
_Important:_ Configure Kubernetes authorization policies (i.e. RBAC) to prevent non-admin users from reading the
|
||||||
|
@ -81,17 +81,6 @@ and if that FederationDomain allows multiple identity providers, then you will n
|
|||||||
you would like to use in the resulting kubeconfig with the `--upstream-identity-provider-name` and/or `--upstream-identity-provider-type` flags.
|
you would like to use in the resulting kubeconfig with the `--upstream-identity-provider-name` and/or `--upstream-identity-provider-type` flags.
|
||||||
You may call `pinniped get kubeconfig` multiple times to generate multiple kubeconfigs for the cluster.
|
You may call `pinniped get kubeconfig` multiple times to generate multiple kubeconfigs for the cluster.
|
||||||
|
|
||||||
By default, the resulting kubeconfig will contain the absolute path to the Pinniped CLI binary that was used to run `pinniped get kubeconfig`.
|
|
||||||
However, this absolute path may not work on the local machines for your end users to whom you distribute the kubeconfig,
|
|
||||||
since they may have the Pinniped CLI installed elsewhere.
|
|
||||||
You can optionally set the absolute path or executable name in the resulting kubeconfig by using the `--pinniped-cli-path`
|
|
||||||
argument. For example, when using `pinniped get kubeconfig --pinniped-cli-path=pinniped` then the resulting kubeconfig
|
|
||||||
will include `pinniped` as the command to execute the Pinniped CLI, and during user login it will find the CLI by
|
|
||||||
searching the user's PATH for a binary named `pinniped`. This also works on Windows, where using `pinniped` as the command
|
|
||||||
can find a binary named `pinniped.exe` in the user's PATH.
|
|
||||||
Alternatively, you could use `pinniped get kubeconfig --pinniped-cli-path=/usr/local/bin/pinniped`
|
|
||||||
if you have reason to believe that your end users' machines will always have the Pinniped CLI installed in `/usr/local/bin`.
|
|
||||||
|
|
||||||
## Use the generated kubeconfig with `kubectl` to access the cluster
|
## Use the generated kubeconfig with `kubectl` to access the cluster
|
||||||
|
|
||||||
A cluster user will typically be given a Pinniped-compatible kubeconfig by their cluster admin. They can use this kubeconfig
|
A cluster user will typically be given a Pinniped-compatible kubeconfig by their cluster admin. They can use this kubeconfig
|
||||||
|
@ -198,7 +198,6 @@ pinniped get kubeconfig [flags]
|
|||||||
--oidc-session-cache string Path to OpenID Connect session cache file
|
--oidc-session-cache string Path to OpenID Connect session cache file
|
||||||
--oidc-skip-browser During OpenID Connect login, skip opening the browser (just print the URL)
|
--oidc-skip-browser During OpenID Connect login, skip opening the browser (just print the URL)
|
||||||
-o, --output string Output file path (default: stdout)
|
-o, --output string Output file path (default: stdout)
|
||||||
--pinniped-cli-path string Full path or executable name for the Pinniped CLI binary to be embedded in the resulting kubeconfig output (e.g. 'pinniped') (default: full path of the binary used to execute this command)
|
|
||||||
--skip-validation Skip final validation of the kubeconfig (default: false)
|
--skip-validation Skip final validation of the kubeconfig (default: false)
|
||||||
--static-token string Instead of doing an OIDC-based login, specify a static token
|
--static-token string Instead of doing an OIDC-based login, specify a static token
|
||||||
--static-token-env string Instead of doing an OIDC-based login, read a static token from the environment
|
--static-token-env string Instead of doing an OIDC-based login, read a static token from the environment
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -126,12 +126,3 @@ spec:
|
|||||||
- name: certs
|
- name: certs
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
tolerations:
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: amd64 #! Allow running on amd64 nodes.
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: arm64 #! Also allow running on arm64 nodes.
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -94,15 +94,6 @@ spec:
|
|||||||
- name: certs
|
- name: certs
|
||||||
secret:
|
secret:
|
||||||
secretName: certs
|
secretName: certs
|
||||||
tolerations:
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: amd64 #! Allow running on amd64 nodes.
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: arm64 #! Also allow running on arm64 nodes.
|
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -155,32 +155,60 @@ stringData: #@ ldapLIDIF()
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: ldap-server-additional-schema-ldif-files
|
name: ldap-server-config-before-ldif-files
|
||||||
namespace: tools
|
namespace: tools
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
#! From https://github.com/bitnami/containers/issues/982#issuecomment-1220354408
|
server-config.ldif: |
|
||||||
memberof.ldif: |
|
# Load the memberof module.
|
||||||
dn: cn=module,cn=config
|
dn: cn=module,cn=config
|
||||||
cn: module
|
cn: module
|
||||||
objectClass: olcModuleList
|
objectClass: olcModuleList
|
||||||
|
objectClass: top
|
||||||
olcModulePath: /opt/bitnami/openldap/lib/openldap
|
olcModulePath: /opt/bitnami/openldap/lib/openldap
|
||||||
olcModuleLoad: memberof.so
|
olcModuleLoad: memberof
|
||||||
olcModuleLoad: refint.so
|
|
||||||
|
|
||||||
dn: olcOverlay=memberof,olcDatabase={2}mdb,cn=config
|
dn: olcOverlay={0}memberof,olcDatabase={2}hdb,cn=config
|
||||||
|
objectClass: olcConfig
|
||||||
objectClass: olcMemberOf
|
objectClass: olcMemberOf
|
||||||
objectClass: olcOverlayConfig
|
objectClass: olcOverlayConfig
|
||||||
|
objectClass: top
|
||||||
olcOverlay: memberof
|
olcOverlay: memberof
|
||||||
|
olcMemberOfDangling: ignore
|
||||||
|
olcMemberOfRefInt: TRUE
|
||||||
|
olcMemberOfGroupOC: groupOfNames
|
||||||
|
olcMemberOfMemberAD: member
|
||||||
|
|
||||||
dn: olcOverlay=refint,olcDatabase={2}mdb,cn=config
|
# Load the refint module.
|
||||||
|
dn: cn=module,cn=config
|
||||||
|
cn: module
|
||||||
|
objectclass: olcModuleList
|
||||||
|
objectclass: top
|
||||||
|
olcmodulepath: /opt/bitnami/openldap/lib/openldap
|
||||||
|
olcmoduleload: refint
|
||||||
|
|
||||||
|
dn: olcOverlay={1}refint,olcDatabase={2}hdb,cn=config
|
||||||
objectClass: olcConfig
|
objectClass: olcConfig
|
||||||
objectClass: olcOverlayConfig
|
objectClass: olcOverlayConfig
|
||||||
objectClass: olcRefintConfig
|
objectClass: olcRefintConfig
|
||||||
objectClass: top
|
objectClass: top
|
||||||
olcOverlay: refint
|
olcOverlay: {1}refint
|
||||||
olcRefintAttribute: memberof member manager owner
|
olcRefintAttribute: memberof member manager owner
|
||||||
---
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ldap-server-config-after-ldif-files
|
||||||
|
namespace: tools
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
server-config.ldif: |
|
||||||
|
# Reject any further connections that do not use TLS or StartTLS
|
||||||
|
dn: olcDatabase={2}hdb,cn=config
|
||||||
|
changetype: modify
|
||||||
|
add: olcSecurity
|
||||||
|
olcSecurity: tls=1
|
||||||
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@ -213,6 +241,13 @@ spec:
|
|||||||
containerPort: 1389
|
containerPort: 1389
|
||||||
- name: ldaps
|
- name: ldaps
|
||||||
containerPort: 1636
|
containerPort: 1636
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m" #! one-tenth of one CPU
|
||||||
|
memory: "64Mi"
|
||||||
|
limits:
|
||||||
|
#! Do not limit CPU because it was causing issues running integration tests on AKS where openldap became very slow.
|
||||||
|
memory: "64Mi"
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
tcpSocket:
|
tcpSocket:
|
||||||
port: ldap
|
port: ldap
|
||||||
@ -239,8 +274,6 @@ spec:
|
|||||||
value: "password" #! ok to hardcode: the LDAP server will not be available from outside the cluster
|
value: "password" #! ok to hardcode: the LDAP server will not be available from outside the cluster
|
||||||
- name: LDAP_ENABLE_TLS
|
- name: LDAP_ENABLE_TLS
|
||||||
value: "yes"
|
value: "yes"
|
||||||
- name: LDAP_REQUIRE_TLS
|
|
||||||
value: "yes"
|
|
||||||
- name: LDAP_TLS_CERT_FILE
|
- name: LDAP_TLS_CERT_FILE
|
||||||
value: "/var/certs/ldap.pem"
|
value: "/var/certs/ldap.pem"
|
||||||
- name: LDAP_TLS_KEY_FILE
|
- name: LDAP_TLS_KEY_FILE
|
||||||
@ -250,12 +283,14 @@ spec:
|
|||||||
#! Note that the custom LDIF file is only read at pod start-up time.
|
#! Note that the custom LDIF file is only read at pod start-up time.
|
||||||
- name: LDAP_CUSTOM_LDIF_DIR
|
- name: LDAP_CUSTOM_LDIF_DIR
|
||||||
value: "/var/ldifs"
|
value: "/var/ldifs"
|
||||||
|
- name: LDAP_SERVER_CONFIG_BEFORE_CUSTOM_LDIF_DIR
|
||||||
|
value: "/var/server-config-before-ldifs"
|
||||||
|
- name: LDAP_SERVER_CONFIG_AFTER_CUSTOM_LDIF_DIR
|
||||||
|
value: "/var/server-config-after-ldifs"
|
||||||
#! Seems like LDAP_ROOT is still required when using LDAP_CUSTOM_LDIF_DIR because it effects the admin user.
|
#! Seems like LDAP_ROOT is still required when using LDAP_CUSTOM_LDIF_DIR because it effects the admin user.
|
||||||
#! Presumably this needs to match the root that we create in the LDIF file.
|
#! Presumably this needs to match the root that we create in the LDIF file.
|
||||||
- name: LDAP_ROOT
|
- name: LDAP_ROOT
|
||||||
value: "dc=pinniped,dc=dev"
|
value: "dc=pinniped,dc=dev"
|
||||||
- name: LDAP_EXTRA_SCHEMAS
|
|
||||||
value: "cosine,inetorgperson,nis,memberof"
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: certs
|
- name: certs
|
||||||
mountPath: /var/certs
|
mountPath: /var/certs
|
||||||
@ -263,9 +298,11 @@ spec:
|
|||||||
- name: ldifs
|
- name: ldifs
|
||||||
mountPath: /var/ldifs
|
mountPath: /var/ldifs
|
||||||
readOnly: true
|
readOnly: true
|
||||||
- name: additional-schema
|
- name: server-config-before-ldifs
|
||||||
mountPath: /opt/bitnami/openldap/etc/schema/memberof.ldif
|
mountPath: /var/server-config-before-ldifs
|
||||||
subPath: memberof.ldif
|
readOnly: true
|
||||||
|
- name: server-config-after-ldifs
|
||||||
|
mountPath: /var/server-config-after-ldifs
|
||||||
readOnly: true
|
readOnly: true
|
||||||
volumes:
|
volumes:
|
||||||
- name: certs
|
- name: certs
|
||||||
@ -274,18 +311,12 @@ spec:
|
|||||||
- name: ldifs
|
- name: ldifs
|
||||||
secret:
|
secret:
|
||||||
secretName: ldap-ldif-files
|
secretName: ldap-ldif-files
|
||||||
- name: additional-schema
|
- name: server-config-before-ldifs
|
||||||
secret:
|
secret:
|
||||||
secretName: ldap-server-additional-schema-ldif-files
|
secretName: ldap-server-config-before-ldif-files
|
||||||
tolerations:
|
- name: server-config-after-ldifs
|
||||||
- key: kubernetes.io/arch
|
secret:
|
||||||
effect: NoSchedule
|
secretName: ldap-server-config-after-ldif-files
|
||||||
operator: Equal
|
|
||||||
value: amd64 #! Allow running on amd64 nodes.
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: arm64 #! Also allow running on arm64 nodes.
|
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -30,6 +30,13 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
containerPort: 3128
|
containerPort: 3128
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m" #! one-tenth of one CPU
|
||||||
|
memory: "64Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "100m" #! one-tenth of one CPU
|
||||||
|
memory: "64Mi"
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: log-dir
|
- name: log-dir
|
||||||
mountPath: "/var/log/squid/"
|
mountPath: "/var/log/squid/"
|
||||||
@ -51,15 +58,6 @@ spec:
|
|||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: log-dir
|
- name: log-dir
|
||||||
mountPath: "/var/log/squid/"
|
mountPath: "/var/log/squid/"
|
||||||
tolerations:
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: amd64 #! Allow running on amd64 nodes.
|
|
||||||
- key: kubernetes.io/arch
|
|
||||||
effect: NoSchedule
|
|
||||||
operator: Equal
|
|
||||||
value: arm64 #! Also allow running on arm64 nodes.
|
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@data/values
|
#@data/values
|
||||||
@ -28,7 +28,7 @@ pinny_ldap_password:
|
|||||||
|
|
||||||
#! Images for each of the deployed test components.
|
#! Images for each of the deployed test components.
|
||||||
dex_image: ghcr.io/pinniped-ci-bot/test-dex:latest
|
dex_image: ghcr.io/pinniped-ci-bot/test-dex:latest
|
||||||
ldap_image: ghcr.io/pinniped-ci-bot/test-bitnami-ldap:latest
|
ldap_image: ghcr.io/pinniped-ci-bot/test-ldap:latest
|
||||||
proxy_image: ghcr.io/pinniped-ci-bot/test-forward-proxy:latest
|
proxy_image: ghcr.io/pinniped-ci-bot/test-forward-proxy:latest
|
||||||
cfssl_image: ghcr.io/pinniped-ci-bot/test-cfssl:latest
|
cfssl_image: ghcr.io/pinniped-ci-bot/test-cfssl:latest
|
||||||
kubectl_image: ghcr.io/pinniped-ci-bot/test-kubectl:latest
|
kubectl_image: ghcr.io/pinniped-ci-bot/test-kubectl:latest
|
||||||
|
@ -48,15 +48,25 @@ func TestFormPostHTML_Browser_Parallel(t *testing.T) {
|
|||||||
t.Run("callback server error", func(t *testing.T) {
|
t.Run("callback server error", func(t *testing.T) {
|
||||||
browser := browsertest.OpenBrowser(t)
|
browser := browsertest.OpenBrowser(t)
|
||||||
|
|
||||||
// Serve the form_post template with a redirect URI that will return an HTTP 400 response.
|
// Serve the form_post template with a redirect URI that will return an HTTP 500 response.
|
||||||
responseParams := formpostRandomParams(t)
|
responseParams := formpostRandomParams(t)
|
||||||
formpostInitiate(t, browser, formpostTemplateServer(t, callbackURL+"?fail=400", responseParams))
|
formpostInitiate(t, browser, formpostTemplateServer(t, callbackURL+"?fail=500", responseParams))
|
||||||
|
|
||||||
// Now we handle the callback and assert that we got what we expected.
|
// Now we handle the callback and assert that we got what we expected.
|
||||||
expectCallback(t, responseParams)
|
expectCallback(t, responseParams)
|
||||||
|
|
||||||
// This failure should cause the UI to enter the "error" state.
|
// This is not 100% the behavior we'd like, but because our JS is making
|
||||||
formpostExpectErrorState(t, browser)
|
// a cross-origin fetch() without CORS, we don't get to know anything
|
||||||
|
// about the response (even whether it is 200 vs. 500), so this case
|
||||||
|
// is the same as the success case.
|
||||||
|
//
|
||||||
|
// This case is fairly unlikely in practice, and if the CLI encounters
|
||||||
|
// an error it can also expose it via stderr anyway.
|
||||||
|
//
|
||||||
|
// In the future, we could change the Javascript code to use mode 'cors'
|
||||||
|
// because we have upgraded our CLI callback endpoint to handle CORS,
|
||||||
|
// and then we could change this to formpostExpectManualState().
|
||||||
|
formpostExpectSuccessState(t, browser)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("network failure", func(t *testing.T) {
|
t.Run("network failure", func(t *testing.T) {
|
||||||
@ -103,7 +113,7 @@ func TestFormPostHTML_Browser_Parallel(t *testing.T) {
|
|||||||
// It returns the URL of the running test server and a function for fetching the next
|
// It returns the URL of the running test server and a function for fetching the next
|
||||||
// received form POST parameters.
|
// received form POST parameters.
|
||||||
//
|
//
|
||||||
// The test server supports special `?fail=close` and `?fail=400` to force error cases.
|
// The test server supports special `?fail=close` and `?fail=500` to force error cases.
|
||||||
func formpostCallbackServer(t *testing.T) (string, func(*testing.T, url.Values)) {
|
func formpostCallbackServer(t *testing.T) (string, func(*testing.T, url.Values)) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
results := make(chan url.Values)
|
results := make(chan url.Values)
|
||||||
@ -146,9 +156,8 @@ func formpostCallbackServer(t *testing.T) (string, func(*testing.T, url.Values))
|
|||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case "400": // If "fail=400" is passed, return a 400 error.
|
case "500": // If "fail=500" is passed, return a 500 error.
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
_, _ = w.Write([]byte("this is the text of the bad request error response"))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -256,19 +265,6 @@ func formpostExpectSuccessState(t *testing.T, b *browsertest.Browser) {
|
|||||||
formpostExpectFavicon(t, b, "✅")
|
formpostExpectFavicon(t, b, "✅")
|
||||||
}
|
}
|
||||||
|
|
||||||
// formpostExpectErrorState asserts that the page is in the "error" state.
|
|
||||||
func formpostExpectErrorState(t *testing.T, b *browsertest.Browser) {
|
|
||||||
t.Helper()
|
|
||||||
t.Logf("expecting to see error message become visible...")
|
|
||||||
b.WaitForVisibleElements(t, "div#error")
|
|
||||||
errorDivText := b.TextOfFirstMatch(t, "div#error")
|
|
||||||
require.Contains(t, errorDivText, "Error during login")
|
|
||||||
require.Contains(t, errorDivText, "400: this is the text of the bad request error response")
|
|
||||||
require.Contains(t, errorDivText, "Please try again.")
|
|
||||||
require.Equal(t, "Error during login", b.Title(t))
|
|
||||||
formpostExpectFavicon(t, b, "⛔")
|
|
||||||
}
|
|
||||||
|
|
||||||
// formpostExpectManualState asserts that the page is in the "manual" state and returns the auth code.
|
// formpostExpectManualState asserts that the page is in the "manual" state and returns the auth code.
|
||||||
func formpostExpectManualState(t *testing.T, b *browsertest.Browser) string {
|
func formpostExpectManualState(t *testing.T, b *browsertest.Browser) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
@ -235,7 +235,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
|||||||
createIDP func(t *testing.T) string
|
createIDP func(t *testing.T) string
|
||||||
|
|
||||||
// Optionally specify the identityProviders part of the FederationDomain's spec by returning it from this function.
|
// Optionally specify the identityProviders part of the FederationDomain's spec by returning it from this function.
|
||||||
// Also return the displayName of the IDP that should be used during authentication (or empty string for no IDP name in the auth request).
|
// Also return the displayName of the IDP that should be used during authentication.
|
||||||
// This function takes the name of the IDP CR which was returned by createIDP() as as argument.
|
// This function takes the name of the IDP CR which was returned by createIDP() as as argument.
|
||||||
federationDomainIDPs func(t *testing.T, idpName string) (idps []configv1alpha1.FederationDomainIdentityProvider, useIDPDisplayName string)
|
federationDomainIDPs func(t *testing.T, idpName string) (idps []configv1alpha1.FederationDomainIdentityProvider, useIDPDisplayName string)
|
||||||
|
|
||||||
@ -1430,51 +1430,6 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
|||||||
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { return "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Username) + "$" },
|
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { return "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Username) + "$" },
|
||||||
wantDownstreamIDTokenGroups: env.SupervisorUpstreamOIDC.ExpectedGroups,
|
wantDownstreamIDTokenGroups: env.SupervisorUpstreamOIDC.ExpectedGroups,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "oidc upstream with downstream dynamic client happy path, requesting all scopes, using the IDP chooser page",
|
|
||||||
maybeSkip: skipNever,
|
|
||||||
createIDP: func(t *testing.T) string {
|
|
||||||
spec := basicOIDCIdentityProviderSpec()
|
|
||||||
spec.Claims = idpv1alpha1.OIDCClaims{
|
|
||||||
Username: env.SupervisorUpstreamOIDC.UsernameClaim,
|
|
||||||
Groups: env.SupervisorUpstreamOIDC.GroupsClaim,
|
|
||||||
}
|
|
||||||
spec.AuthorizationConfig = idpv1alpha1.OIDCAuthorizationConfig{
|
|
||||||
AdditionalScopes: env.SupervisorUpstreamOIDC.AdditionalScopes,
|
|
||||||
}
|
|
||||||
return testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseReady).Name
|
|
||||||
},
|
|
||||||
federationDomainIDPs: func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string) {
|
|
||||||
displayName := "my oidc idp"
|
|
||||||
return []configv1alpha1.FederationDomainIdentityProvider{
|
|
||||||
{
|
|
||||||
DisplayName: displayName,
|
|
||||||
ObjectRef: v1.TypedLocalObjectReference{
|
|
||||||
APIGroup: ptr.To("idp.supervisor." + env.APIGroupSuffix),
|
|
||||||
Kind: "OIDCIdentityProvider",
|
|
||||||
Name: idpName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"" // return an empty string be used as the pinniped_idp_name param's value in the authorize request,
|
|
||||||
// which should cause the authorize endpoint to show the IDP chooser page
|
|
||||||
},
|
|
||||||
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
|
|
||||||
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
|
|
||||||
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
|
|
||||||
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
|
|
||||||
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
|
|
||||||
}, configv1alpha1.OIDCClientPhaseReady)
|
|
||||||
},
|
|
||||||
requestAuthorization: requestAuthorizationUsingBrowserAuthcodeFlowOIDCWithIDPChooserPage,
|
|
||||||
wantDownstreamIDTokenSubjectToMatch: "^" +
|
|
||||||
regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Issuer) +
|
|
||||||
regexp.QuoteMeta("?idpName="+url.QueryEscape("my oidc idp")) +
|
|
||||||
regexp.QuoteMeta("&sub=") + ".+" +
|
|
||||||
"$",
|
|
||||||
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { return "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Username) + "$" },
|
|
||||||
wantDownstreamIDTokenGroups: env.SupervisorUpstreamOIDC.ExpectedGroups,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "oidc upstream with downstream dynamic client happy path, requesting all scopes, with additional claims",
|
name: "oidc upstream with downstream dynamic client happy path, requesting all scopes, with additional claims",
|
||||||
maybeSkip: skipNever,
|
maybeSkip: skipNever,
|
||||||
@ -2772,8 +2727,9 @@ func requestAuthorizationAndExpectImmediateRedirectToCallback(t *testing.T, _, d
|
|||||||
browser.WaitForURL(t, callbackURLPattern)
|
browser.WaitForURL(t, callbackURLPattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
func openBrowserAndNavigateToAuthorizeURL(t *testing.T, downstreamAuthorizeURL string, httpClient *http.Client) *browsertest.Browser {
|
func requestAuthorizationUsingBrowserAuthcodeFlowOIDC(t *testing.T, _, downstreamAuthorizeURL, downstreamCallbackURL, _, _ string, httpClient *http.Client) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
env := testlib.IntegrationEnv(t)
|
||||||
|
|
||||||
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Minute)
|
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Minute)
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
@ -2786,45 +2742,13 @@ func openBrowserAndNavigateToAuthorizeURL(t *testing.T, downstreamAuthorizeURL s
|
|||||||
t.Logf("opening browser to downstream authorize URL %s", testlib.MaskTokens(downstreamAuthorizeURL))
|
t.Logf("opening browser to downstream authorize URL %s", testlib.MaskTokens(downstreamAuthorizeURL))
|
||||||
browser.Navigate(t, downstreamAuthorizeURL)
|
browser.Navigate(t, downstreamAuthorizeURL)
|
||||||
|
|
||||||
return browser
|
|
||||||
}
|
|
||||||
|
|
||||||
func loginToUpstreamOIDCAndWaitForCallback(t *testing.T, b *browsertest.Browser, downstreamCallbackURL string) {
|
|
||||||
t.Helper()
|
|
||||||
env := testlib.IntegrationEnv(t)
|
|
||||||
|
|
||||||
// Expect to be redirected to the upstream provider and log in.
|
// Expect to be redirected to the upstream provider and log in.
|
||||||
browsertest.LoginToUpstreamOIDC(t, b, env.SupervisorUpstreamOIDC)
|
browsertest.LoginToUpstreamOIDC(t, browser, env.SupervisorUpstreamOIDC)
|
||||||
|
|
||||||
// Wait for the login to happen and us be redirected back to a localhost callback.
|
// Wait for the login to happen and us be redirected back to a localhost callback.
|
||||||
t.Logf("waiting for redirect to callback")
|
t.Logf("waiting for redirect to callback")
|
||||||
callbackURLPattern := regexp.MustCompile(`\A` + regexp.QuoteMeta(downstreamCallbackURL) + `\?.+\z`)
|
callbackURLPattern := regexp.MustCompile(`\A` + regexp.QuoteMeta(downstreamCallbackURL) + `\?.+\z`)
|
||||||
b.WaitForURL(t, callbackURLPattern)
|
browser.WaitForURL(t, callbackURLPattern)
|
||||||
}
|
|
||||||
|
|
||||||
func requestAuthorizationUsingBrowserAuthcodeFlowOIDC(t *testing.T, _, downstreamAuthorizeURL, downstreamCallbackURL, _, _ string, httpClient *http.Client) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
browser := openBrowserAndNavigateToAuthorizeURL(t, downstreamAuthorizeURL, httpClient)
|
|
||||||
|
|
||||||
loginToUpstreamOIDCAndWaitForCallback(t, browser, downstreamCallbackURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
func requestAuthorizationUsingBrowserAuthcodeFlowOIDCWithIDPChooserPage(t *testing.T, downstreamIssuer, downstreamAuthorizeURL, downstreamCallbackURL, _, _ string, httpClient *http.Client) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
browser := openBrowserAndNavigateToAuthorizeURL(t, downstreamAuthorizeURL, httpClient)
|
|
||||||
|
|
||||||
t.Log("waiting for redirect to IDP chooser page")
|
|
||||||
browser.WaitForURL(t, regexp.MustCompile(fmt.Sprintf(`\A%s/choose_identity_provider.*\z`, downstreamIssuer)))
|
|
||||||
|
|
||||||
t.Log("waiting for any IDP chooser button to be visible")
|
|
||||||
browser.WaitForVisibleElements(t, "button")
|
|
||||||
|
|
||||||
t.Log("clicking the first IDP chooser button")
|
|
||||||
browser.ClickFirstMatch(t, "button")
|
|
||||||
|
|
||||||
loginToUpstreamOIDCAndWaitForCallback(t, browser, downstreamCallbackURL)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestAuthorizationUsingBrowserAuthcodeFlowLDAP(t *testing.T, downstreamIssuer, downstreamAuthorizeURL, downstreamCallbackURL, username, password string, httpClient *http.Client) {
|
func requestAuthorizationUsingBrowserAuthcodeFlowLDAP(t *testing.T, downstreamIssuer, downstreamAuthorizeURL, downstreamCallbackURL, username, password string, httpClient *http.Client) {
|
||||||
|
@ -184,38 +184,38 @@ func (b *Browser) Title(t *testing.T) string {
|
|||||||
return title
|
return title
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Browser) WaitForVisibleElements(t *testing.T, cssSelectors ...string) {
|
func (b *Browser) WaitForVisibleElements(t *testing.T, selectors ...string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
for _, s := range cssSelectors {
|
for _, s := range selectors {
|
||||||
b.runWithTimeout(t, b.timeout(), chromedp.WaitVisible(s, chromedp.ByQuery))
|
b.runWithTimeout(t, b.timeout(), chromedp.WaitVisible(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Browser) TextOfFirstMatch(t *testing.T, cssSelector string) string {
|
func (b *Browser) TextOfFirstMatch(t *testing.T, selector string) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var text string
|
var text string
|
||||||
b.runWithTimeout(t, b.timeout(), chromedp.Text(cssSelector, &text, chromedp.NodeVisible, chromedp.ByQuery))
|
b.runWithTimeout(t, b.timeout(), chromedp.Text(selector, &text, chromedp.NodeVisible))
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Browser) AttrValueOfFirstMatch(t *testing.T, cssSelector string, attributeName string) string {
|
func (b *Browser) AttrValueOfFirstMatch(t *testing.T, selector string, attributeName string) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var value string
|
var value string
|
||||||
var ok bool
|
var ok bool
|
||||||
b.runWithTimeout(t, b.timeout(), chromedp.AttributeValue(cssSelector, attributeName, &value, &ok, chromedp.ByQuery))
|
b.runWithTimeout(t, b.timeout(), chromedp.AttributeValue(selector, attributeName, &value, &ok))
|
||||||
require.Truef(t, ok, "did not find attribute named %q on first element returned by selector %q", attributeName, cssSelector)
|
require.Truef(t, ok, "did not find attribute named %q on first element returned by selector %q", attributeName, selector)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Browser) SendKeysToFirstMatch(t *testing.T, cssSelector string, runesToType string) {
|
func (b *Browser) SendKeysToFirstMatch(t *testing.T, selector string, runesToType string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
b.runWithTimeout(t, b.timeout(), chromedp.SendKeys(cssSelector, runesToType, chromedp.NodeVisible, chromedp.NodeEnabled, chromedp.ByQuery))
|
b.runWithTimeout(t, b.timeout(), chromedp.SendKeys(selector, runesToType, chromedp.NodeVisible, chromedp.NodeEnabled))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Browser) ClickFirstMatch(t *testing.T, cssSelector string) string {
|
func (b *Browser) ClickFirstMatch(t *testing.T, selector string) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var text string
|
var text string
|
||||||
b.runWithTimeout(t, b.timeout(), chromedp.Click(cssSelector, chromedp.NodeVisible, chromedp.NodeEnabled, chromedp.ByQuery))
|
b.runWithTimeout(t, b.timeout(), chromedp.Click(selector, chromedp.NodeVisible, chromedp.NodeEnabled))
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user