Skip to content

Commit

Permalink
topdown: jwt cache (#7274)
Browse files Browse the repository at this point in the history
Adding cache to `io.jwt` token verification built-ins

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
  • Loading branch information
johanfylling authored Jan 24, 2025
1 parent 211e95d commit 6e83f2a
Show file tree
Hide file tree
Showing 10 changed files with 1,319 additions and 208 deletions.
13 changes: 7 additions & 6 deletions docs/content/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -864,12 +864,13 @@ It also represents the configuration of the inter-query _value_ cache that built
this cache is utilized by the `regex` and `glob` built-in functions for compiled regex and glob match patterns
respectively, and the `json.schema_match` built-in function for compiled JSON schemas.

| Field | Type | Required | Description |
|--------------------------------------------------------------------------| --- | --- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `caching.inter_query_builtin_cache.max_size_bytes` | `int64` | No | Inter-query cache size limit in bytes. OPA will drop old items from the cache if this limit is exceeded. By default, no limit is set. |
| `caching.inter_query_builtin_cache.forced_eviction_threshold_percentage` | `int64` | No | Threshold limit configured as percentage of `caching.inter_query_builtin_cache.max_size_bytes`, when exceeded OPA will start dropping old items permaturely. By default, set to `100`. |
| `caching.inter_query_builtin_cache.stale_entry_eviction_period_seconds` | `int64` | No | Stale entry eviction period in seconds. OPA will drop expired items from the cache every `stale_entry_eviction_period_seconds`. By default, set to `0` indicating stale entry eviction is disabled. |
| `caching.inter_query_builtin_value_cache.max_num_entries` | `int` | No | Maximum number of entries in the Inter-query value cache. OPA will drop random items from the cache if this limit is exceeded. By default, set to `0` indicating unlimited size. |
| Field | Type | Required | Description |
|--------------------------------------------------------------------------|---------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `caching.inter_query_builtin_cache.max_size_bytes` | `int64` | No | Inter-query cache size limit in bytes. OPA will drop old items from the cache if this limit is exceeded. By default, no limit is set. |
| `caching.inter_query_builtin_cache.forced_eviction_threshold_percentage` | `int64` | No | Threshold limit configured as percentage of `caching.inter_query_builtin_cache.max_size_bytes`, when exceeded OPA will start dropping old items permaturely. By default, set to `100`. |
| `caching.inter_query_builtin_cache.stale_entry_eviction_period_seconds` | `int64` | No | Stale entry eviction period in seconds. OPA will drop expired items from the cache every `stale_entry_eviction_period_seconds`. By default, set to `0` indicating stale entry eviction is disabled. |
| `caching.inter_query_builtin_value_cache.max_num_entries` | `int` | No | Maximum number of entries in the Inter-query value cache. OPA will drop random items from the cache if this limit is exceeded. By default, set to `0` indicating unlimited size. |
| `caching.inter_query_builtin_value_cache.named.io_jwt.max_num_entries` | `int` | No | Maximum number of entries in the `io_jwt` cache, used by the [`io.jwt` token verification](../policy-reference/#tokens) built-in functions. OPA will drop random items from the cache if this limit is exceeded. By default, this cache is disabled. |

## Distributed tracing

Expand Down
45 changes: 39 additions & 6 deletions v1/plugins/discovery/discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1717,7 +1717,14 @@ func TestReconfigureWithLocalOverride(t *testing.T) {
"decision_logs": {"console": true},
"nd_builtin_cache": false,
"distributed_tracing": {"type": "grpc"},
"caching": {"inter_query_builtin_cache": {"max_size_bytes": 10000000, "forced_eviction_threshold_percentage": 90}}
"caching": {
"inter_query_builtin_cache": {"max_size_bytes": 10000000, "forced_eviction_threshold_percentage": 90},
"inter_query_builtin_value_cache": {
"named": {
"io_jwt": {"max_num_entries": 55}
}
}
}
}`)

manager, err := plugins.New(bootConfigRaw, "test-id", inmem.New())
Expand Down Expand Up @@ -1877,7 +1884,14 @@ func TestReconfigureWithLocalOverride(t *testing.T) {
serviceBundle = makeDataBundle(7, `
{
"config": {
"caching": {"inter_query_builtin_cache": {"max_size_bytes": 200, "stale_entry_eviction_period_seconds": 10, "forced_eviction_threshold_percentage": 200}}
"caching": {
"inter_query_builtin_cache": {"max_size_bytes": 200, "stale_entry_eviction_period_seconds": 10, "forced_eviction_threshold_percentage": 200},
"inter_query_builtin_value_cache": {
"named": {
"io_jwt": {"max_num_entries": 10}
}
}
}
}
}
`)
Expand All @@ -1888,7 +1902,11 @@ func TestReconfigureWithLocalOverride(t *testing.T) {
t.Fatal("Expected to find status, found nil")
}

expectedOverriddenKeys := []string{"caching.inter_query_builtin_cache.max_size_bytes", "caching.inter_query_builtin_cache.forced_eviction_threshold_percentage"}
expectedOverriddenKeys := []string{
"caching.inter_query_builtin_cache.max_size_bytes",
"caching.inter_query_builtin_cache.forced_eviction_threshold_percentage",
"caching.inter_query_builtin_value_cache.named.io_jwt.max_num_entries",
}
for _, k := range expectedOverriddenKeys {
if !strings.Contains(disco.status.Message, k) {
t.Fatalf("expected key \"%v\" to be overridden", k)
Expand All @@ -1908,9 +1926,24 @@ func TestReconfigureWithLocalOverride(t *testing.T) {
*threshold = 90
maxNumEntriesInterQueryValueCache := new(int)
*maxNumEntriesInterQueryValueCache = 0

expectedCacheConf := &cache.Config{InterQueryBuiltinCache: cache.InterQueryBuiltinCacheConfig{MaxSizeBytes: maxSize, StaleEntryEvictionPeriodSeconds: period, ForcedEvictionThresholdPercentage: threshold},
InterQueryBuiltinValueCache: cache.InterQueryBuiltinValueCacheConfig{MaxNumEntries: maxNumEntriesInterQueryValueCache}}
maxNumEntriesJWTValueCache := new(int)
*maxNumEntriesJWTValueCache = 55

expectedCacheConf := &cache.Config{
InterQueryBuiltinCache: cache.InterQueryBuiltinCacheConfig{
MaxSizeBytes: maxSize,
StaleEntryEvictionPeriodSeconds: period,
ForcedEvictionThresholdPercentage: threshold,
},
InterQueryBuiltinValueCache: cache.InterQueryBuiltinValueCacheConfig{
MaxNumEntries: maxNumEntriesInterQueryValueCache,
NamedCacheConfigs: map[string]*cache.NamedValueCacheConfig{
"io_jwt": {
MaxNumEntries: maxNumEntriesJWTValueCache,
},
},
},
}

if !reflect.DeepEqual(cacheConf, expectedCacheConf) {
t.Fatalf("want %v got %v", expectedCacheConf, cacheConf)
Expand Down
Loading

0 comments on commit 6e83f2a

Please sign in to comment.