Repository: clouditor/clouditor
Pull request #1013 (2023-03-15 13:46:33)

Upgraded to newest github.com/oxisto/oauth2go
There were some changes with respect to the location of the JWKS that needs to be adapted.


Patch:
diff --git a/cmd/engine/engine.go b/cmd/engine/engine.go
index 99918c36..fe9ec724 100644
--- a/cmd/engine/engine.go
+++ b/cmd/engine/engine.go
@@ -40,6 +40,7 @@ import (
 	"clouditor.io/clouditor/api/orchestrator"
 	commands_login "clouditor.io/clouditor/cli/commands/login"
 	"clouditor.io/clouditor/internal/auth"
+	"clouditor.io/clouditor/internal/util"
 	"clouditor.io/clouditor/logging/formatter"
 	"clouditor.io/clouditor/persistence"
 	"clouditor.io/clouditor/persistence/gorm"
@@ -91,6 +92,7 @@ const (
 	CreateDefaultTarget              = "target-default-create"
 	DiscoveryAutoStartFlag           = "discovery-auto-start"
 	DiscoveryProviderFlag            = "discovery-provider"
+	DiscoveryResourceGroupFlag       = "discovery-resource-group"
 	DashboardURLFlag                 = "dashboard-url"
 
 	DefaultAPIDefaultUser                      = "clouditor"
@@ -109,6 +111,7 @@ const (
 	DefaultDBInMemory                          = false
 	DefaultCreateDefaultTarget                 = true
 	DefaultDiscoveryAutoStart                  = false
+	DefaultDiscoveryResourceGroup              = ""
 	DefaultDashboardURL                        = "http://localhost:8080"
 
 	EnvPrefix = "CLOUDITOR"
@@ -163,6 +166,7 @@ func init() {
 	engineCmd.Flags().Bool(CreateDefaultTarget, DefaultCreateDefaultTarget, "Creates a default target cloud service if it does not exist")
 	engineCmd.Flags().Bool(DiscoveryAutoStartFlag, DefaultDiscoveryAutoStart, "Automatically start the discovery when engine starts")
 	engineCmd.Flags().StringSliceP(DiscoveryProviderFlag, "p", []string{}, "Providers to discover, separated by comma")
+	engineCmd.Flags().String(DiscoveryResourceGroupFlag, DefaultDiscoveryResourceGroup, "Limit the scope of the discovery to a resource group (currently only used in the Azure discoverer")
 	engineCmd.Flags().String(DashboardURLFlag, DefaultDashboardURL, "The URL of the Clouditor Dashboard. If the embedded server is used, a public OAuth 2.0 client based on this URL will be added")
 
 	_ = viper.BindPFlag(APIDefaultUserFlag, engineCmd.Flags().Lookup(APIDefaultUserFlag))
@@ -190,6 +194,7 @@ func init() {
 	_ = viper.BindPFlag(CreateDefaultTarget, engineCmd.Flags().Lookup(CreateDefaultTarget))
 	_ = viper.BindPFlag(DiscoveryAutoStartFlag, engineCmd.Flags().Lookup(DiscoveryAutoStartFlag))
 	_ = viper.BindPFlag(DiscoveryProviderFlag, engineCmd.Flags().Lookup(DiscoveryProviderFlag))
+	_ = viper.BindPFlag(DiscoveryResourceGroupFlag, engineCmd.Flags().Lookup(DiscoveryResourceGroupFlag))
 	_ = viper.BindPFlag(DashboardURLFlag, engineCmd.Flags().Lookup(DashboardURLFlag))
 }
 
@@ -354,7 +359,7 @@ func doCmd(_ *cobra.Command, _ []string) (err error) {
 					"",
 					fmt.Sprintf("%s/callback", viper.GetString(DashboardURLFlag)),
 				),
-				// Createa a confidential client with default credentials for our services
+				// Create a confidential client with default credentials for our services
 				oauth2.WithClient(
 					viper.GetString(ServiceOAuth2ClientIDFlag),
 					viper.GetString(ServiceOAuth2ClientIDFlag),
@@ -397,7 +402,9 @@ func doCmd(_ *cobra.Command, _ []string) (err error) {
 	if viper.GetBool(DiscoveryAutoStartFlag) {
 		go func() {
 			<-rest.GetReadyChannel()
-			_, err = discoveryService.Start(context.Background(), &discovery.StartDiscoveryRequest{})
+			_, err = discoveryService.Start(context.Background(), &discovery.StartDiscoveryRequest{
+				ResourceGroup: util.Ref(viper.GetString(DiscoveryResourceGroupFlag)),
+			})
 			if err != nil {
 				log.Errorf("Could not automatically start discovery: %v", err)
 			}
diff --git a/go.mod b/go.mod
index 24071bd8..05b48c8e 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0
 	github.com/logrusorgru/aurora/v3 v3.0.0
 	github.com/open-policy-agent/opa v0.50.0
-	github.com/oxisto/oauth2go v0.6.0
+	github.com/oxisto/oauth2go v0.7.1
 	github.com/sirupsen/logrus v1.9.0
 	github.com/spf13/cobra v1.6.1
 	github.com/spf13/viper v1.15.0
@@ -41,9 +41,9 @@ require (
 
 // runtime dependencies (AWS)
 require (
-	github.com/aws/aws-sdk-go-v2 v1.17.5
+	github.com/aws/aws-sdk-go-v2 v1.17.6
 	github.com/aws/aws-sdk-go-v2/config v1.18.2
-	github.com/aws/aws-sdk-go-v2/service/ec2 v1.88.0
+	github.com/aws/aws-sdk-go-v2/service/ec2 v1.89.1
 	github.com/aws/aws-sdk-go-v2/service/lambda v1.30.0
 	github.com/aws/aws-sdk-go-v2/service/s3 v1.30.0
 	github.com/aws/aws-sdk-go-v2/service/sts v1.18.0
@@ -73,13 +73,13 @@ require (
 	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
 	github.com/aws/aws-sdk-go-v2/credentials v1.13.2 // indirect
 	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24 // indirect
 	github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 // indirect
 	github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22 // indirect
-	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 // indirect
 	github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 // indirect
 	github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect
diff --git a/go.sum b/go.sum
index 6e2bc2d5..b2f8f931 100644
--- a/go.sum
+++ b/go.sum
@@ -75,8 +75,9 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig
 github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
 github.com/aws/aws-sdk-go-v2 v1.17.1/go.mod h1:JLnGeGONAyi2lWXI1p0PCIOIy333JMVK1U7Hf0aRFLw=
 github.com/aws/aws-sdk-go-v2 v1.17.3/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
-github.com/aws/aws-sdk-go-v2 v1.17.5 h1:TzCUW1Nq4H8Xscph5M/skINUitxM5UBAyvm2s7XBzL4=
 github.com/aws/aws-sdk-go-v2 v1.17.5/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
+github.com/aws/aws-sdk-go-v2 v1.17.6 h1:Y773UK7OBqhzi5VDXMi1zVGsoj+CVHs2eaC2bDsLwi0=
+github.com/aws/aws-sdk-go-v2 v1.17.6/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs=
 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno=
 github.com/aws/aws-sdk-go-v2/config v1.18.2 h1:tRhTb3xMZsB0gW0sXWpqs9FeIP8iQp5SvnvwiPXzHwo=
@@ -87,26 +88,28 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 h1:E3PXZSI3F2bzyj6XxUXdTI
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19/go.mod h1:VihW95zQpeKQWVPGkwT+2+WJNQV8UXFfMTWdU6VErL8=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25/go.mod h1:Zb29PYkf42vVYQY6pvSyJCJcFHlPIiY+YKdPtwnvMkY=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27/go.mod h1:a1/UpzeyBBerajpnP5nGZa9mGzsBn5cOKxm6NWQsvoI=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 h1:9/aKwwus0TQxppPXFmf010DFrE+ssSbzroLVYINA+xE=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29/go.mod h1:Dip3sIGv485+xerzVv24emnjX5Sg88utCL8fwGmCeWg=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30 h1:y+8n9AGDjikyXoMBTRaHHHSaFEB8267ykmvyPodJfys=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30/go.mod h1:LUBAO3zNXQjoONBKn/kR1y0Q4cj/D02Ts0uHYjcCQLM=
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19/go.mod h1:6Q0546uHDp421okhmmGfbxzq2hBqbXFNpi4k+Q1JnQA=
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21/go.mod h1:+Gxn8jYn5k9ebfHEqlhrMirFjSW0v0C9fI+KN5vk2kE=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 h1:b/Vn141DBuLVgXbhRWIrl9g+ww7G+ScV5SzniWR13jQ=
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23/go.mod h1:mr6c4cHC+S/MMkrjtSlG4QA36kOznDep+0fga5L/fGQ=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24 h1:r+Kv+SEJquhAZXaJ7G4u44cIwXV3f8K+N482NNAzJZA=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24/go.mod h1:gAuCezX/gob6BSMbItsSlMb6WZGV7K2+fWOvk8xBSto=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 h1:Mza+vlnZr+fPKFKRq/lKGVvM6B/8ZZmNdEopOwSQLms=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26/go.mod h1:Y2OJ+P+MC1u1VKnavT+PshiEuGPyh/7DqxoDNij4/bg=
 github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18 h1:H/mF2LNWwX00lD6FlYfKpLLZgUW7oIzCBkig78x4Xok=
 github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18/go.mod h1:T2Ku+STrYQ1zIkL1wMvj8P3wWQaaCMKNdz70MT2FLfE=
-github.com/aws/aws-sdk-go-v2/service/ec2 v1.88.0 h1:YVxTUKCZqTzp2bT/ctafMOf/36TYKlk+Zio9kuHYxXU=
-github.com/aws/aws-sdk-go-v2/service/ec2 v1.88.0/go.mod h1:2HxUY7Pkfmt1uIhPrFp0/O6+0aGoLaGIN5tXp/rYDL8=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.89.1 h1:2CO0T8ReHjH5TFjk9RHmAafJt4vk/wMlQtn3c9bNL5Y=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.89.1/go.mod h1:zDr1uSSLVYc6KqXvrmqYkeqnfbmOOrbVloz4Eqsc83k=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8=
 github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22 h1:kv5vRAl00tozRxSnI0IszPWGXsJOyA7hmEUHFYqsyvw=
 github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22/go.mod h1:Od+GU5+Yx41gryN/ZGZzAJMZ9R1yn6lgA0fD5Lo5SkQ=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19/go.mod h1:02CP6iuYP+IVnBX5HULVdSAku/85eHB2Y9EsFhrkEwU=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21/go.mod h1:lRToEJsn+DRA9lW4O9L9+/3hjTkUzlzyzHqn8MTds5k=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23 h1:QoOybhwRfciWUBbZ0gp9S7XaDnCuSTeK/fySB99V1ls=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23/go.mod h1:9uPh+Hrz2Vn6oMnQYiUi/zbh3ovbnQk19YKINkQny44=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24 h1:c5qGfdbCHav6viBwiyDns3OXqhqAbGjfIB4uVu2ayhk=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24/go.mod h1:HMA4FZG6fyib+NDo5bpIxX1EhYjrAOveZJY2YR0xrNE=
 github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 h1:vY5siRXvW5TrOKm2qKEf9tliBfdLxdfy0i02LOcmqUo=
 github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21/go.mod h1:WZvNXT1XuH8dnJM0HvOlvk+RNn7NbAPvA/ACO0QarSc=
 github.com/aws/aws-sdk-go-v2/service/lambda v1.30.0 h1:i2AFUTfisQPZP0iZlUEJiGfOBxEN7Yy+d3zBfDYRmnQ=
@@ -368,8 +371,8 @@ github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys=
 github.com/open-policy-agent/opa v0.50.0 h1:CBRj7lJ9DFDHvlx2SRP6uFOCD9ooxDdNW9fYK2IIW+0=
 github.com/open-policy-agent/opa v0.50.0/go.mod h1:9jKfDk0L5b9rnhH4M0nq10cGHbYOxqygxzTT3dsvhec=
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
-github.com/oxisto/oauth2go v0.6.0 h1:0Ej2sUUdqPh/z6KxZ7pyTu5HVATJQkPI3CH/74CaB/w=
-github.com/oxisto/oauth2go v0.6.0/go.mod h1:KPsEcfPj68VAYqpDgNmkPUUxULTbPdEXeGdtkyq/XF4=
+github.com/oxisto/oauth2go v0.7.1 h1:C+DsrZeAahLbQY1OFtWNpj8G/5pa8qVjaee5ktH4vLM=
+github.com/oxisto/oauth2go v0.7.1/go.mod h1:P1P110o1ygqNQfQ2CdLbMsbI4HwZ1KFe+kCoAUdKs8c=
 github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
 github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
 github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI=
@@ -549,7 +552,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
 golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -561,7 +563,6 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
 golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
 golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/rest/rest.go b/rest/rest.go
index 58ae5444..94c99d09 100644
--- a/rest/rest.go
+++ b/rest/rest.go
@@ -56,6 +56,9 @@ var (
 	// srv holds the global http.Server of our REST API.
 	srv *http.Server
 
+	// httpPort holds the used HTTP port of the http.Server
+	httpPort uint16
+
 	// sock holds the listener socket of our REST API.
 	sock net.Listener
 
@@ -149,16 +152,17 @@ func WithEmbeddedOAuth2Server(keyPath string, keyPassword string, saveOnCreate b
 	return func(cc *corsConfig, sm *runtime.ServeMux) {
 		opts = append(opts, oauth2.WithSigningKeysFunc(func() map[int]*ecdsa.PrivateKey {
 			return auth.LoadSigningKeys(keyPath, keyPassword, saveOnCreate)
-		}))
+		}), oauth2.WithPublicURL(fmt.Sprintf("http://localhost:%d/v1/auth", httpPort)))
 
 		authSrv := oauth2.NewServer("", opts...)
 		authHandler := func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
 			http.StripPrefix("/v1/auth", authSrv.Handler).ServeHTTP(w, r)
 		}
 
-		WithAdditionalHandler("GET", "/.well-known/jwks.json", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
-			authSrv.Handler.(*http.ServeMux).ServeHTTP(w, r)
+		WithAdditionalHandler("GET", "/.well-known/openid-configuration", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
+			authSrv.Handler.ServeHTTP(w, r)
 		})(cc, sm)
+		WithAdditionalHandler("GET", "/v1/auth/certs", authHandler)(cc, sm)
 		WithAdditionalHandler("GET", "/v1/auth/login", authHandler)(cc, sm)
 		WithAdditionalHandler("GET", "/v1/auth/authorize", authHandler)(cc, sm)
 		WithAdditionalHandler("POST", "/v1/auth/login", authHandler)(cc, sm)
@@ -168,10 +172,12 @@ func WithEmbeddedOAuth2Server(keyPath string, keyPassword string, saveOnCreate b
 
 // RunServer starts our REST API. The REST API is a reverse proxy using grpc-gateway that
 // exposes certain gRPC calls as RESTful HTTP methods.
-func RunServer(ctx context.Context, grpcPort uint16, httpPort uint16, serverOpts ...ServerConfigOption) (err error) {
+func RunServer(ctx context.Context, grpcPort uint16, port uint16, serverOpts ...ServerConfigOption) (err error) {
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
 
+	httpPort = port
+
 	mux := runtime.NewServeMux()
 
 	for _, o := range serverOpts {
diff --git a/service/auth_middleware.go b/service/auth_middleware.go
index 000cfb41..5a703626 100644
--- a/service/auth_middleware.go
+++ b/service/auth_middleware.go
@@ -76,7 +76,7 @@ type AuthConfig struct {
 }
 
 // DefaultJWKSURL is the default JWKS url pointing to a local authentication server.
-const DefaultJWKSURL = "http://localhost:8080/.well-known/jwks.json"
+const DefaultJWKSURL = "http://localhost:8080/v1/auth/certs"
 
 // AuthOption is a function-style option type to fine-tune authentication
 type AuthOption func(*AuthConfig)


Test patch:
diff --git a/internal/testutil/auth.go b/internal/testutil/auth.go
index 2467abad..c03e755a 100644
--- a/internal/testutil/auth.go
+++ b/internal/testutil/auth.go
@@ -93,9 +93,18 @@ func init() {
 func StartAuthenticationServer() (srv *oauth2.AuthorizationServer, port uint16, err error) {
 	var nl net.Listener
 
-	srv = oauth2.NewServer(":0",
+	// create a new socket for HTTP communication
+	nl, err = net.Listen("tcp", "localhost:0")
+	if err != nil {
+		return nil, 0, fmt.Errorf("could not listen: %w", err)
+	}
+
+	port = nl.Addr().(*net.TCPAddr).AddrPort().Port()
+
+	srv = oauth2.NewServer(fmt.Sprintf(":%d", port),
 		oauth2.WithClient("cli", "", "http://localhost:10000/callback"),
 		oauth2.WithClient(TestAuthClientID, TestAuthClientSecret, ""),
+		oauth2.WithPublicURL(fmt.Sprintf("http://localhost:%d", port)),
 		login.WithLoginPage(
 			login.WithUser(TestAuthUser, TestAuthPassword),
 			login.WithBaseURL("/v1/auth"),
@@ -104,24 +113,17 @@ func StartAuthenticationServer() (srv *oauth2.AuthorizationServer, port uint16,
 
 	// simulate the /v1/auth endpoints
 	srv.Handler.(*http.ServeMux).Handle("/v1/auth/token", http.StripPrefix("/v1/auth", srv.Handler))
-
-	// create a new socket for HTTP communication
-	nl, err = net.Listen("tcp", srv.Addr)
-	if err != nil {
-		return nil, 0, fmt.Errorf("could not listen: %w", err)
-	}
+	srv.Handler.(*http.ServeMux).Handle("/v1/auth/certs", http.StripPrefix("/v1/auth", srv.Handler))
 
 	go func() {
 		_ = srv.Serve(nl)
 	}()
 
-	port = nl.Addr().(*net.TCPAddr).AddrPort().Port()
-
 	return srv, port, nil
 }
 
 func JWKSURL(port uint16) string {
-	return fmt.Sprintf("http://localhost:%d/.well-known/jwks.json", port)
+	return fmt.Sprintf("http://localhost:%d/v1/auth/certs", port)
 }
 
 func TokenURL(port uint16) string {