From dde9861a48b2443afb11cbb96fbf52708c1f489a Mon Sep 17 00:00:00 2001 From: jdiaconu Date: Thu, 15 Jan 2026 12:01:23 +0100 Subject: [PATCH 1/3] feat: Add Ping provider name Signed-off-by: jdiaconu --- pkg/oidc/parser.go | 9 ++++++--- pkg/oidc/provider.go | 9 +++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pkg/oidc/parser.go b/pkg/oidc/parser.go index 07e5cc6a..e6ec02c7 100644 --- a/pkg/oidc/parser.go +++ b/pkg/oidc/parser.go @@ -38,6 +38,7 @@ const ( DuoProviderName OryProviderName IdpProviderName + PingProviderName SelfProviderName ) @@ -55,9 +56,11 @@ type providerMetadata struct { JWKSURL string `json:"jwks_uri"` } -const defaultCacheSize = 10 * 1024 * 1024 // 10MB -const defaultCacheExpiration = 24 // 24 hours -const defaultAcceptableSkew = 5 * time.Second // 5 seconds +const ( + defaultCacheSize = 10 * 1024 * 1024 // 10MB + defaultCacheExpiration = 24 // 24 hours + defaultAcceptableSkew = 5 * time.Second // 5 seconds +) type CachedJwks struct { Jwks string diff --git a/pkg/oidc/provider.go b/pkg/oidc/provider.go index fe6a93ce..6b7841c5 100644 --- a/pkg/oidc/provider.go +++ b/pkg/oidc/provider.go @@ -33,6 +33,8 @@ func (p *parser) detectProviderName( return OktaProviderName, nil case isDuo(headers, providerUrl.Host): return DuoProviderName, nil + case isPing(headers, providerUrl.Host): + return PingProviderName, nil default: return IdpProviderName, nil } @@ -53,6 +55,13 @@ func isDuo(headers http.Header, host string) bool { strings.HasPrefix(host, "duosecurity.com")) } +func isPing(_ http.Header, host string) bool { + return strings.HasSuffix(host, "pingone.com") || + strings.HasSuffix(host, "pingone.eu") || + strings.HasSuffix(host, "pingone.com.au") || + strings.HasSuffix(host, "pingone.ca") +} + func getProviderMetadata(ctx context.Context, issuer string) (*providerMetadata, error) { metadata, oidcErr := getOidcProviderMetadata(ctx, issuer) if oidcErr == nil { From 573e4bb2154ff6edc083cd7860138486b74fa098 Mon Sep 17 00:00:00 2001 From: jdiaconu Date: Thu, 15 Jan 2026 16:38:59 +0100 Subject: [PATCH 2/3] feat: Add diversified sub claim Signed-off-by: jdiaconu --- internal/node/id_generator.go | 3 +++ pkg/oidc/parser.go | 25 ++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/internal/node/id_generator.go b/internal/node/id_generator.go index 76b070c4..bbd50c4f 100644 --- a/internal/node/id_generator.go +++ b/internal/node/id_generator.go @@ -23,6 +23,7 @@ const ( DuoScheme = "DUO-" OryScheme = "ORY-" IdpScheme = "IDP-" + PingScheme = "PING-" SelfScheme = "AGNTCY-" ) @@ -65,6 +66,8 @@ func (g *idGenerator) GenerateFromProof( scheme = OryScheme case oidc.IdpProviderName: scheme = IdpScheme + case oidc.PingProviderName: + scheme = PingScheme case oidc.SelfProviderName: scheme = SelfScheme default: diff --git a/pkg/oidc/parser.go b/pkg/oidc/parser.go index e6ec02c7..66467663 100644 --- a/pkg/oidc/parser.go +++ b/pkg/oidc/parser.go @@ -208,9 +208,28 @@ func (p *parser) GetClaims( return nil, errors.New("failed to decode JWT: missing 'iss' claim") } - subject, ok := jwtToken.Subject() - if !ok { - return nil, errors.New("failed to decode JWT: missing 'sub' claim") + var subOk bool + + var cidError, clientIDError error + + var sub, cid, clientID string + + // Get the subject from 'sub', 'cid' or 'client_id' claim + sub, subOk = jwtToken.Subject() + cidError = jwtToken.Get("cid", &cid) + clientIDError = jwtToken.Get("client_id", &clientID) + + if !subOk && cidError != nil && clientIDError != nil { + return nil, errors.New("failed to decode JWT: missing 'sub', 'cid' or 'client_id' claim") + } + + subject := sub + if subject == "" { + if cidError == nil && cid != "" { + subject = cid + } else if clientIDError == nil && clientID != "" { + subject = clientID + } } var subJWK map[string]any From c1f4cab140dad68f49a10b6fe63fbcf82a59d2bd Mon Sep 17 00:00:00 2001 From: jdiaconu Date: Mon, 19 Jan 2026 17:35:03 +0100 Subject: [PATCH 3/3] feat: Add automatic key alg detection Signed-off-by: jdiaconu --- pkg/oidc/parser.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/oidc/parser.go b/pkg/oidc/parser.go index 66467663..107f2283 100644 --- a/pkg/oidc/parser.go +++ b/pkg/oidc/parser.go @@ -125,7 +125,9 @@ func (p *parser) VerifyJwt(ctx context.Context, parsedJwt *ParsedJWT) error { } // Verify the JWT signature - _, err = jws.Verify([]byte(*parsedJwt.jwt), jws.WithKeySet(jwks)) + // The algorithm is inferred from the key automatically + // In some providers there is no "alg" specified in the JWKS + _, err = jws.Verify([]byte(*parsedJwt.jwt), jws.WithKeySet(jwks, jws.WithInferAlgorithmFromKey(true))) if err != nil { return err }