Skip to content

Commit 20849bd

Browse files
lestrratDaisuke Maki
and
Daisuke Maki
authored
Change default behavior around truncation of time fields (#1318)
* Change the default settings for truncation * appease linter --------- Co-authored-by: Daisuke Maki <lestrrat+github@github.com>
1 parent 08159ca commit 20849bd

File tree

6 files changed

+479
-14
lines changed

6 files changed

+479
-14
lines changed

Changes

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ Changes
44
v3 has many incompatibilities with v2. To see the full list of differences between
55
v2 and v3, please read the Changes-v3.md file (https://github.com/lestrrat-go/jwx/blob/develop/v3/Changes-v3.md)
66

7+
v3.0.0-beta1
8+
* [jwt] Token validation no longer truncates time based fields by default.
9+
To restore old behavior, you can either change the global settings by
10+
calling `jwt.Settings(jwt.WithTruncation(time.Second))`, or you can
11+
change it by each invocation by using `jwt.Validate(..., jwt.WithTruncation(0))`
12+
713
v3.0.0-alpha3 13 Mar 2025
814
* [jwk] Importing/Exporting from jwk.Key to ecdh.PrivateKey/ecdh.PublicKey should now work. Previously these keys were not properly
915
recognized by the exporter/importer. Note that keys that use X25519 and

jwt/jwt.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,28 @@ import (
99
"fmt"
1010
"io"
1111
"sync/atomic"
12+
"time"
1213

1314
"github.com/lestrrat-go/jwx/v3"
1415
"github.com/lestrrat-go/jwx/v3/internal/json"
1516
"github.com/lestrrat-go/jwx/v3/jws"
1617
"github.com/lestrrat-go/jwx/v3/jwt/internal/types"
1718
)
1819

20+
var defaultTruncation atomic.Int64
21+
1922
// Settings controls global settings that are specific to JWTs.
2023
func Settings(options ...GlobalOption) {
2124
var flattenAudience bool
2225
var parsePedantic bool
2326
var parsePrecision = types.MaxPrecision + 1 // illegal value, so we can detect nothing was set
2427
var formatPrecision = types.MaxPrecision + 1 // illegal value, so we can detect nothing was set
25-
28+
truncation := time.Duration(-1)
2629
//nolint:forcetypeassert
2730
for _, option := range options {
2831
switch option.Ident() {
32+
case identTruncation{}:
33+
truncation = option.Value().(time.Duration)
2934
case identFlattenAudience{}:
3035
flattenAudience = option.Value().(bool)
3136
case identNumericDateParsePedantic{}:
@@ -79,6 +84,10 @@ func Settings(options ...GlobalOption) {
7984
}
8085
defaultOptionsMu.Unlock()
8186
}
87+
88+
if truncation >= 0 {
89+
defaultTruncation.Store(int64(truncation))
90+
}
8291
}
8392

8493
var registry = json.NewRegistry()
@@ -503,3 +512,7 @@ type CustomDecodeFunc = json.CustomDecodeFunc
503512
func RegisterCustomField(name string, object interface{}) {
504513
registry.Register(name, object)
505514
}
515+
516+
func getDefaultTruncation() time.Duration {
517+
return time.Duration(defaultTruncation.Load())
518+
}

jwt/options.yaml

+18-5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ interfaces:
4040
- name: ReadFileOption
4141
comment: |
4242
ReadFileOption is a type of `Option` that can be passed to `jws.ReadFile`
43+
- name: GlobalValidateOption
44+
methods:
45+
- globalOption
46+
- parseOption
47+
- readFileOption
48+
- validateOption
49+
comment: |
50+
GlobalValidateOption describes an Option that can be passed to `jwt.Settings()` and `jwt.Validate()`
4351
options:
4452
- ident: AcceptableSkew
4553
interface: ValidateOption
@@ -48,14 +56,19 @@ options:
4856
WithAcceptableSkew specifies the duration in which exp, iat and nbf
4957
claims may differ by. This value should be positive
5058
- ident: Truncation
51-
interface: ValidateOption
59+
interface: GlobalValidateOption
5260
argument_type: time.Duration
5361
comment: |
5462
WithTruncation specifies the amount that should be used when
55-
truncating time values used during time-based validation routines.
56-
By default time values are truncated down to second accuracy.
57-
If you want to use sub-second accuracy, you will need to set
58-
this value to 0.
63+
truncating time values used during time-based validation routines,
64+
and by default this is disabled.
65+
66+
In v2 of this library, time values were truncated down to second accuracy, i.e.
67+
1.0000001 seconds is truncated to 1 second. To restore this behavior, set
68+
this value to `time.Second`
69+
70+
Since v3, this option can be passed to `jwt.Settings()` to set the truncation
71+
value globally, as well as per invocation of `jwt.Validate()`
5972
- ident: Clock
6073
interface: ValidateOption
6174
argument_type: Clock

jwt/options_gen.go

+32-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jwt/validate.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func timeClaim(t Token, clock Clock, c string) time.Time {
4949
// that can control the behavior of this method.
5050
func Validate(t Token, options ...ValidateOption) error {
5151
ctx := context.Background()
52-
trunc := time.Second
52+
trunc := getDefaultTruncation()
5353

5454
var clock Clock = ClockFunc(time.Now)
5555
var skew time.Duration

0 commit comments

Comments
 (0)