Skip to content

Commit dddea72

Browse files
authored
agent: fix JWT cache (#4309)
The JWT cache in the agent has a bug whereby we do not distinguish between audience sets {"ab", "cd"} and {"a", "bcd"} (for example) due to the way we build the cache keys. Fix this. Signed-off-by: Carlo Teubner <[email protected]>
1 parent f9a8db5 commit dddea72

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

pkg/agent/manager/cache/jwt_cache.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,19 @@ func (c *JWTSVIDCache) SetJWTSVID(spiffeID spiffeid.ID, audience []string, svid
4242
func jwtSVIDKey(spiffeID spiffeid.ID, audience []string) string {
4343
h := sha256.New()
4444

45+
// Form the cache key as the SHA-256 hash of the SPIFFE ID and all the audiences.
46+
// In order to avoid ambiguities, we will write a nul byte to the hash function after each data
47+
// item.
48+
4549
// duplicate and sort the audience slice
4650
audience = append([]string(nil), audience...)
4751
sort.Strings(audience)
4852

4953
_, _ = io.WriteString(h, spiffeID.String())
54+
h.Write([]byte{0})
5055
for _, a := range audience {
5156
_, _ = io.WriteString(h, a)
57+
h.Write([]byte{0})
5258
}
5359

5460
return base64.StdEncoding.EncodeToString(h.Sum(nil))

pkg/agent/manager/cache/jwt_cache_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/stretchr/testify/assert"
1010
)
1111

12-
func TestJWTSVIDCache(t *testing.T) {
12+
func TestJWTSVIDCacheBasic(t *testing.T) {
1313
now := time.Now()
1414
expected := &client.JWTSVID{Token: "X", IssuedAt: now, ExpiresAt: now.Add(time.Second)}
1515

@@ -28,3 +28,23 @@ func TestJWTSVIDCache(t *testing.T) {
2828
assert.True(t, ok)
2929
assert.Equal(t, expected, actual)
3030
}
31+
32+
func TestJWTSVIDCacheKeyHashing(t *testing.T) {
33+
spiffeID := spiffeid.RequireFromString("spiffe://example.org/blog")
34+
now := time.Now()
35+
expected := &client.JWTSVID{Token: "X", IssuedAt: now, ExpiresAt: now.Add(time.Second)}
36+
37+
cache := NewJWTSVIDCache()
38+
cache.SetJWTSVID(spiffeID, []string{"ab", "cd"}, expected)
39+
40+
// JWT is cached
41+
actual, ok := cache.GetJWTSVID(spiffeID, []string{"ab", "cd"})
42+
assert.True(t, ok)
43+
assert.Equal(t, expected, actual)
44+
45+
// JWT is not cached, despite concatenation of audiences (in lexicographical order) matching
46+
// that of the cached item
47+
actual, ok = cache.GetJWTSVID(spiffeID, []string{"a", "bcd"})
48+
assert.False(t, ok)
49+
assert.Nil(t, actual)
50+
}

0 commit comments

Comments
 (0)