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

@@ -14,12 +14,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/zitadel/oidc/v3/pkg/client"
"github.com/zitadel/oidc/v3/pkg/oidc"
"google.golang.org/protobuf/proto"
http_util "github.com/zitadel/zitadel/internal/api/http"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2"
)
@@ -53,25 +51,16 @@ func TestServer_Keys(t *testing.T) {
require.NoError(t, err)
tests := []struct {
name string
webKeyFeature bool
wantLen int
name string
wantLen int
}{
{
name: "legacy only",
webKeyFeature: false,
wantLen: 1,
},
{
name: "webkeys with legacy",
webKeyFeature: true,
wantLen: 3, // 1 legacy + 2 created by enabling feature flag
name: "webkeys",
wantLen: 2, // 2 from instance creation.
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ensureWebKeyFeature(t, instance, tt.webKeyFeature)
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
resp, err := http.Get(discovery.JwksURI)
require.NoError(ttt, err)
@@ -92,30 +81,10 @@ func TestServer_Keys(t *testing.T) {
}
cacheControl := resp.Header.Get("cache-control")
if tt.webKeyFeature {
require.Equal(ttt, "max-age=300, must-revalidate", cacheControl)
return
}
require.Equal(ttt, "no-store", cacheControl)
require.Equal(ttt, "max-age=300, must-revalidate", cacheControl)
}, time.Minute, time.Second/10)
})
}
}
func ensureWebKeyFeature(t *testing.T, instance *integration.Instance, set bool) {
ctxIam := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
_, err := instance.Client.FeatureV2.SetInstanceFeatures(ctxIam, &feature.SetInstanceFeaturesRequest{
WebKey: proto.Bool(set),
})
require.NoError(t, err)
t.Cleanup(func() {
_, err := instance.Client.FeatureV2.SetInstanceFeatures(ctxIam, &feature.SetInstanceFeaturesRequest{
WebKey: proto.Bool(false),
})
require.NoError(t, err)
})
}

View File

@@ -35,21 +35,14 @@ func TestServer_UserInfo(t *testing.T) {
tests := []struct {
name string
trigger bool
webKey bool
}{
{
name: "trigger enabled",
trigger: true,
},
// This is the only functional test we need to cover web keys.
// - By creating tokens the signer is tested
// - When obtaining the tokens, the RP verifies the ID Token using the key set from the jwks endpoint.
// - By calling userinfo with the access token as JWT, the Token Verifier with the public key cache is tested.
{
name: "web keys",
name: "trigger disabled",
trigger: false,
webKey: true,
},
}
@@ -57,7 +50,6 @@ func TestServer_UserInfo(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
_, err := Instance.Client.FeatureV2.SetInstanceFeatures(iamOwnerCTX, &feature.SetInstanceFeaturesRequest{
OidcTriggerIntrospectionProjections: &tt.trigger,
WebKey: &tt.webKey,
})
require.NoError(t, err)
testServer_UserInfo(t)