Skip to content

Commit cd694f4

Browse files
committed
feat: make id_token mutator cache configurable
1 parent 62ca1e8 commit cd694f4

File tree

5 files changed

+101
-20
lines changed

5 files changed

+101
-20
lines changed

.schema/config.schema.json

+19
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,25 @@
11401140
"pattern": "^[0-9]+(ns|us|ms|s|m|h)$",
11411141
"default": "15m",
11421142
"examples": ["1h", "1m", "30s"]
1143+
},
1144+
"cache": {
1145+
"additionalProperties": false,
1146+
"type": "object",
1147+
"properties": {
1148+
"enabled": {
1149+
"title": "Enabled",
1150+
"type": "boolean",
1151+
"default": true,
1152+
"examples": [false, true],
1153+
"description": "En-/disables this component."
1154+
},
1155+
"max_cost": {
1156+
"type": "integer",
1157+
"default": 33554432,
1158+
"title": "Maximum Cached Cost",
1159+
"description": "Max cost to cache."
1160+
}
1161+
}
11431162
}
11441163
},
11451164
"additionalProperties": false

.schemas/mutators.id_token.schema.json

+19
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@
3232
"pattern": "^[0-9]+(ns|us|ms|s|m|h)$",
3333
"default": "1m",
3434
"examples": ["1h", "1m", "30s"]
35+
},
36+
"cache": {
37+
"additionalProperties": false,
38+
"type": "object",
39+
"properties": {
40+
"enabled": {
41+
"title": "Enabled",
42+
"type": "boolean",
43+
"default": true,
44+
"examples": [false, true],
45+
"description": "En-/disables this component."
46+
},
47+
"max_cost": {
48+
"type": "integer",
49+
"default": 33554432,
50+
"title": "Maximum Cached Cost",
51+
"description": "Max cost to cache."
52+
}
53+
}
3554
}
3655
},
3756
"additionalProperties": false

pipeline/mutate/mutator_id_token.go

+43-19
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,28 @@ type MutatorIDToken struct {
3838
templates *template.Template
3939
templatesLock sync.Mutex
4040

41-
tokenCache *ristretto.Cache
42-
tokenCacheEnabled bool
41+
tokenCache *ristretto.Cache
4342
}
4443

4544
type CredentialsIDTokenConfig struct {
46-
Claims string `json:"claims"`
47-
IssuerURL string `json:"issuer_url"`
48-
JWKSURL string `json:"jwks_url"`
49-
TTL string `json:"ttl"`
45+
Claims string `json:"claims"`
46+
IssuerURL string `json:"issuer_url"`
47+
JWKSURL string `json:"jwks_url"`
48+
TTL string `json:"ttl"`
49+
Cache IdTokenCacheConfig `json:"cache"`
50+
}
51+
52+
type IdTokenCacheConfig struct {
53+
Enabled bool `json:"enabled"`
54+
MaxCost int `json:"max_cost"`
5055
}
5156

5257
func (c *CredentialsIDTokenConfig) ClaimsTemplateID() string {
5358
return fmt.Sprintf("%x", md5.Sum([]byte(c.Claims)))
5459
}
5560

5661
func NewMutatorIDToken(c configuration.Provider, r MutatorIDTokenRegistry) *MutatorIDToken {
57-
cache, _ := ristretto.NewCache(&ristretto.Config{
58-
NumCounters: 10000,
59-
MaxCost: 1 << 25,
60-
BufferItems: 64,
61-
})
62-
return &MutatorIDToken{r: r, c: c, templates: x.NewTemplate("id_token"), tokenCache: cache, tokenCacheEnabled: true}
62+
return &MutatorIDToken{r: r, c: c, templates: x.NewTemplate("id_token")}
6363
}
6464

6565
func (a *MutatorIDToken) GetID() string {
@@ -70,10 +70,6 @@ func (a *MutatorIDToken) WithCache(t *template.Template) {
7070
a.templates = t
7171
}
7272

73-
func (a *MutatorIDToken) SetCaching(token bool) {
74-
a.tokenCacheEnabled = token
75-
}
76-
7773
type idTokenCacheContainer struct {
7874
ExpiresAt time.Time
7975
TTL time.Duration
@@ -87,7 +83,7 @@ func (a *MutatorIDToken) cacheKey(config *CredentialsIDTokenConfig, ttl time.Dur
8783
}
8884

8985
func (a *MutatorIDToken) tokenFromCache(config *CredentialsIDTokenConfig, session *authn.AuthenticationSession, claims []byte, ttl time.Duration) (string, bool) {
90-
if !a.tokenCacheEnabled {
86+
if !config.Cache.Enabled {
9187
return "", false
9288
}
9389

@@ -108,7 +104,7 @@ func (a *MutatorIDToken) tokenFromCache(config *CredentialsIDTokenConfig, sessio
108104
}
109105

110106
func (a *MutatorIDToken) tokenToCache(config *CredentialsIDTokenConfig, session *authn.AuthenticationSession, claims []byte, ttl time.Duration, expiresAt time.Time, token string) {
111-
if !a.tokenCacheEnabled {
107+
if !config.Cache.Enabled {
112108
return
113109
}
114110

@@ -195,7 +191,11 @@ func (a *MutatorIDToken) Validate(config json.RawMessage) error {
195191
}
196192

197193
func (a *MutatorIDToken) Config(config json.RawMessage) (*CredentialsIDTokenConfig, error) {
198-
var c CredentialsIDTokenConfig
194+
c := CredentialsIDTokenConfig{
195+
Cache: IdTokenCacheConfig{
196+
Enabled: true, // default to true
197+
},
198+
}
199199
if err := a.c.MutatorConfig(a.GetID(), config, &c); err != nil {
200200
return nil, NewErrMutatorMisconfigured(a, err)
201201
}
@@ -204,5 +204,29 @@ func (a *MutatorIDToken) Config(config json.RawMessage) (*CredentialsIDTokenConf
204204
c.TTL = "15m"
205205
}
206206

207+
if a.tokenCache == nil {
208+
cost := int64(c.Cache.MaxCost)
209+
if cost == 0 {
210+
cost = 1 << 25
211+
}
212+
213+
cache, err := ristretto.NewCache(&ristretto.Config{
214+
NumCounters: cost * 10,
215+
// Allocate a max
216+
MaxCost: cost,
217+
// This is a best-practice value.
218+
BufferItems: 64,
219+
Cost: func(value interface{}) int64 {
220+
container := value.(*idTokenCacheContainer)
221+
return int64(len(container.Token))
222+
},
223+
})
224+
225+
if err != nil {
226+
return nil, err
227+
}
228+
a.tokenCache = cache
229+
}
230+
207231
return &c, nil
208232
}

pipeline/mutate/mutator_id_token_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,8 @@ func BenchmarkMutatorIDToken(b *testing.B) {
386386
} {
387387
b.Run("alg="+alg, func(b *testing.B) {
388388
for _, enableCache := range []bool{true, false} {
389-
a.(*MutatorIDToken).SetCaching(enableCache)
390389
b.Run(fmt.Sprintf("cache=%v", enableCache), func(b *testing.B) {
390+
conf.SetForTest(b, "mutators.id_token.config.cache.enabled", true)
391391
var tc idTokenTestCase
392392
var config []byte
393393

spec/config.schema.json

+19
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,25 @@
11401140
"pattern": "^[0-9]+(ns|us|ms|s|m|h)$",
11411141
"default": "15m",
11421142
"examples": ["1h", "1m", "30s"]
1143+
},
1144+
"cache": {
1145+
"additionalProperties": false,
1146+
"type": "object",
1147+
"properties": {
1148+
"enabled": {
1149+
"title": "Enabled",
1150+
"type": "boolean",
1151+
"default": true,
1152+
"examples": [false, true],
1153+
"description": "En-/disables this component."
1154+
},
1155+
"max_cost": {
1156+
"type": "integer",
1157+
"default": 33554432,
1158+
"title": "Maximum Cached Cost",
1159+
"description": "Max cost to cache."
1160+
}
1161+
}
11431162
}
11441163
},
11451164
"additionalProperties": false

0 commit comments

Comments
 (0)