diff -pruN 5.2.2-1/.github/CODEOWNERS 5.3.0-1/.github/CODEOWNERS
--- 5.2.2-1/.github/CODEOWNERS	1970-01-01 00:00:00.000000000 +0000
+++ 5.3.0-1/.github/CODEOWNERS	2025-09-29 23:42:57.000000000 +0000
@@ -0,0 +1 @@
+*  @oxisto @mfridman
diff -pruN 5.2.2-1/.github/workflows/build.yml 5.3.0-1/.github/workflows/build.yml
--- 5.2.2-1/.github/workflows/build.yml	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/.github/workflows/build.yml	2025-09-29 23:42:57.000000000 +0000
@@ -13,7 +13,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        go: ["1.21", "1.22", "1.23"]
+        go: ["1.21", "1.22", "1.23", "1.24"]
     steps:
       - name: Checkout
         uses: actions/checkout@v4
diff -pruN 5.2.2-1/.github/workflows/lint.yml 5.3.0-1/.github/workflows/lint.yml
--- 5.2.2-1/.github/workflows/lint.yml	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/.github/workflows/lint.yml	2025-09-29 23:42:57.000000000 +0000
@@ -14,10 +14,10 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v5
         with:
-          go-version: "1.23"
+          go-version: "1.24"
           check-latest: true
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@v6
+        uses: golangci/golangci-lint-action@v8
         with:
           # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
           version: latest
diff -pruN 5.2.2-1/MIGRATION_GUIDE.md 5.3.0-1/MIGRATION_GUIDE.md
--- 5.2.2-1/MIGRATION_GUIDE.md	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/MIGRATION_GUIDE.md	2025-09-29 23:42:57.000000000 +0000
@@ -155,7 +155,7 @@ stored in base64 encoded form, which was
 type Token struct {
 	Raw       string                 // Raw contains the raw token
 	Method    SigningMethod          // Method is the signing method used or to be used
-	Header    map[string]interface{} // Header is the first segment of the token in decoded form
+	Header    map[string]any         // Header is the first segment of the token in decoded form
 	Claims    Claims                 // Claims is the second segment of the token in decoded form
 	Signature []byte                 // Signature is the third segment of the token in decoded form
 	Valid     bool                   // Valid specifies if the token is valid
diff -pruN 5.2.2-1/cmd/jwt/main.go 5.3.0-1/cmd/jwt/main.go
--- 5.2.2-1/cmd/jwt/main.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/cmd/jwt/main.go	2025-09-29 23:42:57.000000000 +0000
@@ -91,13 +91,15 @@ func loadData(p string) ([]byte, error)
 			return nil, err
 		}
 		rdr = f
-		defer f.Close()
+		if err := f.Close(); err != nil {
+			return nil, err
+		}
 	}
 	return io.ReadAll(rdr)
 }
 
 // Print a json object in accordance with the prophecy (or the command line options)
-func printJSON(j interface{}) error {
+func printJSON(j any) error {
 	var out []byte
 	var err error
 
@@ -130,7 +132,7 @@ func verifyToken() error {
 	}
 
 	// Parse the token.  Load the key from command line option
-	token, err := jwt.Parse(string(tokData), func(t *jwt.Token) (interface{}, error) {
+	token, err := jwt.Parse(string(tokData), func(t *jwt.Token) (any, error) {
 		if isNone() {
 			return jwt.UnsafeAllowNoneSignatureType, nil
 		}
@@ -194,7 +196,7 @@ func signToken() error {
 	}
 
 	// get the key
-	var key interface{}
+	var key any
 	if isNone() {
 		key = jwt.UnsafeAllowNoneSignatureType
 	} else {
diff -pruN 5.2.2-1/debian/changelog 5.3.0-1/debian/changelog
--- 5.2.2-1/debian/changelog	2025-03-22 19:36:53.000000000 +0000
+++ 5.3.0-1/debian/changelog	2025-09-29 23:44:17.000000000 +0000
@@ -1,3 +1,10 @@
+golang-github-golang-jwt-jwt-v5 (5.3.0-1) unstable; urgency=medium
+
+  * New upstream release
+  * Drop redundant Rules-Requires-Root from d/control
+
+ -- Mathias Gibbens <gibmat@debian.org>  Mon, 29 Sep 2025 23:44:17 +0000
+
 golang-github-golang-jwt-jwt-v5 (5.2.2-1) unstable; urgency=medium
 
   * New upstream release
diff -pruN 5.2.2-1/debian/control 5.3.0-1/debian/control
--- 5.2.2-1/debian/control	2025-03-22 19:04:08.000000000 +0000
+++ 5.3.0-1/debian/control	2025-09-29 23:43:57.000000000 +0000
@@ -14,7 +14,6 @@ Standards-Version: 4.7.2
 Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-github-golang-jwt-jwt-v5
 Vcs-Git: https://salsa.debian.org/go-team/packages/golang-github-golang-jwt-jwt-v5.git
 Homepage: https://github.com/golang-jwt/jwt
-Rules-Requires-Root: no
 XS-Go-Import-Path: github.com/golang-jwt/jwt/v5
 
 Package: golang-github-golang-jwt-jwt-v5-dev
diff -pruN 5.2.2-1/ecdsa.go 5.3.0-1/ecdsa.go
--- 5.2.2-1/ecdsa.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/ecdsa.go	2025-09-29 23:42:57.000000000 +0000
@@ -55,7 +55,7 @@ func (m *SigningMethodECDSA) Alg() strin
 
 // Verify implements token verification for the SigningMethod.
 // For this verify method, key must be an ecdsa.PublicKey struct
-func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key any) error {
 	// Get the key
 	var ecdsaKey *ecdsa.PublicKey
 	switch k := key.(type) {
@@ -89,7 +89,7 @@ func (m *SigningMethodECDSA) Verify(sign
 
 // Sign implements token signing for the SigningMethod.
 // For this signing method, key must be an ecdsa.PrivateKey struct
-func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodECDSA) Sign(signingString string, key any) ([]byte, error) {
 	// Get the key
 	var ecdsaKey *ecdsa.PrivateKey
 	switch k := key.(type) {
diff -pruN 5.2.2-1/ecdsa_test.go 5.3.0-1/ecdsa_test.go
--- 5.2.2-1/ecdsa_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/ecdsa_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -15,7 +15,7 @@ var ecdsaTestData = []struct {
 	keys        map[string]string
 	tokenString string
 	alg         string
-	claims      map[string]interface{}
+	claims      map[string]any
 	valid       bool
 }{
 	{
@@ -23,7 +23,7 @@ var ecdsaTestData = []struct {
 		map[string]string{"private": "test/ec256-private.pem", "public": "test/ec256-public.pem"},
 		"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJmb28iOiJiYXIifQ.feG39E-bn8HXAKhzDZq7yEAPWYDhZlwTn3sePJnU9VrGMmwdXAIEyoOnrjreYlVM_Z4N13eK9-TmMTWyfKJtHQ",
 		"ES256",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
@@ -31,7 +31,7 @@ var ecdsaTestData = []struct {
 		map[string]string{"private": "test/ec384-private.pem", "public": "test/ec384-public.pem"},
 		"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzM4NCJ9.eyJmb28iOiJiYXIifQ.ngAfKMbJUh0WWubSIYe5GMsA-aHNKwFbJk_wq3lq23aPp8H2anb1rRILIzVR0gUf4a8WzDtrzmiikuPWyCS6CN4-PwdgTk-5nehC7JXqlaBZU05p3toM3nWCwm_LXcld",
 		"ES384",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
@@ -39,7 +39,7 @@ var ecdsaTestData = []struct {
 		map[string]string{"private": "test/ec512-private.pem", "public": "test/ec512-public.pem"},
 		"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJmb28iOiJiYXIifQ.AAU0TvGQOcdg2OvrwY73NHKgfk26UDekh9Prz-L_iWuTBIBqOFCWwwLsRiHB1JOddfKAls5do1W0jR_F30JpVd-6AJeTjGKA4C1A1H6gIKwRY0o_tFDIydZCl_lMBMeG5VNFAjO86-WCSKwc3hqaGkq1MugPRq_qrF9AVbuEB4JPLyL5",
 		"ES512",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
@@ -47,7 +47,7 @@ var ecdsaTestData = []struct {
 		map[string]string{"private": "test/ec256-private.pem", "public": "test/ec256-public.pem"},
 		"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.MEQCIHoSJnmGlPaVQDqacx_2XlXEhhqtWceVopjomc2PJLtdAiAUTeGPoNYxZw0z8mgOnnIcjoxRuNDVZvybRZF3wR1l8W",
 		"ES256",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		false,
 	},
 }
diff -pruN 5.2.2-1/ecdsa_utils.go 5.3.0-1/ecdsa_utils.go
--- 5.2.2-1/ecdsa_utils.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/ecdsa_utils.go	2025-09-29 23:42:57.000000000 +0000
@@ -23,7 +23,7 @@ func ParseECPrivateKeyFromPEM(key []byte
 	}
 
 	// Parse the key
-	var parsedKey interface{}
+	var parsedKey any
 	if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
 		if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
 			return nil, err
@@ -50,7 +50,7 @@ func ParseECPublicKeyFromPEM(key []byte)
 	}
 
 	// Parse the key
-	var parsedKey interface{}
+	var parsedKey any
 	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
 		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
 			parsedKey = cert.PublicKey
diff -pruN 5.2.2-1/ed25519.go 5.3.0-1/ed25519.go
--- 5.2.2-1/ed25519.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/ed25519.go	2025-09-29 23:42:57.000000000 +0000
@@ -33,7 +33,7 @@ func (m *SigningMethodEd25519) Alg() str
 
 // Verify implements token verification for the SigningMethod.
 // For this verify method, key must be an ed25519.PublicKey
-func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key any) error {
 	var ed25519Key ed25519.PublicKey
 	var ok bool
 
@@ -55,7 +55,7 @@ func (m *SigningMethodEd25519) Verify(si
 
 // Sign implements token signing for the SigningMethod.
 // For this signing method, key must be an ed25519.PrivateKey
-func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodEd25519) Sign(signingString string, key any) ([]byte, error) {
 	var ed25519Key crypto.Signer
 	var ok bool
 
diff -pruN 5.2.2-1/ed25519_test.go 5.3.0-1/ed25519_test.go
--- 5.2.2-1/ed25519_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/ed25519_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -13,7 +13,7 @@ var ed25519TestData = []struct {
 	keys        map[string]string
 	tokenString string
 	alg         string
-	claims      map[string]interface{}
+	claims      map[string]any
 	valid       bool
 }{
 	{
@@ -21,7 +21,7 @@ var ed25519TestData = []struct {
 		map[string]string{"private": "test/ed25519-private.pem", "public": "test/ed25519-public.pem"},
 		"eyJhbGciOiJFRDI1NTE5IiwidHlwIjoiSldUIn0.eyJmb28iOiJiYXIifQ.ESuVzZq1cECrt9Od_gLPVG-_6uRP_8Nq-ajx6CtmlDqRJZqdejro2ilkqaQgSL-siE_3JMTUW7UwAorLaTyFCw",
 		"EdDSA",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
@@ -29,7 +29,7 @@ var ed25519TestData = []struct {
 		map[string]string{"private": "test/ed25519-private.pem", "public": "test/ed25519-public.pem"},
 		"eyJhbGciOiJFRDI1NTE5IiwidHlwIjoiSldUIn0.eyJmb28iOiJiYXoifQ.ESuVzZq1cECrt9Od_gLPVG-_6uRP_8Nq-ajx6CtmlDqRJZqdejro2ilkqaQgSL-siE_3JMTUW7UwAorLaTyFCw",
 		"EdDSA",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		false,
 	},
 }
diff -pruN 5.2.2-1/ed25519_utils.go 5.3.0-1/ed25519_utils.go
--- 5.2.2-1/ed25519_utils.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/ed25519_utils.go	2025-09-29 23:42:57.000000000 +0000
@@ -24,7 +24,7 @@ func ParseEdPrivateKeyFromPEM(key []byte
 	}
 
 	// Parse the key
-	var parsedKey interface{}
+	var parsedKey any
 	if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
 		return nil, err
 	}
@@ -49,7 +49,7 @@ func ParseEdPublicKeyFromPEM(key []byte)
 	}
 
 	// Parse the key
-	var parsedKey interface{}
+	var parsedKey any
 	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
 		return nil, err
 	}
diff -pruN 5.2.2-1/errors.go 5.3.0-1/errors.go
--- 5.2.2-1/errors.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/errors.go	2025-09-29 23:42:57.000000000 +0000
@@ -2,6 +2,7 @@ package jwt
 
 import (
 	"errors"
+	"fmt"
 	"strings"
 )
 
@@ -47,3 +48,42 @@ func joinErrors(errs ...error) error {
 		errs: errs,
 	}
 }
+
+// Unwrap implements the multiple error unwrapping for this error type, which is
+// possible in Go 1.20.
+func (je joinedError) Unwrap() []error {
+	return je.errs
+}
+
+// newError creates a new error message with a detailed error message. The
+// message will be prefixed with the contents of the supplied error type.
+// Additionally, more errors, that provide more context can be supplied which
+// will be appended to the message. This makes use of Go 1.20's possibility to
+// include more than one %w formatting directive in [fmt.Errorf].
+//
+// For example,
+//
+//	newError("no keyfunc was provided", ErrTokenUnverifiable)
+//
+// will produce the error string
+//
+//	"token is unverifiable: no keyfunc was provided"
+func newError(message string, err error, more ...error) error {
+	var format string
+	var args []any
+	if message != "" {
+		format = "%w: %s"
+		args = []any{err, message}
+	} else {
+		format = "%w"
+		args = []any{err}
+	}
+
+	for _, e := range more {
+		format += ": %w"
+		args = append(args, e)
+	}
+
+	err = fmt.Errorf(format, args...)
+	return err
+}
diff -pruN 5.2.2-1/errors_go1_20.go 5.3.0-1/errors_go1_20.go
--- 5.2.2-1/errors_go1_20.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/errors_go1_20.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-//go:build go1.20
-// +build go1.20
-
-package jwt
-
-import (
-	"fmt"
-)
-
-// Unwrap implements the multiple error unwrapping for this error type, which is
-// possible in Go 1.20.
-func (je joinedError) Unwrap() []error {
-	return je.errs
-}
-
-// newError creates a new error message with a detailed error message. The
-// message will be prefixed with the contents of the supplied error type.
-// Additionally, more errors, that provide more context can be supplied which
-// will be appended to the message. This makes use of Go 1.20's possibility to
-// include more than one %w formatting directive in [fmt.Errorf].
-//
-// For example,
-//
-//	newError("no keyfunc was provided", ErrTokenUnverifiable)
-//
-// will produce the error string
-//
-//	"token is unverifiable: no keyfunc was provided"
-func newError(message string, err error, more ...error) error {
-	var format string
-	var args []any
-	if message != "" {
-		format = "%w: %s"
-		args = []any{err, message}
-	} else {
-		format = "%w"
-		args = []any{err}
-	}
-
-	for _, e := range more {
-		format += ": %w"
-		args = append(args, e)
-	}
-
-	err = fmt.Errorf(format, args...)
-	return err
-}
diff -pruN 5.2.2-1/errors_go_other.go 5.3.0-1/errors_go_other.go
--- 5.2.2-1/errors_go_other.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/errors_go_other.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,78 +0,0 @@
-//go:build !go1.20
-// +build !go1.20
-
-package jwt
-
-import (
-	"errors"
-	"fmt"
-)
-
-// Is implements checking for multiple errors using [errors.Is], since multiple
-// error unwrapping is not possible in versions less than Go 1.20.
-func (je joinedError) Is(err error) bool {
-	for _, e := range je.errs {
-		if errors.Is(e, err) {
-			return true
-		}
-	}
-
-	return false
-}
-
-// wrappedErrors is a workaround for wrapping multiple errors in environments
-// where Go 1.20 is not available. It basically uses the already implemented
-// functionality of joinedError to handle multiple errors with supplies a
-// custom error message that is identical to the one we produce in Go 1.20 using
-// multiple %w directives.
-type wrappedErrors struct {
-	msg string
-	joinedError
-}
-
-// Error returns the stored error string
-func (we wrappedErrors) Error() string {
-	return we.msg
-}
-
-// newError creates a new error message with a detailed error message. The
-// message will be prefixed with the contents of the supplied error type.
-// Additionally, more errors, that provide more context can be supplied which
-// will be appended to the message. Since we cannot use of Go 1.20's possibility
-// to include more than one %w formatting directive in [fmt.Errorf], we have to
-// emulate that.
-//
-// For example,
-//
-//	newError("no keyfunc was provided", ErrTokenUnverifiable)
-//
-// will produce the error string
-//
-//	"token is unverifiable: no keyfunc was provided"
-func newError(message string, err error, more ...error) error {
-	// We cannot wrap multiple errors here with %w, so we have to be a little
-	// bit creative. Basically, we are using %s instead of %w to produce the
-	// same error message and then throw the result into a custom error struct.
-	var format string
-	var args []any
-	if message != "" {
-		format = "%s: %s"
-		args = []any{err, message}
-	} else {
-		format = "%s"
-		args = []any{err}
-	}
-	errs := []error{err}
-
-	for _, e := range more {
-		format += ": %s"
-		args = append(args, e)
-		errs = append(errs, e)
-	}
-
-	err = &wrappedErrors{
-		msg:         fmt.Sprintf(format, args...),
-		joinedError: joinedError{errs: errs},
-	}
-	return err
-}
diff -pruN 5.2.2-1/example_test.go 5.3.0-1/example_test.go
--- 5.2.2-1/example_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/example_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -84,13 +84,13 @@ func ExampleParseWithClaims_customClaims
 		jwt.RegisteredClaims
 	}
 
-	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
+	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (any, error) {
 		return []byte("AllYourBase"), nil
 	})
 	if err != nil {
 		log.Fatal(err)
 	} else if claims, ok := token.Claims.(*MyCustomClaims); ok {
-		fmt.Println(claims.Foo, claims.RegisteredClaims.Issuer)
+		fmt.Println(claims.Foo, claims.Issuer)
 	} else {
 		log.Fatal("unknown claims type, cannot proceed")
 	}
@@ -108,13 +108,13 @@ func ExampleParseWithClaims_validationOp
 		jwt.RegisteredClaims
 	}
 
-	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
+	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (any, error) {
 		return []byte("AllYourBase"), nil
 	}, jwt.WithLeeway(5*time.Second))
 	if err != nil {
 		log.Fatal(err)
 	} else if claims, ok := token.Claims.(*MyCustomClaims); ok {
-		fmt.Println(claims.Foo, claims.RegisteredClaims.Issuer)
+		fmt.Println(claims.Foo, claims.Issuer)
 	} else {
 		log.Fatal("unknown claims type, cannot proceed")
 	}
@@ -147,13 +147,13 @@ func (m MyCustomClaims) Validate() error
 func ExampleParseWithClaims_customValidation() {
 	tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpc3MiOiJ0ZXN0IiwiYXVkIjoic2luZ2xlIn0.QAWg1vGvnqRuCFTMcPkjZljXHh8U3L_qUjszOtQbeaA"
 
-	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
+	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (any, error) {
 		return []byte("AllYourBase"), nil
 	}, jwt.WithLeeway(5*time.Second))
 	if err != nil {
 		log.Fatal(err)
 	} else if claims, ok := token.Claims.(*MyCustomClaims); ok {
-		fmt.Println(claims.Foo, claims.RegisteredClaims.Issuer)
+		fmt.Println(claims.Foo, claims.Issuer)
 	} else {
 		log.Fatal("unknown claims type, cannot proceed")
 	}
@@ -166,7 +166,7 @@ func ExampleParse_errorChecking() {
 	// Token from another example.  This token is expired
 	var tokenString = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"
 
-	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
+	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
 		return []byte("AllYourBase"), nil
 	})
 
diff -pruN 5.2.2-1/go.mod 5.3.0-1/go.mod
--- 5.2.2-1/go.mod	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/go.mod	2025-09-29 23:42:57.000000000 +0000
@@ -1,3 +1,3 @@
 module github.com/golang-jwt/jwt/v5
 
-go 1.18
+go 1.21
diff -pruN 5.2.2-1/hmac.go 5.3.0-1/hmac.go
--- 5.2.2-1/hmac.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/hmac.go	2025-09-29 23:42:57.000000000 +0000
@@ -55,7 +55,7 @@ func (m *SigningMethodHMAC) Alg() string
 // about this, and why we intentionally are not supporting string as a key can
 // be found on our usage guide
 // https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types.
-func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key any) error {
 	// Verify the key is the right type
 	keyBytes, ok := key.([]byte)
 	if !ok {
@@ -88,7 +88,7 @@ func (m *SigningMethodHMAC) Verify(signi
 // cryptographically random source, e.g. crypto/rand. Additional information
 // about this, and why we intentionally are not supporting string as a key can
 // be found on our usage guide https://golang-jwt.github.io/jwt/usage/signing_methods/.
-func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodHMAC) Sign(signingString string, key any) ([]byte, error) {
 	if keyBytes, ok := key.([]byte); ok {
 		if !m.Hash.Available() {
 			return nil, ErrHashUnavailable
diff -pruN 5.2.2-1/hmac_example_test.go 5.3.0-1/hmac_example_test.go
--- 5.2.2-1/hmac_example_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/hmac_example_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -48,7 +48,7 @@ func ExampleParse_hmac() {
 	// useful if you use multiple keys for your application.  The standard is to use 'kid' in the
 	// head of the token to identify which key to use, but the parsed token (head and claims) is provided
 	// to the callback, providing flexibility.
-	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
+	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
 		// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
 		return hmacSampleSecret, nil
 	}, jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()}))
diff -pruN 5.2.2-1/hmac_test.go 5.3.0-1/hmac_test.go
--- 5.2.2-1/hmac_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/hmac_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -13,35 +13,35 @@ var hmacTestData = []struct {
 	name        string
 	tokenString string
 	alg         string
-	claims      map[string]interface{}
+	claims      map[string]any
 	valid       bool
 }{
 	{
 		"web sample",
 		"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
 		"HS256",
-		map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
+		map[string]any{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
 		true,
 	},
 	{
 		"HS384",
 		"eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.KWZEuOD5lbBxZ34g7F-SlVLAQ_r5KApWNWlZIIMyQVz5Zs58a7XdNzj5_0EcNoOy",
 		"HS384",
-		map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
+		map[string]any{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
 		true,
 	},
 	{
 		"HS512",
 		"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.CN7YijRX6Aw1n2jyI2Id1w90ja-DEMYiWixhYCyHnrZ1VfJRaFQz1bEbjjA5Fn4CLYaUG432dEYmSbS4Saokmw",
 		"HS512",
-		map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
+		map[string]any{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
 		true,
 	},
 	{
 		"web sample: invalid",
 		"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXo",
 		"HS256",
-		map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
+		map[string]any{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
 		false,
 	},
 }
diff -pruN 5.2.2-1/http_example_test.go 5.3.0-1/http_example_test.go
--- 5.2.2-1/http_example_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/http_example_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -92,11 +92,11 @@ func Example_getTokenViaHTTP() {
 	// Read the token out of the response body
 	buf, err := io.ReadAll(res.Body)
 	fatal(err)
-	res.Body.Close()
+	_ = res.Body.Close()
 	tokenString := strings.TrimSpace(string(buf))
 
 	// Parse the token
-	token, err := jwt.ParseWithClaims(tokenString, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
+	token, err := jwt.ParseWithClaims(tokenString, &CustomClaimsExample{}, func(token *jwt.Token) (any, error) {
 		// since we only use the one private key to sign the tokens,
 		// we also only use its public counter part to verify
 		return verifyKey, nil
@@ -104,7 +104,7 @@ func Example_getTokenViaHTTP() {
 	fatal(err)
 
 	claims := token.Claims.(*CustomClaimsExample)
-	fmt.Println(claims.CustomerInfo.Name)
+	fmt.Println(claims.Name)
 
 	// Output: test
 }
@@ -126,7 +126,7 @@ func Example_useTokenViaHTTP() {
 	// Read the response body
 	buf, err := io.ReadAll(res.Body)
 	fatal(err)
-	res.Body.Close()
+	_ = res.Body.Close()
 	fmt.Printf("%s", buf)
 
 	// Output: Welcome, foo
@@ -156,7 +156,7 @@ func authHandler(w http.ResponseWriter,
 	// make sure its post
 	if r.Method != "POST" {
 		w.WriteHeader(http.StatusBadRequest)
-		fmt.Fprintln(w, "No POST", r.Method)
+		_, _ = fmt.Fprintln(w, "No POST", r.Method)
 		return
 	}
 
@@ -168,27 +168,27 @@ func authHandler(w http.ResponseWriter,
 	// check values
 	if user != "test" || pass != "known" {
 		w.WriteHeader(http.StatusForbidden)
-		fmt.Fprintln(w, "Wrong info")
+		_, _ = fmt.Fprintln(w, "Wrong info")
 		return
 	}
 
 	tokenString, err := createToken(user)
 	if err != nil {
 		w.WriteHeader(http.StatusInternalServerError)
-		fmt.Fprintln(w, "Sorry, error while Signing Token!")
+		_, _ = fmt.Fprintln(w, "Sorry, error while Signing Token!")
 		log.Printf("Token Signing error: %v\n", err)
 		return
 	}
 
 	w.Header().Set("Content-Type", "application/jwt")
 	w.WriteHeader(http.StatusOK)
-	fmt.Fprintln(w, tokenString)
+	_, _ = fmt.Fprintln(w, tokenString)
 }
 
 // only accessible with a valid token
 func restrictedHandler(w http.ResponseWriter, r *http.Request) {
 	// Get token from request
-	token, err := request.ParseFromRequest(r, request.OAuth2Extractor, func(token *jwt.Token) (interface{}, error) {
+	token, err := request.ParseFromRequest(r, request.OAuth2Extractor, func(token *jwt.Token) (any, error) {
 		// since we only use the one private key to sign the tokens,
 		// we also only use its public counter part to verify
 		return verifyKey, nil
@@ -197,10 +197,10 @@ func restrictedHandler(w http.ResponseWr
 	// If the token is missing or invalid, return error
 	if err != nil {
 		w.WriteHeader(http.StatusUnauthorized)
-		fmt.Fprintln(w, "Invalid token:", err)
+		_, _ = fmt.Fprintln(w, "Invalid token:", err)
 		return
 	}
 
 	// Token is valid
-	fmt.Fprintln(w, "Welcome,", token.Claims.(*CustomClaimsExample).Name)
+	_, _ = fmt.Fprintln(w, "Welcome,", token.Claims.(*CustomClaimsExample).Name)
 }
diff -pruN 5.2.2-1/map_claims.go 5.3.0-1/map_claims.go
--- 5.2.2-1/map_claims.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/map_claims.go	2025-09-29 23:42:57.000000000 +0000
@@ -5,9 +5,9 @@ import (
 	"fmt"
 )
 
-// MapClaims is a claims type that uses the map[string]interface{} for JSON
+// MapClaims is a claims type that uses the map[string]any for JSON
 // decoding. This is the default claims type if you don't supply one
-type MapClaims map[string]interface{}
+type MapClaims map[string]any
 
 // GetExpirationTime implements the Claims interface.
 func (m MapClaims) GetExpirationTime() (*NumericDate, error) {
@@ -73,7 +73,7 @@ func (m MapClaims) parseClaimsString(key
 		cs = append(cs, v)
 	case []string:
 		cs = v
-	case []interface{}:
+	case []any:
 		for _, a := range v {
 			vs, ok := a.(string)
 			if !ok {
@@ -92,7 +92,7 @@ func (m MapClaims) parseClaimsString(key
 func (m MapClaims) parseString(key string) (string, error) {
 	var (
 		ok  bool
-		raw interface{}
+		raw any
 		iss string
 	)
 	raw, ok = m[key]
diff -pruN 5.2.2-1/map_claims_test.go 5.3.0-1/map_claims_test.go
--- 5.2.2-1/map_claims_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/map_claims_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -6,60 +6,65 @@ import (
 )
 
 func TestVerifyAud(t *testing.T) {
-	var nilInterface interface{}
-	var nilListInterface []interface{}
-	var intListInterface interface{} = []int{1, 2, 3}
+	var nilInterface any
+	var nilListInterface []any
+	var intListInterface any = []int{1, 2, 3}
 	type test struct {
-		Name       string
-		MapClaims  MapClaims
-		Expected   bool
-		Comparison string
-		Required   bool
+		Name        string
+		MapClaims   MapClaims
+		Expected    bool
+		Comparison  []string
+		MatchAllAud bool
+		Required    bool
 	}
 	tests := []test{
 		// Matching Claim in aud
 		// Required = true
-		{Name: "String Aud matching required", MapClaims: MapClaims{"aud": "example.com"}, Expected: true, Required: true, Comparison: "example.com"},
-		{Name: "[]String Aud with match required", MapClaims: MapClaims{"aud": []string{"example.com", "example.example.com"}}, Expected: true, Required: true, Comparison: "example.com"},
+		{Name: "String Aud matching required", MapClaims: MapClaims{"aud": "example.com"}, Expected: true, Required: true, Comparison: []string{"example.com"}},
+		{Name: "[]String Aud with match required", MapClaims: MapClaims{"aud": []string{"example.com", "example.example.com"}}, Expected: true, Required: true, Comparison: []string{"example.com"}},
+		{Name: "[]String Aud with []match any required", MapClaims: MapClaims{"aud": []string{"example.com", "example.example.com"}}, Expected: true, Required: true, Comparison: []string{"example.com", "auth.example.com"}},
+		{Name: "[]String Aud with []match all required", MapClaims: MapClaims{"aud": []string{"example.com", "example.example.com"}}, Expected: true, Required: true, Comparison: []string{"example.com", "example.example.com"}, MatchAllAud: true},
 
 		// Required = false
-		{Name: "String Aud with match not required", MapClaims: MapClaims{"aud": "example.com"}, Expected: true, Required: false, Comparison: "example.com"},
-		{Name: "Empty String Aud with match not required", MapClaims: MapClaims{}, Expected: true, Required: false, Comparison: "example.com"},
-		{Name: "Empty String Aud with match not required", MapClaims: MapClaims{"aud": ""}, Expected: true, Required: false, Comparison: "example.com"},
-		{Name: "Nil String Aud with match not required", MapClaims: MapClaims{"aud": nil}, Expected: true, Required: false, Comparison: "example.com"},
+		{Name: "String Aud with match not required", MapClaims: MapClaims{"aud": "example.com"}, Expected: true, Required: false, Comparison: []string{"example.com"}},
+		{Name: "Empty String Aud with match not required", MapClaims: MapClaims{}, Expected: true, Required: false, Comparison: []string{"example.com"}},
+		{Name: "Empty String Aud with match not required", MapClaims: MapClaims{"aud": ""}, Expected: true, Required: false, Comparison: []string{"example.com"}},
+		{Name: "Nil String Aud with match not required", MapClaims: MapClaims{"aud": nil}, Expected: true, Required: false, Comparison: []string{"example.com"}},
 
-		{Name: "[]String Aud with match not required", MapClaims: MapClaims{"aud": []string{"example.com", "example.example.com"}}, Expected: true, Required: false, Comparison: "example.com"},
-		{Name: "Empty []String Aud with match not required", MapClaims: MapClaims{"aud": []string{}}, Expected: true, Required: false, Comparison: "example.com"},
+		{Name: "[]String Aud with match not required", MapClaims: MapClaims{"aud": []string{"example.com", "example.example.com"}}, Expected: true, Required: false, Comparison: []string{"example.com"}},
+		{Name: "Empty []String Aud with match not required", MapClaims: MapClaims{"aud": []string{}}, Expected: true, Required: false, Comparison: []string{"example.com"}},
 
 		// Non-Matching Claim in aud
 		// Required = true
-		{Name: "String Aud without match required", MapClaims: MapClaims{"aud": "not.example.com"}, Expected: false, Required: true, Comparison: "example.com"},
-		{Name: "Empty String Aud without match required", MapClaims: MapClaims{"aud": ""}, Expected: false, Required: true, Comparison: "example.com"},
-		{Name: "[]String Aud without match required", MapClaims: MapClaims{"aud": []string{"not.example.com", "example.example.com"}}, Expected: false, Required: true, Comparison: "example.com"},
-		{Name: "Empty []String Aud without match required", MapClaims: MapClaims{"aud": []string{""}}, Expected: false, Required: true, Comparison: "example.com"},
-		{Name: "String Aud without match not required", MapClaims: MapClaims{"aud": "not.example.com"}, Expected: false, Required: true, Comparison: "example.com"},
-		{Name: "Empty String Aud without match not required", MapClaims: MapClaims{"aud": ""}, Expected: false, Required: true, Comparison: "example.com"},
-		{Name: "[]String Aud without match not required", MapClaims: MapClaims{"aud": []string{"not.example.com", "example.example.com"}}, Expected: false, Required: true, Comparison: "example.com"},
+		{Name: "String Aud without match required", MapClaims: MapClaims{"aud": "not.example.com"}, Expected: false, Required: true, Comparison: []string{"example.com"}},
+		{Name: "Empty String Aud without match required", MapClaims: MapClaims{"aud": ""}, Expected: false, Required: true, Comparison: []string{"example.com"}},
+		{Name: "[]String Aud without match required", MapClaims: MapClaims{"aud": []string{"not.example.com", "example.example.com"}}, Expected: false, Required: true, Comparison: []string{"example.com"}},
+		{Name: "Empty []String Aud without match required", MapClaims: MapClaims{"aud": []string{""}}, Expected: false, Required: true, Comparison: []string{"example.com"}},
+		{Name: "String Aud without match not required", MapClaims: MapClaims{"aud": "not.example.com"}, Expected: false, Required: true, Comparison: []string{"example.com"}},
+		{Name: "Empty String Aud without match not required", MapClaims: MapClaims{"aud": ""}, Expected: false, Required: true, Comparison: []string{"example.com"}},
+		{Name: "[]String Aud without match not required", MapClaims: MapClaims{"aud": []string{"not.example.com", "example.example.com"}}, Expected: false, Required: true, Comparison: []string{"example.com"}},
 
 		// Required = false
-		{Name: "Empty []String Aud without match required", MapClaims: MapClaims{"aud": []string{""}}, Expected: true, Required: false, Comparison: "example.com"},
+		{Name: "Empty []String Aud without match required", MapClaims: MapClaims{"aud": []string{""}}, Expected: true, Required: false, Comparison: []string{"example.com"}},
 
-		// []interface{}
-		{Name: "Empty []interface{} Aud without match required", MapClaims: MapClaims{"aud": nilListInterface}, Expected: true, Required: false, Comparison: "example.com"},
-		{Name: "[]interface{} Aud with match required", MapClaims: MapClaims{"aud": []interface{}{"a", "foo", "example.com"}}, Expected: true, Required: true, Comparison: "example.com"},
-		{Name: "[]interface{} Aud with match but invalid types", MapClaims: MapClaims{"aud": []interface{}{"a", 5, "example.com"}}, Expected: false, Required: true, Comparison: "example.com"},
-		{Name: "[]interface{} Aud int with match required", MapClaims: MapClaims{"aud": intListInterface}, Expected: false, Required: true, Comparison: "example.com"},
+		// []any
+		{Name: "Empty []interface{} Aud without match required", MapClaims: MapClaims{"aud": nilListInterface}, Expected: true, Required: false, Comparison: []string{"example.com"}},
+		{Name: "[]interface{} Aud with match required", MapClaims: MapClaims{"aud": []any{"a", "foo", "example.com"}}, Expected: true, Required: true, Comparison: []string{"example.com"}},
+		{Name: "[]interface{} Aud with match but invalid types", MapClaims: MapClaims{"aud": []any{"a", 5, "example.com"}}, Expected: false, Required: true, Comparison: []string{"example.com"}},
+		{Name: "[]interface{} Aud int with match required", MapClaims: MapClaims{"aud": intListInterface}, Expected: false, Required: true, Comparison: []string{"example.com"}},
 
-		// interface{}
-		{Name: "Empty interface{} Aud without match not required", MapClaims: MapClaims{"aud": nilInterface}, Expected: true, Required: false, Comparison: "example.com"},
+		// any
+		{Name: "Empty interface{} Aud without match not required", MapClaims: MapClaims{"aud": nilInterface}, Expected: true, Required: false, Comparison: []string{"example.com"}},
 	}
 
 	for _, test := range tests {
 		t.Run(test.Name, func(t *testing.T) {
 			var opts []ParserOption
 
-			if test.Required {
-				opts = append(opts, WithAudience(test.Comparison))
+			if test.Required && test.MatchAllAud {
+				opts = append(opts, WithAllAudiences(test.Comparison...))
+			} else if test.Required {
+				opts = append(opts, WithAudience(test.Comparison...))
 			}
 
 			validator := NewValidator(opts...)
diff -pruN 5.2.2-1/none.go 5.3.0-1/none.go
--- 5.2.2-1/none.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/none.go	2025-09-29 23:42:57.000000000 +0000
@@ -25,7 +25,7 @@ func (m *signingMethodNone) Alg() string
 }
 
 // Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Verify(signingString string, sig []byte, key interface{}) (err error) {
+func (m *signingMethodNone) Verify(signingString string, sig []byte, key any) (err error) {
 	// Key must be UnsafeAllowNoneSignatureType to prevent accidentally
 	// accepting 'none' signing method
 	if _, ok := key.(unsafeNoneMagicConstant); !ok {
@@ -41,7 +41,7 @@ func (m *signingMethodNone) Verify(signi
 }
 
 // Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *signingMethodNone) Sign(signingString string, key any) ([]byte, error) {
 	if _, ok := key.(unsafeNoneMagicConstant); ok {
 		return []byte{}, nil
 	}
diff -pruN 5.2.2-1/none_test.go 5.3.0-1/none_test.go
--- 5.2.2-1/none_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/none_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -12,8 +12,8 @@ var noneTestData = []struct {
 	name        string
 	tokenString string
 	alg         string
-	key         interface{}
-	claims      map[string]interface{}
+	key         any
+	claims      map[string]any
 	valid       bool
 }{
 	{
@@ -21,7 +21,7 @@ var noneTestData = []struct {
 		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.",
 		"none",
 		jwt.UnsafeAllowNoneSignatureType,
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
@@ -29,7 +29,7 @@ var noneTestData = []struct {
 		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.",
 		"none",
 		nil,
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		false,
 	},
 	{
@@ -37,7 +37,7 @@ var noneTestData = []struct {
 		"eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw",
 		"none",
 		jwt.UnsafeAllowNoneSignatureType,
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		false,
 	},
 }
diff -pruN 5.2.2-1/parser_option.go 5.3.0-1/parser_option.go
--- 5.2.2-1/parser_option.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/parser_option.go	2025-09-29 23:42:57.000000000 +0000
@@ -66,20 +66,37 @@ func WithExpirationRequired() ParserOpti
 	}
 }
 
-// WithAudience configures the validator to require the specified audience in
-// the `aud` claim. Validation will fail if the audience is not listed in the
-// token or the `aud` claim is missing.
+// WithAudience configures the validator to require any of the specified
+// audiences in the `aud` claim. Validation will fail if the audience is not
+// listed in the token or the `aud` claim is missing.
 //
 // NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
 // application-specific. Since this validation API is helping developers in
 // writing secure application, we decided to REQUIRE the existence of the claim,
 // if an audience is expected.
-func WithAudience(aud string) ParserOption {
+func WithAudience(aud ...string) ParserOption {
 	return func(p *Parser) {
 		p.validator.expectedAud = aud
 	}
 }
 
+// WithAllAudiences configures the validator to require all the specified
+// audiences in the `aud` claim. Validation will fail if the specified audiences
+// are not listed in the token or the `aud` claim is missing. Duplicates within
+// the list are de-duplicated since internally, we use a map to look up the
+// audiences.
+//
+// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
+// application-specific. Since this validation API is helping developers in
+// writing secure application, we decided to REQUIRE the existence of the claim,
+// if an audience is expected.
+func WithAllAudiences(aud ...string) ParserOption {
+	return func(p *Parser) {
+		p.validator.expectedAud = aud
+		p.validator.expectAllAud = true
+	}
+}
+
 // WithIssuer configures the validator to require the specified issuer in the
 // `iss` claim. Validation will fail if a different issuer is specified in the
 // token or the `iss` claim is missing.
diff -pruN 5.2.2-1/parser_test.go 5.3.0-1/parser_test.go
--- 5.2.2-1/parser_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/parser_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -22,29 +22,29 @@ var (
 	jwtTestEC256PublicKey  crypto.PublicKey
 	jwtTestEC256PrivateKey crypto.PrivateKey
 	paddedKey              crypto.PublicKey
-	defaultKeyFunc         jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestDefaultKey, nil }
-	ecdsaKeyFunc           jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestEC256PublicKey, nil }
-	paddedKeyFunc          jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return paddedKey, nil }
-	emptyKeyFunc           jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, nil }
-	errorKeyFunc           jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, errKeyFuncError }
+	defaultKeyFunc         jwt.Keyfunc = func(t *jwt.Token) (any, error) { return jwtTestDefaultKey, nil }
+	ecdsaKeyFunc           jwt.Keyfunc = func(t *jwt.Token) (any, error) { return jwtTestEC256PublicKey, nil }
+	paddedKeyFunc          jwt.Keyfunc = func(t *jwt.Token) (any, error) { return paddedKey, nil }
+	emptyKeyFunc           jwt.Keyfunc = func(t *jwt.Token) (any, error) { return nil, nil }
+	errorKeyFunc           jwt.Keyfunc = func(t *jwt.Token) (any, error) { return nil, errKeyFuncError }
 	nilKeyFunc             jwt.Keyfunc = nil
-	multipleZeroKeyFunc    jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return []interface{}{}, nil }
-	multipleEmptyKeyFunc   jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) {
+	multipleZeroKeyFunc    jwt.Keyfunc = func(t *jwt.Token) (any, error) { return []any{}, nil }
+	multipleEmptyKeyFunc   jwt.Keyfunc = func(t *jwt.Token) (any, error) {
 		return jwt.VerificationKeySet{Keys: []jwt.VerificationKey{nil, nil}}, nil
 	}
-	multipleVerificationKeysFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) {
+	multipleVerificationKeysFunc jwt.Keyfunc = func(t *jwt.Token) (any, error) {
 		return []jwt.VerificationKey{jwtTestDefaultKey, jwtTestEC256PublicKey}, nil
 	}
-	multipleLastKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) {
+	multipleLastKeyFunc jwt.Keyfunc = func(t *jwt.Token) (any, error) {
 		return jwt.VerificationKeySet{Keys: []jwt.VerificationKey{jwtTestEC256PublicKey, jwtTestDefaultKey}}, nil
 	}
-	multipleFirstKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) {
+	multipleFirstKeyFunc jwt.Keyfunc = func(t *jwt.Token) (any, error) {
 		return jwt.VerificationKeySet{Keys: []jwt.VerificationKey{jwtTestDefaultKey, jwtTestEC256PublicKey}}, nil
 	}
-	multipleAltTypedKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) {
+	multipleAltTypedKeyFunc jwt.Keyfunc = func(t *jwt.Token) (any, error) {
 		return jwt.VerificationKeySet{Keys: []jwt.VerificationKey{jwtTestDefaultKey, jwtTestDefaultKey}}, nil
 	}
-	emptyVerificationKeySetFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) {
+	emptyVerificationKeySetFunc jwt.Keyfunc = func(t *jwt.Token) (any, error) {
 		return jwt.VerificationKeySet{}, nil
 	}
 )
@@ -437,7 +437,7 @@ var jwtTestData = []struct {
 
 // signToken creates and returns a signed JWT token using signingMethod.
 func signToken(claims jwt.Claims, signingMethod jwt.SigningMethod) string {
-	var privateKey interface{}
+	var privateKey any
 	switch signingMethod {
 	case jwt.SigningMethodRS256:
 		privateKey = jwtTestRSAPrivateKey
@@ -744,7 +744,7 @@ func TestSetPadding(t *testing.T) {
 			// Parse the token
 			var token *jwt.Token
 			var err error
-			var opts []jwt.ParserOption = []jwt.ParserOption{jwt.WithoutClaimsValidation()}
+			var opts = []jwt.ParserOption{jwt.WithoutClaimsValidation()}
 
 			if data.paddedDecode {
 				opts = append(opts, jwt.WithPaddingAllowed())
@@ -812,7 +812,7 @@ func benchmarkParsing(b *testing.B, pars
 }
 
 // Helper method for benchmarking various signing methods
-func benchmarkSigning(b *testing.B, method jwt.SigningMethod, key interface{}) {
+func benchmarkSigning(b *testing.B, method jwt.SigningMethod, key any) {
 	b.Helper()
 	t := jwt.New(method)
 	b.ReportAllocs()
diff -pruN 5.2.2-1/request/request_test.go 5.3.0-1/request/request_test.go
--- 5.2.2-1/request/request_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/request/request_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -58,7 +58,7 @@ func TestParseRequest(t *testing.T) {
 	// load keys from disk
 	privateKey := test.LoadRSAPrivateKeyFromDisk("../test/sample_key")
 	publicKey := test.LoadRSAPublicKeyFromDisk("../test/sample_key.pub")
-	keyfunc := func(*jwt.Token) (interface{}, error) {
+	keyfunc := func(*jwt.Token) (any, error) {
 		return publicKey, nil
 	}
 
diff -pruN 5.2.2-1/rsa.go 5.3.0-1/rsa.go
--- 5.2.2-1/rsa.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/rsa.go	2025-09-29 23:42:57.000000000 +0000
@@ -46,7 +46,7 @@ func (m *SigningMethodRSA) Alg() string
 
 // Verify implements token verification for the SigningMethod
 // For this signing method, must be an *rsa.PublicKey structure.
-func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key any) error {
 	var rsaKey *rsa.PublicKey
 	var ok bool
 
@@ -67,7 +67,7 @@ func (m *SigningMethodRSA) Verify(signin
 
 // Sign implements token signing for the SigningMethod
 // For this signing method, must be an *rsa.PrivateKey structure.
-func (m *SigningMethodRSA) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodRSA) Sign(signingString string, key any) ([]byte, error) {
 	var rsaKey *rsa.PrivateKey
 	var ok bool
 
diff -pruN 5.2.2-1/rsa_pss.go 5.3.0-1/rsa_pss.go
--- 5.2.2-1/rsa_pss.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/rsa_pss.go	2025-09-29 23:42:57.000000000 +0000
@@ -1,6 +1,3 @@
-//go:build go1.4
-// +build go1.4
-
 package jwt
 
 import (
@@ -82,7 +79,7 @@ func init() {
 
 // Verify implements token verification for the SigningMethod.
 // For this verify method, key must be an rsa.PublicKey struct
-func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key any) error {
 	var rsaKey *rsa.PublicKey
 	switch k := key.(type) {
 	case *rsa.PublicKey:
@@ -108,7 +105,7 @@ func (m *SigningMethodRSAPSS) Verify(sig
 
 // Sign implements token signing for the SigningMethod.
 // For this signing method, key must be an rsa.PrivateKey struct
-func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodRSAPSS) Sign(signingString string, key any) ([]byte, error) {
 	var rsaKey *rsa.PrivateKey
 
 	switch k := key.(type) {
diff -pruN 5.2.2-1/rsa_pss_test.go 5.3.0-1/rsa_pss_test.go
--- 5.2.2-1/rsa_pss_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/rsa_pss_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -1,6 +1,3 @@
-//go:build go1.4
-// +build go1.4
-
 package jwt_test
 
 import (
@@ -18,35 +15,35 @@ var rsaPSSTestData = []struct {
 	name        string
 	tokenString string
 	alg         string
-	claims      map[string]interface{}
+	claims      map[string]any
 	valid       bool
 }{
 	{
 		"Basic PS256",
 		"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9w",
 		"PS256",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
 		"Basic PS384",
 		"eyJhbGciOiJQUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.w7-qqgj97gK4fJsq_DCqdYQiylJjzWONvD0qWWWhqEOFk2P1eDULPnqHRnjgTXoO4HAw4YIWCsZPet7nR3Xxq4ZhMqvKW8b7KlfRTb9cH8zqFvzMmybQ4jv2hKc3bXYqVow3AoR7hN_CWXI3Dv6Kd2X5xhtxRHI6IL39oTVDUQ74LACe-9t4c3QRPuj6Pq1H4FAT2E2kW_0KOc6EQhCLWEhm2Z2__OZskDC8AiPpP8Kv4k2vB7l0IKQu8Pr4RcNBlqJdq8dA5D3hk5TLxP8V5nG1Ib80MOMMqoS3FQvSLyolFX-R_jZ3-zfq6Ebsqr0yEb0AH2CfsECF7935Pa0FKQ",
 		"PS384",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
 		"Basic PS512",
 		"eyJhbGciOiJQUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.GX1HWGzFaJevuSLavqqFYaW8_TpvcjQ8KfC5fXiSDzSiT9UD9nB_ikSmDNyDILNdtjZLSvVKfXxZJqCfefxAtiozEDDdJthZ-F0uO4SPFHlGiXszvKeodh7BuTWRI2wL9-ZO4mFa8nq3GMeQAfo9cx11i7nfN8n2YNQ9SHGovG7_T_AvaMZB_jT6jkDHpwGR9mz7x1sycckEo6teLdHRnH_ZdlHlxqknmyTu8Odr5Xh0sJFOL8BepWbbvIIn-P161rRHHiDWFv6nhlHwZnVzjx7HQrWSGb6-s2cdLie9QL_8XaMcUpjLkfOMKkDOfHo6AvpL7Jbwi83Z2ZTHjJWB-A",
 		"PS512",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		true,
 	},
 	{
 		"basic PS256 invalid: foo => bar",
 		"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9W",
 		"PS256",
-		map[string]interface{}{"foo": "bar"},
+		map[string]any{"foo": "bar"},
 		false,
 	},
 }
diff -pruN 5.2.2-1/rsa_utils.go 5.3.0-1/rsa_utils.go
--- 5.2.2-1/rsa_utils.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/rsa_utils.go	2025-09-29 23:42:57.000000000 +0000
@@ -23,7 +23,7 @@ func ParseRSAPrivateKeyFromPEM(key []byt
 		return nil, ErrKeyMustBePEMEncoded
 	}
 
-	var parsedKey interface{}
+	var parsedKey any
 	if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
 		if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
 			return nil, err
@@ -53,7 +53,7 @@ func ParseRSAPrivateKeyFromPEMWithPasswo
 		return nil, ErrKeyMustBePEMEncoded
 	}
 
-	var parsedKey interface{}
+	var parsedKey any
 
 	var blockDecrypted []byte
 	if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {
@@ -86,7 +86,7 @@ func ParseRSAPublicKeyFromPEM(key []byte
 	}
 
 	// Parse the key
-	var parsedKey interface{}
+	var parsedKey any
 	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
 		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
 			parsedKey = cert.PublicKey
diff -pruN 5.2.2-1/signing_method.go 5.3.0-1/signing_method.go
--- 5.2.2-1/signing_method.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/signing_method.go	2025-09-29 23:42:57.000000000 +0000
@@ -12,9 +12,9 @@ var signingMethodLock = new(sync.RWMutex
 // signature in Sign. The signature is then usually base64 encoded as part of a
 // JWT.
 type SigningMethod interface {
-	Verify(signingString string, sig []byte, key interface{}) error // Returns nil if signature is valid
-	Sign(signingString string, key interface{}) ([]byte, error)     // Returns signature or error
-	Alg() string                                                    // returns the alg identifier for this method (example: 'HS256')
+	Verify(signingString string, sig []byte, key any) error // Returns nil if signature is valid
+	Sign(signingString string, key any) ([]byte, error)     // Returns signature or error
+	Alg() string                                            // returns the alg identifier for this method (example: 'HS256')
 }
 
 // RegisterSigningMethod registers the "alg" name and a factory function for signing method.
diff -pruN 5.2.2-1/test/helpers.go 5.3.0-1/test/helpers.go
--- 5.2.2-1/test/helpers.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/test/helpers.go	2025-09-29 23:42:57.000000000 +0000
@@ -33,7 +33,7 @@ func LoadRSAPublicKeyFromDisk(location s
 }
 
 // MakeSampleToken creates and returns a encoded JWT token that has been signed with the specified cryptographic key.
-func MakeSampleToken(c jwt.Claims, method jwt.SigningMethod, key interface{}) string {
+func MakeSampleToken(c jwt.Claims, method jwt.SigningMethod, key any) string {
 	token := jwt.NewWithClaims(method, c)
 	s, e := token.SignedString(key)
 
diff -pruN 5.2.2-1/token.go 5.3.0-1/token.go
--- 5.2.2-1/token.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/token.go	2025-09-29 23:42:57.000000000 +0000
@@ -11,9 +11,9 @@ import (
 // Token.  This allows you to use properties in the Header of the token (such as
 // `kid`) to identify which key to use.
 //
-// The returned interface{} may be a single key or a VerificationKeySet containing
+// The returned any may be a single key or a VerificationKeySet containing
 // multiple keys.
-type Keyfunc func(*Token) (interface{}, error)
+type Keyfunc func(*Token) (any, error)
 
 // VerificationKey represents a public or secret key for verifying a token's signature.
 type VerificationKey interface {
@@ -28,12 +28,12 @@ type VerificationKeySet struct {
 // Token represents a JWT Token.  Different fields will be used depending on
 // whether you're creating or parsing/verifying a token.
 type Token struct {
-	Raw       string                 // Raw contains the raw token.  Populated when you [Parse] a token
-	Method    SigningMethod          // Method is the signing method used or to be used
-	Header    map[string]interface{} // Header is the first segment of the token in decoded form
-	Claims    Claims                 // Claims is the second segment of the token in decoded form
-	Signature []byte                 // Signature is the third segment of the token in decoded form.  Populated when you Parse a token
-	Valid     bool                   // Valid specifies if the token is valid.  Populated when you Parse/Verify a token
+	Raw       string         // Raw contains the raw token.  Populated when you [Parse] a token
+	Method    SigningMethod  // Method is the signing method used or to be used
+	Header    map[string]any // Header is the first segment of the token in decoded form
+	Claims    Claims         // Claims is the second segment of the token in decoded form
+	Signature []byte         // Signature is the third segment of the token in decoded form.  Populated when you Parse a token
+	Valid     bool           // Valid specifies if the token is valid.  Populated when you Parse/Verify a token
 }
 
 // New creates a new [Token] with the specified signing method and an empty map
@@ -46,7 +46,7 @@ func New(method SigningMethod, opts ...T
 // claims. Additional options can be specified, but are currently unused.
 func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *Token {
 	return &Token{
-		Header: map[string]interface{}{
+		Header: map[string]any{
 			"typ": "JWT",
 			"alg": method.Alg(),
 		},
@@ -60,7 +60,7 @@ func NewWithClaims(method SigningMethod,
 // https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types
 // for an overview of the different signing methods and their respective key
 // types.
-func (t *Token) SignedString(key interface{}) (string, error) {
+func (t *Token) SignedString(key any) (string, error) {
 	sstr, err := t.SigningString()
 	if err != nil {
 		return "", err
diff -pruN 5.2.2-1/token_test.go 5.3.0-1/token_test.go
--- 5.2.2-1/token_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/token_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -10,7 +10,7 @@ func TestToken_SigningString(t1 *testing
 	type fields struct {
 		Raw       string
 		Method    jwt.SigningMethod
-		Header    map[string]interface{}
+		Header    map[string]any
 		Claims    jwt.Claims
 		Signature []byte
 		Valid     bool
@@ -26,7 +26,7 @@ func TestToken_SigningString(t1 *testing
 			fields: fields{
 				Raw:    "",
 				Method: jwt.SigningMethodHS256,
-				Header: map[string]interface{}{
+				Header: map[string]any{
 					"typ": "JWT",
 					"alg": jwt.SigningMethodHS256.Alg(),
 				},
@@ -62,7 +62,7 @@ func TestToken_SigningString(t1 *testing
 func BenchmarkToken_SigningString(b *testing.B) {
 	t := &jwt.Token{
 		Method: jwt.SigningMethodHS256,
-		Header: map[string]interface{}{
+		Header: map[string]any{
 			"typ": "JWT",
 			"alg": jwt.SigningMethodHS256.Alg(),
 		},
diff -pruN 5.2.2-1/types.go 5.3.0-1/types.go
--- 5.2.2-1/types.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/types.go	2025-09-29 23:42:57.000000000 +0000
@@ -103,7 +103,7 @@ func (date *NumericDate) UnmarshalJSON(b
 type ClaimStrings []string
 
 func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) {
-	var value interface{}
+	var value any
 
 	if err = json.Unmarshal(data, &value); err != nil {
 		return err
@@ -116,7 +116,7 @@ func (s *ClaimStrings) UnmarshalJSON(dat
 		aud = append(aud, v)
 	case []string:
 		aud = ClaimStrings(v)
-	case []interface{}:
+	case []any:
 		for _, vv := range v {
 			vs, ok := vv.(string)
 			if !ok {
diff -pruN 5.2.2-1/validator.go 5.3.0-1/validator.go
--- 5.2.2-1/validator.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/validator.go	2025-09-29 23:42:57.000000000 +0000
@@ -1,8 +1,8 @@
 package jwt
 
 import (
-	"crypto/subtle"
 	"fmt"
+	"slices"
 	"time"
 )
 
@@ -52,8 +52,12 @@ type Validator struct {
 	verifyIat bool
 
 	// expectedAud contains the audience this token expects. Supplying an empty
-	// string will disable aud checking.
-	expectedAud string
+	// slice will disable aud checking.
+	expectedAud []string
+
+	// expectAllAud specifies whether all expected audiences must be present in
+	// the token. If false, only one of the expected audiences must be present.
+	expectAllAud bool
 
 	// expectedIss contains the issuer this token expects. Supplying an empty
 	// string will disable iss checking.
@@ -88,7 +92,7 @@ func NewValidator(opts ...ParserOption)
 func (v *Validator) Validate(claims Claims) error {
 	var (
 		now  time.Time
-		errs []error = make([]error, 0, 6)
+		errs = make([]error, 0, 6)
 		err  error
 	)
 
@@ -120,8 +124,8 @@ func (v *Validator) Validate(claims Clai
 	}
 
 	// If we have an expected audience, we also require the audience claim
-	if v.expectedAud != "" {
-		if err = v.verifyAudience(claims, v.expectedAud, true); err != nil {
+	if len(v.expectedAud) > 0 {
+		if err = v.verifyAudience(claims, v.expectedAud, v.expectAllAud); err != nil {
 			errs = append(errs, err)
 		}
 	}
@@ -226,33 +230,39 @@ func (v *Validator) verifyNotBefore(clai
 //
 // Additionally, if any error occurs while retrieving the claim, e.g., when its
 // the wrong type, an ErrTokenUnverifiable error will be returned.
-func (v *Validator) verifyAudience(claims Claims, cmp string, required bool) error {
+func (v *Validator) verifyAudience(claims Claims, cmp []string, expectAllAud bool) error {
 	aud, err := claims.GetAudience()
 	if err != nil {
 		return err
 	}
 
-	if len(aud) == 0 {
+	// Check that aud exists and is not empty. We only require the aud claim
+	// if we expect at least one audience to be present.
+	if len(aud) == 0 || len(aud) == 1 && aud[0] == "" {
+		required := len(v.expectedAud) > 0
 		return errorIfRequired(required, "aud")
 	}
 
-	// use a var here to keep constant time compare when looping over a number of claims
-	result := false
-
-	var stringClaims string
-	for _, a := range aud {
-		if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
-			result = true
+	if !expectAllAud {
+		for _, a := range aud {
+			// If we only expect one match, we can stop early if we find a match
+			if slices.Contains(cmp, a) {
+				return nil
+			}
 		}
-		stringClaims = stringClaims + a
+
+		return ErrTokenInvalidAudience
 	}
 
-	// case where "" is sent in one or many aud claims
-	if stringClaims == "" {
-		return errorIfRequired(required, "aud")
+	// Note that we are looping cmp here to ensure that all expected audiences
+	// are present in the aud claim.
+	for _, a := range cmp {
+		if !slices.Contains(aud, a) {
+			return ErrTokenInvalidAudience
+		}
 	}
 
-	return errorIfFalse(result, ErrTokenInvalidAudience)
+	return nil
 }
 
 // verifyIssuer compares the iss claim in claims against cmp.
diff -pruN 5.2.2-1/validator_test.go 5.3.0-1/validator_test.go
--- 5.2.2-1/validator_test.go	2025-03-22 19:01:34.000000000 +0000
+++ 5.3.0-1/validator_test.go	2025-09-29 23:42:57.000000000 +0000
@@ -22,12 +22,13 @@ func (m MyCustomClaims) Validate() error
 
 func Test_Validator_Validate(t *testing.T) {
 	type fields struct {
-		leeway      time.Duration
-		timeFunc    func() time.Time
-		verifyIat   bool
-		expectedAud string
-		expectedIss string
-		expectedSub string
+		leeway       time.Duration
+		timeFunc     func() time.Time
+		verifyIat    bool
+		expectedAud  []string
+		expectAllAud bool
+		expectedIss  string
+		expectedSub  string
 	}
 	type args struct {
 		claims Claims
@@ -72,12 +73,13 @@ func Test_Validator_Validate(t *testing.
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			v := &Validator{
-				leeway:      tt.fields.leeway,
-				timeFunc:    tt.fields.timeFunc,
-				verifyIat:   tt.fields.verifyIat,
-				expectedAud: tt.fields.expectedAud,
-				expectedIss: tt.fields.expectedIss,
-				expectedSub: tt.fields.expectedSub,
+				leeway:       tt.fields.leeway,
+				timeFunc:     tt.fields.timeFunc,
+				verifyIat:    tt.fields.verifyIat,
+				expectedAud:  tt.fields.expectedAud,
+				expectAllAud: tt.fields.expectAllAud,
+				expectedIss:  tt.fields.expectedIss,
+				expectedSub:  tt.fields.expectedSub,
 			}
 			if err := v.Validate(tt.args.claims); (err != nil) && !errors.Is(err, tt.wantErr) {
 				t.Errorf("validator.Validate() error = %v, wantErr %v", err, tt.wantErr)
@@ -258,4 +260,117 @@ func Test_Validator_verifyIssuedAt(t *te
 			}
 		})
 	}
+}
+
+func Test_Validator_verifyAudience(t *testing.T) {
+	type fields struct {
+		expectedAud []string
+	}
+	type args struct {
+		claims       Claims
+		cmp          []string
+		expectAllAud bool
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr error
+	}{
+		{
+			name:   "fail without audience when expecting one aud match",
+			fields: fields{expectedAud: []string{"example.com"}},
+			args: args{
+				claims:       MapClaims{},
+				cmp:          []string{"example.com"},
+				expectAllAud: false,
+			},
+			wantErr: ErrTokenRequiredClaimMissing,
+		},
+		{
+			name:   "fail without audience when expecting all aud matches",
+			fields: fields{expectedAud: []string{"example.com"}},
+			args: args{
+				claims:       MapClaims{},
+				cmp:          []string{"example.com"},
+				expectAllAud: true,
+			},
+			wantErr: ErrTokenRequiredClaimMissing,
+		},
+		{
+			name:   "good when audience matches",
+			fields: fields{expectedAud: []string{"example.com"}},
+			args: args{
+				claims:       RegisteredClaims{Audience: ClaimStrings{"example.com"}},
+				cmp:          []string{"example.com"},
+				expectAllAud: false,
+			},
+			wantErr: nil,
+		},
+		{
+			name:   "fail when audience matches with one value",
+			fields: fields{expectedAud: []string{"example.org", "example.com"}},
+			args: args{
+				claims:       RegisteredClaims{Audience: ClaimStrings{"example.com"}},
+				cmp:          []string{"example.org", "example.com"},
+				expectAllAud: false,
+			},
+			wantErr: nil,
+		},
+		{
+			name:   "fail when audience matches with all values",
+			fields: fields{expectedAud: []string{"example.org", "example.com"}},
+			args: args{
+				claims:       RegisteredClaims{Audience: ClaimStrings{"example.org", "example.com"}},
+				cmp:          []string{"example.org", "example.com"},
+				expectAllAud: true,
+			},
+			wantErr: nil,
+		},
+		{
+			name:   "fail when audience not matching",
+			fields: fields{expectedAud: []string{"example.org", "example.com"}},
+			args: args{
+				claims:       RegisteredClaims{Audience: ClaimStrings{"example.net"}},
+				cmp:          []string{"example.org", "example.com"},
+				expectAllAud: false,
+			},
+			wantErr: ErrTokenInvalidAudience,
+		},
+		{
+			name:   "fail when audience not matching all values",
+			fields: fields{expectedAud: []string{"example.org", "example.com"}},
+			args: args{
+				claims:       RegisteredClaims{Audience: ClaimStrings{"example.org", "example.net"}},
+				cmp:          []string{"example.org", "example.com"},
+				expectAllAud: true,
+			},
+			wantErr: ErrTokenInvalidAudience,
+		},
+		{
+			name:   "fail when audience missing",
+			fields: fields{expectedAud: []string{"example.org", "example.com"}},
+			args: args{
+				claims:       MapClaims{},
+				cmp:          []string{"example.org", "example.com"},
+				expectAllAud: true,
+			},
+			wantErr: ErrTokenRequiredClaimMissing,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			v := &Validator{
+				expectedAud:  tt.fields.expectedAud,
+				expectAllAud: tt.args.expectAllAud,
+			}
+
+			err := v.verifyAudience(tt.args.claims, tt.args.cmp, tt.args.expectAllAud)
+			if tt.wantErr == nil && err != nil {
+				t.Errorf("validator.verifyAudience() error = %v, wantErr %v", err, tt.wantErr)
+			} else if tt.wantErr != nil && !errors.Is(err, tt.wantErr) {
+				t.Errorf("validator.verifyAudience() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
 }
