iam/authn: Introduce feature flag for authz resource mutations (#108698)
* iam/authz: introduce feature flag for authz resource mutations * lint: fix typo
This commit is contained in:
@@ -995,6 +995,10 @@ export interface FeatureToggles {
|
||||
*/
|
||||
kubernetesAuthzApis?: boolean;
|
||||
/**
|
||||
* Enables create, delete, and update mutations for resources owned by IAM identity
|
||||
*/
|
||||
kubernetesAuthnMutation?: boolean;
|
||||
/**
|
||||
* Enables restore deleted dashboards feature
|
||||
* @default false
|
||||
*/
|
||||
|
||||
@@ -44,6 +44,9 @@ type IdentityAccessManagementAPIBuilder struct {
|
||||
// Toggle for enabling authz management apis
|
||||
enableAuthZApis bool
|
||||
|
||||
// Toggle for enabling authn mutation
|
||||
enableAuthnMutation bool
|
||||
|
||||
// Toggle for enabling dual writer
|
||||
enableDualWriter bool
|
||||
}
|
||||
|
||||
@@ -56,16 +56,17 @@ func RegisterAPIService(
|
||||
authorizer := newIAMAuthorizer(accessClient, legacyAccessClient)
|
||||
|
||||
builder := &IdentityAccessManagementAPIBuilder{
|
||||
store: store,
|
||||
coreRolesStorage: coreRolesStorage,
|
||||
sso: ssoService,
|
||||
authorizer: authorizer,
|
||||
legacyAccessClient: legacyAccessClient,
|
||||
accessClient: accessClient,
|
||||
display: user.NewLegacyDisplayREST(store),
|
||||
reg: reg,
|
||||
enableAuthZApis: features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzApis),
|
||||
enableDualWriter: true,
|
||||
store: store,
|
||||
coreRolesStorage: coreRolesStorage,
|
||||
sso: ssoService,
|
||||
authorizer: authorizer,
|
||||
legacyAccessClient: legacyAccessClient,
|
||||
accessClient: accessClient,
|
||||
display: user.NewLegacyDisplayREST(store),
|
||||
reg: reg,
|
||||
enableAuthZApis: features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzApis),
|
||||
enableAuthnMutation: features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthnMutation),
|
||||
enableDualWriter: true,
|
||||
}
|
||||
apiregistration.RegisterAPI(builder)
|
||||
|
||||
@@ -127,7 +128,7 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
|
||||
storage[teamBindingResource.StoragePath()] = team.NewLegacyBindingStore(b.store)
|
||||
|
||||
userResource := legacyiamv0.UserResourceInfo
|
||||
legacyStore := user.NewLegacyStore(b.store, b.legacyAccessClient)
|
||||
legacyStore := user.NewLegacyStore(b.store, b.legacyAccessClient, b.enableAuthnMutation)
|
||||
storage[userResource.StoragePath()] = legacyStore
|
||||
|
||||
if b.enableDualWriter {
|
||||
|
||||
@@ -37,18 +37,19 @@ var (
|
||||
|
||||
var resource = iamv0.UserResourceInfo
|
||||
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore, ac claims.AccessClient) *LegacyStore {
|
||||
return &LegacyStore{store, ac}
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore, ac claims.AccessClient, enableAuthnMutation bool) *LegacyStore {
|
||||
return &LegacyStore{store, ac, enableAuthnMutation}
|
||||
}
|
||||
|
||||
type LegacyStore struct {
|
||||
store legacy.LegacyIdentityStore
|
||||
ac claims.AccessClient
|
||||
store legacy.LegacyIdentityStore
|
||||
ac claims.AccessClient
|
||||
enableAuthnMutation bool
|
||||
}
|
||||
|
||||
// Update implements rest.Updater.
|
||||
func (s *LegacyStore) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {
|
||||
return nil, false, fmt.Errorf("method not yet implemented")
|
||||
return nil, false, apierrors.NewMethodNotSupported(resource.GroupResource(), "update")
|
||||
}
|
||||
|
||||
// DeleteCollection implements rest.CollectionDeleter.
|
||||
@@ -58,6 +59,10 @@ func (s *LegacyStore) DeleteCollection(ctx context.Context, deleteValidation res
|
||||
|
||||
// Delete implements rest.GracefulDeleter.
|
||||
func (s *LegacyStore) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
|
||||
if !s.enableAuthnMutation {
|
||||
return nil, false, apierrors.NewMethodNotSupported(resource.GroupResource(), "delete")
|
||||
}
|
||||
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
@@ -178,6 +183,10 @@ func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetO
|
||||
|
||||
// Create implements rest.Creater.
|
||||
func (s *LegacyStore) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
|
||||
if !s.enableAuthnMutation {
|
||||
return nil, apierrors.NewMethodNotSupported(resource.GroupResource(), "create")
|
||||
}
|
||||
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1715,6 +1715,14 @@ var (
|
||||
HideFromAdminPage: true,
|
||||
HideFromDocs: true,
|
||||
},
|
||||
{
|
||||
Name: "kubernetesAuthnMutation",
|
||||
Description: "Enables create, delete, and update mutations for resources owned by IAM identity",
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: identityAccessTeam,
|
||||
HideFromAdminPage: true,
|
||||
HideFromDocs: true,
|
||||
},
|
||||
{
|
||||
Name: "restoreDashboards",
|
||||
Description: "Enables restore deleted dashboards feature",
|
||||
|
||||
@@ -223,6 +223,7 @@ alertingListViewV2PreviewToggle,privatePreview,@grafana/alerting-squad,false,fal
|
||||
alertRuleUseFiredAtForStartsAt,experimental,@grafana/alerting-squad,false,false,false
|
||||
alertingBulkActionsInUI,GA,@grafana/alerting-squad,false,false,true
|
||||
kubernetesAuthzApis,experimental,@grafana/identity-access-team,false,false,false
|
||||
kubernetesAuthnMutation,experimental,@grafana/identity-access-team,false,false,false
|
||||
restoreDashboards,experimental,@grafana/grafana-frontend-platform,false,false,false
|
||||
skipTokenRotationIfRecent,GA,@grafana/identity-access-team,false,false,false
|
||||
alertEnrichment,experimental,@grafana/alerting-squad,false,false,false
|
||||
|
||||
|
@@ -903,6 +903,10 @@ const (
|
||||
// Registers AuthZ /apis endpoint
|
||||
FlagKubernetesAuthzApis = "kubernetesAuthzApis"
|
||||
|
||||
// FlagKubernetesAuthnMutation
|
||||
// Enables create, delete, and update mutations for resources owned by IAM identity
|
||||
FlagKubernetesAuthnMutation = "kubernetesAuthnMutation"
|
||||
|
||||
// FlagRestoreDashboards
|
||||
// Enables restore deleted dashboards feature
|
||||
FlagRestoreDashboards = "restoreDashboards"
|
||||
|
||||
@@ -1670,6 +1670,23 @@
|
||||
"requiresRestart": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "kubernetesAuthnMutation",
|
||||
"resourceVersion": "1753454405614",
|
||||
"creationTimestamp": "2025-07-25T14:12:51Z",
|
||||
"annotations": {
|
||||
"grafana.app/updatedTimestamp": "2025-07-25 14:40:05.614358 +0000 UTC"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"description": "Enables create, delete, and update mutations for resources owned by IAM identity",
|
||||
"stage": "experimental",
|
||||
"codeowner": "@grafana/identity-access-team",
|
||||
"hideFromAdminPage": true,
|
||||
"hideFromDocs": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "kubernetesAuthzApis",
|
||||
|
||||
@@ -198,6 +198,7 @@ func TestIntegrationUsers(t *testing.T) {
|
||||
},
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs,
|
||||
featuremgmt.FlagKubernetesAuthnMutation,
|
||||
},
|
||||
})
|
||||
doUserCRUDTestsUsingTheNewAPIs(t, helper)
|
||||
|
||||
Reference in New Issue
Block a user