chore(oidc): graduate webkey to stable (#10122)

# Which Problems Are Solved

Stabilize the usage of webkeys.

# How the Problems Are Solved

- Remove all legacy signing key code from the OIDC API
- Remove the webkey feature flag from proto
- Remove the webkey feature flag from console
- Cleanup documentation

# Additional Changes

- Resolved some canonical header linter errors in OIDC
- Use the constant for `projections.lock` in the saml package.

# Additional Context

- Closes #10029
- After #10105
- After #10061
This commit is contained in:
Tim Möhlmann
2025-06-26 19:17:45 +03:00
committed by GitHub
parent 1ebbe275b9
commit 016676e1dc
59 changed files with 203 additions and 1614 deletions

View File

@@ -3,11 +3,8 @@ package command
import (
"context"
"github.com/muhlemmer/gu"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/command/preparation"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/feature"
@@ -21,7 +18,6 @@ type InstanceFeatures struct {
UserSchema *bool
TokenExchange *bool
ImprovedPerformance []feature.ImprovedPerformanceType
WebKey *bool
DebugOIDCParentError *bool
OIDCSingleV1SessionTermination *bool
DisableUserTokenEvent *bool
@@ -38,7 +34,6 @@ func (m *InstanceFeatures) isEmpty() bool {
m.TokenExchange == nil &&
// nil check to allow unset improvements
m.ImprovedPerformance == nil &&
m.WebKey == nil &&
m.DebugOIDCParentError == nil &&
m.OIDCSingleV1SessionTermination == nil &&
m.DisableUserTokenEvent == nil &&
@@ -55,9 +50,6 @@ func (c *Commands) SetInstanceFeatures(ctx context.Context, f *InstanceFeatures)
if err := c.eventstore.FilterToQueryReducer(ctx, wm); err != nil {
return nil, err
}
if err := c.setupWebKeyFeature(ctx, wm, f); err != nil {
return nil, err
}
commands := wm.setCommands(ctx, f)
if len(commands) == 0 {
return writeModelToObjectDetails(wm.WriteModel), nil
@@ -78,21 +70,6 @@ func prepareSetFeatures(instanceID string, f *InstanceFeatures) preparation.Vali
}
}
// setupWebKeyFeature generates the initial web keys for the instance,
// if the feature is enabled in the request and the feature wasn't enabled already in the writeModel.
// [Commands.GenerateInitialWebKeys] checks if keys already exist and does nothing if that's the case.
// The default config of a RSA key with 2048 and the SHA256 hasher is assumed.
// Users can customize this after using the webkey/v3 API.
func (c *Commands) setupWebKeyFeature(ctx context.Context, wm *InstanceFeaturesWriteModel, f *InstanceFeatures) error {
if !gu.Value(f.WebKey) || gu.Value(wm.WebKey) {
return nil
}
return c.GenerateInitialWebKeys(ctx, &crypto.WebKeyRSAConfig{
Bits: crypto.RSABits2048,
Hasher: crypto.RSAHasherSHA256,
})
}
func (c *Commands) ResetInstanceFeatures(ctx context.Context) (*domain.ObjectDetails, error) {
instanceID := authz.GetInstance(ctx).InstanceID()
wm := NewInstanceFeaturesWriteModel(instanceID)

View File

@@ -71,7 +71,6 @@ func (m *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
feature_v2.InstanceUserSchemaEventType,
feature_v2.InstanceTokenExchangeEventType,
feature_v2.InstanceImprovedPerformanceEventType,
feature_v2.InstanceWebKeyEventType,
feature_v2.InstanceDebugOIDCParentErrorEventType,
feature_v2.InstanceOIDCSingleV1SessionTerminationEventType,
feature_v2.InstanceDisableUserTokenEvent,
@@ -106,9 +105,6 @@ func reduceInstanceFeature(features *InstanceFeatures, key feature.Key, value an
case feature.KeyImprovedPerformance:
v := value.([]feature.ImprovedPerformanceType)
features.ImprovedPerformance = v
case feature.KeyWebKey:
v := value.(bool)
features.WebKey = &v
case feature.KeyDebugOIDCParentError:
v := value.(bool)
features.DebugOIDCParentError = &v
@@ -140,7 +136,6 @@ func (wm *InstanceFeaturesWriteModel) setCommands(ctx context.Context, f *Instan
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.TokenExchange, f.TokenExchange, feature_v2.InstanceTokenExchangeEventType)
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.UserSchema, f.UserSchema, feature_v2.InstanceUserSchemaEventType)
cmds = appendFeatureSliceUpdate(ctx, cmds, aggregate, wm.ImprovedPerformance, f.ImprovedPerformance, feature_v2.InstanceImprovedPerformanceEventType)
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.WebKey, f.WebKey, feature_v2.InstanceWebKeyEventType)
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DebugOIDCParentError, f.DebugOIDCParentError, feature_v2.InstanceDebugOIDCParentErrorEventType)
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.OIDCSingleV1SessionTermination, f.OIDCSingleV1SessionTermination, feature_v2.InstanceOIDCSingleV1SessionTerminationEventType)
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DisableUserTokenEvent, f.DisableUserTokenEvent, feature_v2.InstanceDisableUserTokenEvent)

View File

@@ -13,31 +13,6 @@ import (
"github.com/zitadel/zitadel/internal/repository/keypair"
)
func (c *Commands) GenerateSigningKeyPair(ctx context.Context, algorithm string) error {
privateCrypto, publicCrypto, err := crypto.GenerateEncryptedKeyPair(c.keySize, c.keyAlgorithm)
if err != nil {
return err
}
keyID, err := c.idGenerator.Next()
if err != nil {
return err
}
privateKeyExp := time.Now().UTC().Add(c.privateKeyLifetime)
publicKeyExp := time.Now().UTC().Add(c.publicKeyLifetime)
keyPairWriteModel := NewKeyPairWriteModel(keyID, authz.GetInstance(ctx).InstanceID())
keyAgg := KeyPairAggregateFromWriteModel(&keyPairWriteModel.WriteModel)
_, err = c.eventstore.Push(ctx, keypair.NewAddedEvent(
ctx,
keyAgg,
crypto.KeyUsageSigning,
algorithm,
privateCrypto, publicCrypto,
privateKeyExp, publicKeyExp))
return err
}
func (c *Commands) GenerateSAMLCACertificate(ctx context.Context, algorithm string) error {
now := time.Now().UTC()
after := now.Add(c.certificateLifetime)