Merge pull request #982 from vmware-tanzu/upstream-ldap-group-refresh-skip
Only run group refresh when the skipGroupRefresh boolean isn't set
This commit is contained in:
commit
339bb84765
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -131,6 +131,31 @@ type ActiveDirectoryIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes ActiveDirectoryIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an ActiveDirectory identity provider.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -119,6 +119,31 @@ type LDAPIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
|
@ -119,6 +119,30 @@ spec:
|
||||
search can be slow for some Active Directory servers. To disable
|
||||
it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this Active Directory identity
|
||||
|
@ -111,6 +111,30 @@ spec:
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as "member={}".
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this LDAP identity provider,
|
||||
|
8
generated/1.17/README.adoc
generated
8
generated/1.17/README.adoc
generated
@ -801,6 +801,10 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". Optional, when not specified it will be based on the result of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). The default behavior searches your entire domain for groups. It may make sense to specify a subtree as a search base if you wish to exclude some groups for security reasons or to make searches faster.
|
||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
@ -988,6 +992,10 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". When not specified, no group search will be performed and authenticated users will not belong to any groups from the LDAP provider. Also, when not specified, the values of Filter and Attributes are ignored.
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -131,6 +131,31 @@ type ActiveDirectoryIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes ActiveDirectoryIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an ActiveDirectory identity provider.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -119,6 +119,31 @@ type LDAPIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
|
@ -119,6 +119,30 @@ spec:
|
||||
search can be slow for some Active Directory servers. To disable
|
||||
it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this Active Directory identity
|
||||
|
@ -111,6 +111,30 @@ spec:
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as "member={}".
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this LDAP identity provider,
|
||||
|
8
generated/1.18/README.adoc
generated
8
generated/1.18/README.adoc
generated
@ -801,6 +801,10 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". Optional, when not specified it will be based on the result of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). The default behavior searches your entire domain for groups. It may make sense to specify a subtree as a search base if you wish to exclude some groups for security reasons or to make searches faster.
|
||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
@ -988,6 +992,10 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". When not specified, no group search will be performed and authenticated users will not belong to any groups from the LDAP provider. Also, when not specified, the values of Filter and Attributes are ignored.
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -131,6 +131,31 @@ type ActiveDirectoryIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes ActiveDirectoryIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an ActiveDirectory identity provider.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -119,6 +119,31 @@ type LDAPIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
|
@ -119,6 +119,30 @@ spec:
|
||||
search can be slow for some Active Directory servers. To disable
|
||||
it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this Active Directory identity
|
||||
|
@ -111,6 +111,30 @@ spec:
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as "member={}".
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this LDAP identity provider,
|
||||
|
8
generated/1.19/README.adoc
generated
8
generated/1.19/README.adoc
generated
@ -801,6 +801,10 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". Optional, when not specified it will be based on the result of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). The default behavior searches your entire domain for groups. It may make sense to specify a subtree as a search base if you wish to exclude some groups for security reasons or to make searches faster.
|
||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
@ -988,6 +992,10 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". When not specified, no group search will be performed and authenticated users will not belong to any groups from the LDAP provider. Also, when not specified, the values of Filter and Attributes are ignored.
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -131,6 +131,31 @@ type ActiveDirectoryIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes ActiveDirectoryIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an ActiveDirectory identity provider.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -119,6 +119,31 @@ type LDAPIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
|
@ -119,6 +119,30 @@ spec:
|
||||
search can be slow for some Active Directory servers. To disable
|
||||
it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this Active Directory identity
|
||||
|
@ -111,6 +111,30 @@ spec:
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as "member={}".
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this LDAP identity provider,
|
||||
|
8
generated/1.20/README.adoc
generated
8
generated/1.20/README.adoc
generated
@ -801,6 +801,10 @@ ActiveDirectoryIdentityProvider describes the configuration of an upstream Micro
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". Optional, when not specified it will be based on the result of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). The default behavior searches your entire domain for groups. It may make sense to specify a subtree as a search base if you wish to exclude some groups for security reasons or to make searches faster.
|
||||
| *`filter`* __string__ | Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". This searches nested groups by default. Note that nested group search can be slow for some Active Directory servers. To disable it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-activedirectoryidentityprovidergroupsearchattributes[$$ActiveDirectoryIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
@ -988,6 +992,10 @@ LDAPIdentityProvider describes the configuration of an upstream Lightweight Dire
|
||||
| *`base`* __string__ | Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". When not specified, no group search will be performed and authenticated users will not belong to any groups from the LDAP provider. Also, when not specified, the values of Filter and Attributes are ignored.
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for groups for a user. The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the dn (distinguished name) of the user entry found as a result of the user search. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". For more information about LDAP filters, see https://ldap.com/ldap-filters. Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used. Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityprovidergroupsearchattributes[$$LDAPIdentityProviderGroupSearchAttributes$$]__ | Attributes specifies how the group's information should be read from each LDAP entry which was found as the result of the group search.
|
||||
| *`skipGroupRefresh`* __boolean__ | The user's group membership is refreshed as they interact with the supervisor to obtain new credentials (as their old credentials expire). This allows group membership changes to be quickly reflected into Kubernetes clusters. Since group membership is often used to bind authorization policies, it is important to keep the groups observed in Kubernetes clusters in-sync with the identity provider.
|
||||
In some environments, frequent group membership queries may result in a significant performance impact on the identity provider and/or the supervisor. The best approach to handle performance impacts is to tweak the group query to be more performant, for example by disabling nested group search or by using a more targeted group search base.
|
||||
If the group search query cannot be made performant and you are willing to have group memberships remain static for approximately a day, then set skipGroupRefresh to true. This is an insecure configuration as authorization policies that are bound to group membership will not notice if a user has been removed from a particular group until their next login.
|
||||
This is an experimental feature that may be removed or significantly altered in the future. Consumers of this configuration should carefully read all release notes before upgrading to ensure that the meaning of this field has not changed.
|
||||
|===
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -131,6 +131,31 @@ type ActiveDirectoryIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes ActiveDirectoryIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an ActiveDirectory identity provider.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -119,6 +119,31 @@ type LDAPIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
|
@ -119,6 +119,30 @@ spec:
|
||||
search can be slow for some Active Directory servers. To disable
|
||||
it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this Active Directory identity
|
||||
|
@ -111,6 +111,30 @@ spec:
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as "member={}".
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
type: boolean
|
||||
type: object
|
||||
host:
|
||||
description: 'Host is the hostname of this LDAP identity provider,
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -131,6 +131,31 @@ type ActiveDirectoryIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes ActiveDirectoryIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an ActiveDirectory identity provider.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@ -119,6 +119,31 @@ type LDAPIdentityProviderGroupSearch struct {
|
||||
// the result of the group search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderGroupSearchAttributes `json:"attributes,omitempty"`
|
||||
|
||||
// The user's group membership is refreshed as they interact with the supervisor
|
||||
// to obtain new credentials (as their old credentials expire). This allows group
|
||||
// membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
// group membership is often used to bind authorization policies, it is important
|
||||
// to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
// provider.
|
||||
//
|
||||
// In some environments, frequent group membership queries may result in a
|
||||
// significant performance impact on the identity provider and/or the supervisor.
|
||||
// The best approach to handle performance impacts is to tweak the group query
|
||||
// to be more performant, for example by disabling nested group search or by
|
||||
// using a more targeted group search base.
|
||||
//
|
||||
// If the group search query cannot be made performant and you are willing to
|
||||
// have group memberships remain static for approximately a day, then set
|
||||
// skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
// policies that are bound to group membership will not notice if a user has
|
||||
// been removed from a particular group until their next login.
|
||||
//
|
||||
// This is an experimental feature that may be removed or significantly altered
|
||||
// in the future. Consumers of this configuration should carefully read all
|
||||
// release notes before upgrading to ensure that the meaning of this field has
|
||||
// not changed.
|
||||
SkipGroupRefresh bool `json:"skipGroupRefresh,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
|
@ -333,6 +333,7 @@ func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context,
|
||||
Base: spec.GroupSearch.Base,
|
||||
Filter: adUpstreamImpl.Spec().GroupSearch().Filter(),
|
||||
GroupNameAttribute: adUpstreamImpl.Spec().GroupSearch().GroupNameAttribute(),
|
||||
SkipGroupRefresh: spec.GroupSearch.SkipGroupRefresh,
|
||||
},
|
||||
Dialer: c.ldapDialer,
|
||||
UIDAttributeParsingOverrides: map[string]func(*ldap.Entry) (string, error){
|
||||
|
@ -192,6 +192,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
|
||||
Attributes: v1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{
|
||||
GroupName: testGroupNameAttrName,
|
||||
},
|
||||
SkipGroupRefresh: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -1907,6 +1908,75 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
|
||||
SearchBaseFoundCondition: condPtr(withoutTime(searchBaseFoundInRootDSECondition(0))),
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "skipping group refresh is valid",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
|
||||
upstream.Spec.GroupSearch.SkipGroupRefresh = true
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{
|
||||
{
|
||||
Name: testName,
|
||||
ResourceUID: testResourceUID,
|
||||
Host: testHost,
|
||||
ConnectionProtocol: upstreamldap.TLS,
|
||||
CABundle: testCABundle,
|
||||
BindUsername: testBindUsername,
|
||||
BindPassword: testBindPassword,
|
||||
UserSearch: upstreamldap.UserSearchConfig{
|
||||
Base: testUserSearchBase,
|
||||
Filter: testUserSearchFilter,
|
||||
UsernameAttribute: testUsernameAttrName,
|
||||
UIDAttribute: testUIDAttrName,
|
||||
},
|
||||
GroupSearch: upstreamldap.GroupSearchConfig{
|
||||
Base: testGroupSearchBase,
|
||||
Filter: testGroupSearchFilter,
|
||||
GroupNameAttribute: testGroupNameAttrName,
|
||||
SkipGroupRefresh: true,
|
||||
},
|
||||
UIDAttributeParsingOverrides: map[string]func(*ldap.Entry) (string, error){"objectGUID": microsoftUUIDFromBinaryAttr("objectGUID")},
|
||||
RefreshAttributeChecks: map[string]func(*ldap.Entry, provider.StoredRefreshAttributes) error{
|
||||
"pwdLastSet": upstreamldap.AttributeUnchangedSinceLogin("pwdLastSet"),
|
||||
"userAccountControl": validUserAccountControl,
|
||||
"msDS-User-Account-Control-Computed": validComputedUserAccountControl,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
|
||||
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
bindSecretValidTrueCondition(1234),
|
||||
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
|
||||
searchBaseFoundInConfigCondition(1234),
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
LastTransitionTime: now,
|
||||
Reason: "Success",
|
||||
Message: "loaded TLS configuration",
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
wantValidatedSettings: map[string]upstreamwatchers.ValidatedSettings{testName: {
|
||||
BindSecretResourceVersion: "4242",
|
||||
LDAPConnectionProtocol: upstreamldap.TLS,
|
||||
UserSearchBase: testUserSearchBase,
|
||||
GroupSearchBase: testGroupSearchBase,
|
||||
IDPSpecGeneration: 1234,
|
||||
ConnectionValidCondition: condPtr(activeDirectoryConnectionValidTrueConditionWithoutTimeOrGeneration("4242")),
|
||||
SearchBaseFoundCondition: condPtr(withoutTime(searchBaseFoundInConfigCondition(0))),
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -239,6 +239,7 @@ func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *
|
||||
Base: spec.GroupSearch.Base,
|
||||
Filter: spec.GroupSearch.Filter,
|
||||
GroupNameAttribute: spec.GroupSearch.Attributes.GroupName,
|
||||
SkipGroupRefresh: spec.GroupSearch.SkipGroupRefresh,
|
||||
},
|
||||
Dialer: c.ldapDialer,
|
||||
}
|
||||
|
@ -196,6 +196,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
|
||||
Attributes: v1alpha1.LDAPIdentityProviderGroupSearchAttributes{
|
||||
GroupName: testGroupNameAttrName,
|
||||
},
|
||||
SkipGroupRefresh: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -1053,6 +1054,67 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
|
||||
IDPSpecGeneration: 1234,
|
||||
ConnectionValidCondition: condPtr(ldapConnectionValidTrueConditionWithoutTimeOrGeneration("4242")),
|
||||
}}},
|
||||
{
|
||||
name: "skipping group refresh is valid",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Spec.GroupSearch.SkipGroupRefresh = true
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{
|
||||
{
|
||||
Name: testName,
|
||||
ResourceUID: testResourceUID,
|
||||
Host: testHost,
|
||||
ConnectionProtocol: upstreamldap.TLS,
|
||||
CABundle: testCABundle,
|
||||
BindUsername: testBindUsername,
|
||||
BindPassword: testBindPassword,
|
||||
UserSearch: upstreamldap.UserSearchConfig{
|
||||
Base: testUserSearchBase,
|
||||
Filter: testUserSearchFilter,
|
||||
UsernameAttribute: testUsernameAttrName,
|
||||
UIDAttribute: testUIDAttrName,
|
||||
},
|
||||
GroupSearch: upstreamldap.GroupSearchConfig{
|
||||
Base: testGroupSearchBase,
|
||||
Filter: testGroupSearchFilter,
|
||||
GroupNameAttribute: testGroupNameAttrName,
|
||||
SkipGroupRefresh: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
bindSecretValidTrueCondition(1234),
|
||||
ldapConnectionValidTrueCondition(1234, "4242"),
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
LastTransitionTime: now,
|
||||
Reason: "Success",
|
||||
Message: "loaded TLS configuration",
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
wantValidatedSettings: map[string]upstreamwatchers.ValidatedSettings{testName: {
|
||||
BindSecretResourceVersion: "4242",
|
||||
LDAPConnectionProtocol: upstreamldap.TLS,
|
||||
UserSearchBase: testUserSearchBase,
|
||||
GroupSearchBase: testGroupSearchBase,
|
||||
IDPSpecGeneration: 1234,
|
||||
ConnectionValidCondition: condPtr(ldapConnectionValidTrueConditionWithoutTimeOrGeneration("4242")),
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -115,6 +115,7 @@ type StoredRefreshAttributes struct {
|
||||
Username string
|
||||
Subject string
|
||||
DN string
|
||||
Groups []string
|
||||
AdditionalAttributes map[string]string
|
||||
}
|
||||
|
||||
|
@ -275,6 +275,10 @@ func upstreamLDAPRefresh(ctx context.Context, providerCache oidc.UpstreamIdentit
|
||||
return err
|
||||
}
|
||||
subject := session.Fosite.Claims.Subject
|
||||
oldGroups, err := getDownstreamGroupsFromPinnipedSession(session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s := session.Custom
|
||||
|
||||
@ -305,6 +309,7 @@ func upstreamLDAPRefresh(ctx context.Context, providerCache oidc.UpstreamIdentit
|
||||
Username: username,
|
||||
Subject: subject,
|
||||
DN: dn,
|
||||
Groups: oldGroups,
|
||||
AdditionalAttributes: additionalAttributes,
|
||||
})
|
||||
if err != nil {
|
||||
@ -353,7 +358,7 @@ func getDownstreamUsernameFromPinnipedSession(session *psession.PinnipedSession)
|
||||
if extra == nil {
|
||||
return "", errorsx.WithStack(errMissingUpstreamSessionInternalError)
|
||||
}
|
||||
downstreamUsernameInterface := extra["username"]
|
||||
downstreamUsernameInterface := extra[oidc.DownstreamUsernameClaim]
|
||||
if downstreamUsernameInterface == nil {
|
||||
return "", errorsx.WithStack(errMissingUpstreamSessionInternalError)
|
||||
}
|
||||
@ -363,3 +368,28 @@ func getDownstreamUsernameFromPinnipedSession(session *psession.PinnipedSession)
|
||||
}
|
||||
return downstreamUsername, nil
|
||||
}
|
||||
|
||||
func getDownstreamGroupsFromPinnipedSession(session *psession.PinnipedSession) ([]string, error) {
|
||||
extra := session.Fosite.Claims.Extra
|
||||
if extra == nil {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError)
|
||||
}
|
||||
downstreamGroupsInterface := extra[oidc.DownstreamGroupsClaim]
|
||||
if downstreamGroupsInterface == nil {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError)
|
||||
}
|
||||
downstreamGroupsInterfaceList, ok := downstreamGroupsInterface.([]interface{})
|
||||
if !ok {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError)
|
||||
}
|
||||
|
||||
downstreamGroups := make([]string, 0, len(downstreamGroupsInterfaceList))
|
||||
for _, downstreamGroupInterface := range downstreamGroupsInterfaceList {
|
||||
downstreamGroup, ok := downstreamGroupInterface.(string)
|
||||
if !ok || len(downstreamGroup) == 0 {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError)
|
||||
}
|
||||
downstreamGroups = append(downstreamGroups, downstreamGroup)
|
||||
}
|
||||
return downstreamGroups, nil
|
||||
}
|
||||
|
@ -150,6 +150,11 @@ type GroupSearchConfig struct {
|
||||
// GroupNameAttribute is the attribute in the LDAP group entry from which the group name should be
|
||||
// retrieved. Empty means to use 'cn'.
|
||||
GroupNameAttribute string
|
||||
|
||||
// SkipGroupRefresh skips the group refresh operation that occurs with each refresh
|
||||
// (every 5 minutes). This can be done if group search is very slow or resource intensive for the LDAP
|
||||
// server.
|
||||
SkipGroupRefresh bool
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
@ -230,6 +235,10 @@ func (p *Provider) PerformRefresh(ctx context.Context, storedRefreshAttributes p
|
||||
}
|
||||
}
|
||||
|
||||
if p.c.GroupSearch.SkipGroupRefresh {
|
||||
return storedRefreshAttributes.Groups, nil
|
||||
}
|
||||
|
||||
mappedGroupNames, err := p.searchGroupsForUserDN(conn, userDN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1298,6 +1298,37 @@ func TestUpstreamRefresh(t *testing.T) {
|
||||
},
|
||||
wantGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "happy path where group search is configured but skipGroupRefresh is set",
|
||||
providerConfig: &ProviderConfig{
|
||||
Name: "some-provider-name",
|
||||
Host: testHost,
|
||||
CABundle: nil, // this field is only used by the production dialer, which is replaced by a mock for this test
|
||||
ConnectionProtocol: TLS,
|
||||
BindUsername: testBindUsername,
|
||||
BindPassword: testBindPassword,
|
||||
UserSearch: UserSearchConfig{
|
||||
Base: testUserSearchBase,
|
||||
UIDAttribute: testUserSearchUIDAttribute,
|
||||
UsernameAttribute: testUserSearchUsernameAttribute,
|
||||
},
|
||||
GroupSearch: GroupSearchConfig{
|
||||
Base: testGroupSearchBase,
|
||||
Filter: testGroupSearchFilter,
|
||||
GroupNameAttribute: testGroupSearchGroupNameAttribute,
|
||||
SkipGroupRefresh: true,
|
||||
},
|
||||
RefreshAttributeChecks: map[string]func(*ldap.Entry, provider.StoredRefreshAttributes) error{
|
||||
pwdLastSetAttribute: AttributeUnchangedSinceLogin(pwdLastSetAttribute),
|
||||
},
|
||||
},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Search(expectedUserSearch).Return(happyPathUserSearchResult, nil).Times(1) // note that group search is not expected
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantGroups: nil, // do not update groups
|
||||
},
|
||||
{
|
||||
name: "error where dial fails",
|
||||
providerConfig: providerConfig,
|
||||
|
@ -51,25 +51,24 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
maybeSkip func(t *testing.T)
|
||||
createTestUser func(t *testing.T) (string, string)
|
||||
deleteTestUser func(t *testing.T, username string)
|
||||
requestAuthorization func(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL, username, password string, httpClient *http.Client)
|
||||
createIDP func(t *testing.T) string
|
||||
wantDownstreamIDTokenSubjectToMatch string
|
||||
wantDownstreamIDTokenUsernameToMatch func(username string) string
|
||||
wantDownstreamIDTokenGroups []string
|
||||
wantDownstreamIDTokenGroupsAfterRefresh []string
|
||||
wantErrorDescription string
|
||||
wantErrorType string
|
||||
name string
|
||||
maybeSkip func(t *testing.T)
|
||||
createTestUser func(t *testing.T) (string, string)
|
||||
deleteTestUser func(t *testing.T, username string)
|
||||
requestAuthorization func(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL, username, password string, httpClient *http.Client)
|
||||
createIDP func(t *testing.T) string
|
||||
wantDownstreamIDTokenSubjectToMatch string
|
||||
wantDownstreamIDTokenUsernameToMatch func(username string) string
|
||||
wantDownstreamIDTokenGroups []string
|
||||
wantErrorDescription string
|
||||
wantErrorType string
|
||||
|
||||
// Either revoke the user's session on the upstream provider, or manipulate the user's session
|
||||
// data in such a way that it should cause the next upstream refresh attempt to fail.
|
||||
breakRefreshSessionData func(t *testing.T, sessionData *psession.PinnipedSession, idpName, username string)
|
||||
// Edit the refresh session data between the initial login and the refresh, which is expected to
|
||||
// succeed.
|
||||
editRefreshSessionDataWithoutBreaking func(t *testing.T, sessionData *psession.PinnipedSession, idpName, username string)
|
||||
editRefreshSessionDataWithoutBreaking func(t *testing.T, sessionData *psession.PinnipedSession, idpName, username string) []string
|
||||
}{
|
||||
{
|
||||
name: "oidc with default username and groups claim settings",
|
||||
@ -132,13 +131,14 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
wantDownstreamIDTokenSubjectToMatch: "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Issuer+"?sub=") + ".+",
|
||||
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { return "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Username) + "$" },
|
||||
wantDownstreamIDTokenGroups: env.SupervisorUpstreamOIDC.ExpectedGroups,
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) {
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) []string {
|
||||
// even if we update this group to the wrong thing, we expect that it will return to the correct
|
||||
// value after we refresh.
|
||||
// However if there are no expected groups then they will not update, so we should skip this.
|
||||
if len(env.SupervisorUpstreamOIDC.ExpectedGroups) > 0 {
|
||||
sessionData.Fosite.Claims.Extra["groups"] = []string{"some-wrong-group", "some-other-group"}
|
||||
}
|
||||
return env.SupervisorUpstreamOIDC.ExpectedGroups
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -284,10 +284,95 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
false,
|
||||
)
|
||||
},
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) {
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) []string {
|
||||
// even if we update this group to the wrong thing, we expect that it will return to the correct
|
||||
// value after we refresh.
|
||||
sessionData.Fosite.Claims.Extra["groups"] = []string{"some-wrong-group", "some-other-group"}
|
||||
return env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs
|
||||
},
|
||||
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
|
||||
customSessionData := pinnipedSession.Custom
|
||||
require.Equal(t, psession.ProviderTypeLDAP, customSessionData.ProviderType)
|
||||
require.NotEmpty(t, customSessionData.LDAP.UserDN)
|
||||
fositeSessionData := pinnipedSession.Fosite
|
||||
fositeSessionData.Claims.Subject = "not-right"
|
||||
},
|
||||
// the ID token Subject should be the Host URL plus the value pulled from the requested UserSearch.Attributes.UID attribute
|
||||
wantDownstreamIDTokenSubjectToMatch: "^" + regexp.QuoteMeta(
|
||||
"ldaps://"+env.SupervisorUpstreamLDAP.Host+
|
||||
"?base="+url.QueryEscape(env.SupervisorUpstreamLDAP.UserSearchBase)+
|
||||
"&sub="+base64.RawURLEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.TestUserUniqueIDAttributeValue)),
|
||||
) + "$",
|
||||
// the ID token Username should have been pulled from the requested UserSearch.Attributes.Username attribute
|
||||
wantDownstreamIDTokenUsernameToMatch: func(_ string) string {
|
||||
return "^" + regexp.QuoteMeta(env.SupervisorUpstreamLDAP.TestUserMailAttributeValue) + "$"
|
||||
},
|
||||
wantDownstreamIDTokenGroups: env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs,
|
||||
},
|
||||
{
|
||||
name: "ldap skip group refresh",
|
||||
maybeSkip: func(t *testing.T) {
|
||||
t.Helper()
|
||||
if len(env.ToolsNamespace) == 0 && !env.HasCapability(testlib.CanReachInternetLDAPPorts) {
|
||||
t.Skip("LDAP integration test requires connectivity to an LDAP server")
|
||||
}
|
||||
},
|
||||
createIDP: func(t *testing.T) string {
|
||||
t.Helper()
|
||||
secret := testlib.CreateTestSecret(t, env.SupervisorNamespace, "ldap-service-account", v1.SecretTypeBasicAuth,
|
||||
map[string]string{
|
||||
v1.BasicAuthUsernameKey: env.SupervisorUpstreamLDAP.BindUsername,
|
||||
v1.BasicAuthPasswordKey: env.SupervisorUpstreamLDAP.BindPassword,
|
||||
},
|
||||
)
|
||||
ldapIDP := testlib.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{
|
||||
Host: env.SupervisorUpstreamLDAP.Host,
|
||||
TLS: &idpv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamLDAP.CABundle)),
|
||||
},
|
||||
Bind: idpv1alpha1.LDAPIdentityProviderBind{
|
||||
SecretName: secret.Name,
|
||||
},
|
||||
UserSearch: idpv1alpha1.LDAPIdentityProviderUserSearch{
|
||||
Base: env.SupervisorUpstreamLDAP.UserSearchBase,
|
||||
Filter: "",
|
||||
Attributes: idpv1alpha1.LDAPIdentityProviderUserSearchAttributes{
|
||||
Username: env.SupervisorUpstreamLDAP.TestUserMailAttributeName,
|
||||
UID: env.SupervisorUpstreamLDAP.TestUserUniqueIDAttributeName,
|
||||
},
|
||||
},
|
||||
GroupSearch: idpv1alpha1.LDAPIdentityProviderGroupSearch{
|
||||
Base: env.SupervisorUpstreamLDAP.GroupSearchBase,
|
||||
Filter: "",
|
||||
Attributes: idpv1alpha1.LDAPIdentityProviderGroupSearchAttributes{
|
||||
GroupName: "dn",
|
||||
},
|
||||
SkipGroupRefresh: true,
|
||||
},
|
||||
}, idpv1alpha1.LDAPPhaseReady)
|
||||
expectedMsg := fmt.Sprintf(
|
||||
`successfully able to connect to "%s" and bind as user "%s" [validated with Secret "%s" at version "%s"]`,
|
||||
env.SupervisorUpstreamLDAP.Host, env.SupervisorUpstreamLDAP.BindUsername,
|
||||
secret.Name, secret.ResourceVersion,
|
||||
)
|
||||
requireSuccessfulLDAPIdentityProviderConditions(t, ldapIDP, expectedMsg)
|
||||
return ldapIDP.Name
|
||||
},
|
||||
requestAuthorization: func(t *testing.T, downstreamAuthorizeURL, _, _, _ string, httpClient *http.Client) {
|
||||
requestAuthorizationUsingCLIPasswordFlow(t,
|
||||
downstreamAuthorizeURL,
|
||||
env.SupervisorUpstreamLDAP.TestUserMailAttributeValue, // username to present to server during login
|
||||
env.SupervisorUpstreamLDAP.TestUserPassword, // password to present to server during login
|
||||
httpClient,
|
||||
false,
|
||||
)
|
||||
},
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) []string {
|
||||
// update the list of groups to the wrong thing and see that they do not get updated because
|
||||
// skip group refresh is set
|
||||
wrongGroups := []string{"some-wrong-group", "some-other-group"}
|
||||
sessionData.Fosite.Claims.Extra["groups"] = wrongGroups
|
||||
return wrongGroups
|
||||
},
|
||||
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
|
||||
customSessionData := pinnipedSession.Custom
|
||||
@ -372,10 +457,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
false,
|
||||
)
|
||||
},
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) {
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) []string {
|
||||
// even if we update this group to the wrong thing, we expect that it will return to the correct
|
||||
// value after we refresh.
|
||||
// value (no groups) after we refresh.
|
||||
sessionData.Fosite.Claims.Extra["groups"] = []string{"some-wrong-group", "some-other-group"}
|
||||
return []string{}
|
||||
},
|
||||
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
|
||||
customSessionData := pinnipedSession.Custom
|
||||
@ -1420,7 +1506,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
false,
|
||||
)
|
||||
},
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, pinnipedSession *psession.PinnipedSession, idpName, _ string) {
|
||||
editRefreshSessionDataWithoutBreaking: func(t *testing.T, pinnipedSession *psession.PinnipedSession, idpName, _ string) []string {
|
||||
// get the idp, update the config.
|
||||
client := testlib.NewSupervisorClientset(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
@ -1434,6 +1520,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
_, err = upstreams.Update(ctx, ldapIDP, metav1.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
time.Sleep(10 * time.Second) // wait for controllers to pick up the change
|
||||
return []string{}
|
||||
},
|
||||
// the ID token Subject should be the Host URL plus the value pulled from the requested UserSearch.Attributes.UID attribute
|
||||
wantDownstreamIDTokenSubjectToMatch: "^" + regexp.QuoteMeta(
|
||||
@ -1445,8 +1532,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
wantDownstreamIDTokenUsernameToMatch: func(_ string) string {
|
||||
return "^" + regexp.QuoteMeta(env.SupervisorUpstreamLDAP.TestUserMailAttributeValue) + "$"
|
||||
},
|
||||
wantDownstreamIDTokenGroups: env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs,
|
||||
wantDownstreamIDTokenGroupsAfterRefresh: []string{},
|
||||
wantDownstreamIDTokenGroups: env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
@ -1464,7 +1550,6 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
tt.wantDownstreamIDTokenSubjectToMatch,
|
||||
tt.wantDownstreamIDTokenUsernameToMatch,
|
||||
tt.wantDownstreamIDTokenGroups,
|
||||
tt.wantDownstreamIDTokenGroupsAfterRefresh,
|
||||
tt.wantErrorDescription,
|
||||
tt.wantErrorType,
|
||||
)
|
||||
@ -1593,14 +1678,13 @@ func testSupervisorLogin(
|
||||
t *testing.T,
|
||||
createIDP func(t *testing.T) string,
|
||||
requestAuthorization func(t *testing.T, downstreamAuthorizeURL string, downstreamCallbackURL string, username string, password string, httpClient *http.Client),
|
||||
editRefreshSessionDataWithoutBreaking func(t *testing.T, pinnipedSession *psession.PinnipedSession, idpName, username string),
|
||||
editRefreshSessionDataWithoutBreaking func(t *testing.T, pinnipedSession *psession.PinnipedSession, idpName, username string) []string,
|
||||
breakRefreshSessionData func(t *testing.T, pinnipedSession *psession.PinnipedSession, idpName, username string),
|
||||
createTestUser func(t *testing.T) (string, string),
|
||||
deleteTestUser func(t *testing.T, username string),
|
||||
wantDownstreamIDTokenSubjectToMatch string,
|
||||
wantDownstreamIDTokenUsernameToMatch func(username string) string,
|
||||
wantDownstreamIDTokenGroups []string,
|
||||
wantDownstreamIDTokenGroupsAfterRefresh []string,
|
||||
wantErrorDescription string,
|
||||
wantErrorType string,
|
||||
) {
|
||||
@ -1754,6 +1838,7 @@ func testSupervisorLogin(
|
||||
// token exchange on the original token
|
||||
doTokenExchange(t, &downstreamOAuth2Config, tokenResponse, httpClient, discovery)
|
||||
|
||||
refreshedGroups := wantDownstreamIDTokenGroups
|
||||
if editRefreshSessionDataWithoutBreaking != nil {
|
||||
latestRefreshToken := tokenResponse.RefreshToken
|
||||
signatureOfLatestRefreshToken := getFositeDataSignature(t, latestRefreshToken)
|
||||
@ -1769,7 +1854,7 @@ func testSupervisorLogin(
|
||||
pinnipedSession, ok := storedRefreshSession.GetSession().(*psession.PinnipedSession)
|
||||
require.True(t, ok, "should have been able to cast session data to PinnipedSession")
|
||||
|
||||
editRefreshSessionDataWithoutBreaking(t, pinnipedSession, idpName, username)
|
||||
refreshedGroups = editRefreshSessionDataWithoutBreaking(t, pinnipedSession, idpName, username)
|
||||
|
||||
// Then save the mutated Secret back to Kubernetes.
|
||||
// There is no update function, so delete and create again at the same name.
|
||||
@ -1783,12 +1868,9 @@ func testSupervisorLogin(
|
||||
|
||||
// When refreshing, expect to get an "at_hash" claim, but no "nonce" claim.
|
||||
expectRefreshedIDTokenClaims := []string{"iss", "exp", "sub", "aud", "auth_time", "iat", "jti", "rat", "username", "groups", "at_hash"}
|
||||
if wantDownstreamIDTokenGroupsAfterRefresh == nil {
|
||||
wantDownstreamIDTokenGroupsAfterRefresh = wantDownstreamIDTokenGroups
|
||||
}
|
||||
verifyTokenResponse(t,
|
||||
refreshedTokenResponse, discovery, downstreamOAuth2Config, "",
|
||||
expectRefreshedIDTokenClaims, wantDownstreamIDTokenSubjectToMatch, wantDownstreamIDTokenUsernameToMatch(username), wantDownstreamIDTokenGroupsAfterRefresh)
|
||||
expectRefreshedIDTokenClaims, wantDownstreamIDTokenSubjectToMatch, wantDownstreamIDTokenUsernameToMatch(username), refreshedGroups)
|
||||
|
||||
require.NotEqual(t, tokenResponse.AccessToken, refreshedTokenResponse.AccessToken)
|
||||
require.NotEqual(t, tokenResponse.RefreshToken, refreshedTokenResponse.RefreshToken)
|
||||
|
Loading…
Reference in New Issue
Block a user