Skip to content

Commit 5bd9002

Browse files
authored
feat: parallel generation of JSON web key set (#3561)
1 parent 2bdad2c commit 5bd9002

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ require (
6969
golang.org/x/crypto v0.10.0
7070
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
7171
golang.org/x/oauth2 v0.9.0
72+
golang.org/x/sync v0.3.0
7273
golang.org/x/tools v0.10.0
7374
)
7475

@@ -232,7 +233,6 @@ require (
232233
go.opentelemetry.io/proto/otlp v0.18.0 // indirect
233234
golang.org/x/mod v0.11.0 // indirect
234235
golang.org/x/net v0.11.0 // indirect
235-
golang.org/x/sync v0.3.0 // indirect
236236
golang.org/x/sys v0.9.0 // indirect
237237
golang.org/x/text v0.10.0 // indirect
238238
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect

jwk/handler.go

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"encoding/json"
88
"net/http"
99

10+
"golang.org/x/sync/errgroup"
11+
1012
"github.com/ory/x/httprouterx"
1113

1214
"github.com/gofrs/uuid"
@@ -89,25 +91,34 @@ func (h *Handler) SetRoutes(admin *httprouterx.RouterAdmin, public *httprouterx.
8991
// 200: jsonWebKeySet
9092
// default: errorOAuth2
9193
func (h *Handler) discoverJsonWebKeys(w http.ResponseWriter, r *http.Request) {
92-
var jwks jose.JSONWebKeySet
93-
94-
ctx := r.Context()
95-
for _, set := range stringslice.Unique(h.r.Config().WellKnownKeys(ctx)) {
96-
keys, err := h.r.KeyManager().GetKeySet(ctx, set)
97-
if errors.Is(err, x.ErrNotFound) {
98-
h.r.Logger().Warnf("JSON Web Key Set \"%s\" does not exist yet, generating new key pair...", set)
99-
keys, err = h.r.KeyManager().GenerateAndPersistKeySet(ctx, set, uuid.Must(uuid.NewV4()).String(), string(jose.RS256), "sig")
100-
if err != nil {
101-
h.r.Writer().WriteError(w, r, err)
102-
return
94+
eg, ctx := errgroup.WithContext(r.Context())
95+
wellKnownKeys := stringslice.Unique(h.r.Config().WellKnownKeys(ctx))
96+
keys := make(chan *jose.JSONWebKeySet, len(wellKnownKeys))
97+
for _, set := range wellKnownKeys {
98+
set := set
99+
eg.Go(func() error {
100+
k, err := h.r.KeyManager().GetKeySet(ctx, set)
101+
if errors.Is(err, x.ErrNotFound) {
102+
h.r.Logger().Warnf("JSON Web Key Set %q does not exist yet, generating new key pair...", set)
103+
k, err = h.r.KeyManager().GenerateAndPersistKeySet(ctx, set, uuid.Must(uuid.NewV4()).String(), string(jose.RS256), "sig")
104+
if err != nil {
105+
return err
106+
}
107+
} else if err != nil {
108+
return err
103109
}
104-
} else if err != nil {
105-
h.r.Writer().WriteError(w, r, err)
106-
return
107-
}
108-
109-
keys = ExcludePrivateKeys(keys)
110-
jwks.Keys = append(jwks.Keys, keys.Keys...)
110+
keys <- ExcludePrivateKeys(k)
111+
return nil
112+
})
113+
}
114+
if err := eg.Wait(); err != nil {
115+
h.r.Writer().WriteError(w, r, err)
116+
return
117+
}
118+
close(keys)
119+
var jwks jose.JSONWebKeySet
120+
for k := range keys {
121+
jwks.Keys = append(jwks.Keys, k.Keys...)
111122
}
112123

113124
h.r.Writer().Write(w, r, &jwks)

0 commit comments

Comments
 (0)