Skip to content

Commit 315ccaa

Browse files
committed
[Bugfix] Fix JWT Secret Tail characters
1 parent b791e3a commit 315ccaa

29 files changed

+787
-207
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- (Feature) (Platform) Login & Logout Endpoints
1717
- (Feature) (Platform) OpenID Integration
1818
- (Maintenance) Operator Labeling Skip
19+
- (Bugfix) Align JWT Discovery
1920

2021
## [1.2.48](https://github.com/arangodb/kube-arangodb/tree/1.2.48) (2025-05-08)
2122
- (Maintenance) Extend Documentation

cmd/admin.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import (
3838
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
3939

4040
"github.com/arangodb-helper/go-certificates"
41-
"github.com/arangodb/go-driver/jwt"
4241
"github.com/arangodb/go-driver/v2/connection"
4342

4443
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
@@ -51,6 +50,7 @@ import (
5150
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
5251
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/generic"
5352
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
53+
"github.com/arangodb/kube-arangodb/pkg/util/token"
5454
)
5555

5656
const (
@@ -405,16 +405,22 @@ func getJWTTokenFromSecrets(ctx context.Context, secrets generic.ReadClient[*cor
405405
ctxChild, cancel := globals.GetGlobalTimeouts().Kubernetes().WithTimeout(ctx)
406406
defer cancel()
407407

408-
token, err := k8sutil.GetTokenSecret(ctxChild, secrets, name)
408+
secret, err := k8sutil.GetTokenSecret(ctxChild, secrets, name)
409409
if err != nil {
410410
return nil, errors.WithMessage(err, fmt.Sprintf("failed to get secret \"%s\"", name))
411411
}
412412

413-
bearerToken, err := jwt.CreateArangodJwtAuthorizationHeader(token, "kube-arangodb")
413+
authz, err := token.NewClaims().With(
414+
token.WithDefaultClaims(),
415+
token.WithServerID("kube-arangodb"),
416+
token.WithAllowedPaths("/_api/version"),
417+
).Sign(secret)
414418
if err != nil {
415419
return nil, errors.WithMessage(err, fmt.Sprintf("failed to create bearer token from secret \"%s\"", name))
416420
}
417421

422+
bearerToken := fmt.Sprintf("bearer %s", authz)
423+
418424
return JWTAuthentication{key: "Authorization", value: bearerToken}, nil
419425
}
420426

integrations/authentication/v1/cache.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,13 @@ import (
2929
"time"
3030

3131
"github.com/arangodb/kube-arangodb/pkg/util"
32+
"github.com/arangodb/kube-arangodb/pkg/util/token"
3233
)
3334

3435
const MaxSize = 128
3536

36-
type tokens struct {
37-
signingToken []byte
38-
39-
validationTokens [][]byte
40-
}
41-
42-
func newCache(cfg Configuration) func(ctx context.Context) (*tokens, time.Duration, error) {
43-
return func(ctx context.Context) (*tokens, time.Duration, error) {
37+
func newCache(cfg Configuration) func(ctx context.Context) (token.Secret, time.Duration, error) {
38+
return func(ctx context.Context) (token.Secret, time.Duration, error) {
4439
files, err := os.ReadDir(cfg.Path)
4540
if err != nil {
4641
return nil, 0, err
@@ -87,9 +82,8 @@ func newCache(cfg Configuration) func(ctx context.Context) (*tokens, time.Durati
8782
data[id] = ts[keys[id]]
8883
}
8984

90-
return &tokens{
91-
signingToken: ts[keys[0]],
92-
validationTokens: data,
93-
}, cfg.TTL, nil
85+
return token.NewSecretSet(token.NewSecret(ts[keys[0]]), util.FormatList(data, func(a []byte) token.Secret {
86+
return token.NewSecret(a)
87+
})...), cfg.TTL, nil
9488
}
9589
}

integrations/authentication/v1/implementation.go

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ type implementation struct {
9191
cfg Configuration
9292

9393
userClient cache.Object[arangodb.Requests]
94-
cache cache.Object[*tokens]
94+
cache cache.Object[token.Secret]
9595
}
9696

9797
func (i *implementation) Name() string {
@@ -189,16 +189,12 @@ func (i *implementation) CreateToken(ctx context.Context, request *pbAuthenticat
189189
duration = v
190190
}
191191

192-
// Token is validated, we can continue with creation
193-
secret := cache.signingToken
194-
195-
signedToken, err := token.New(secret,
196-
token.NewClaims().With(token.WithDefaultClaims(),
197-
token.WithCurrentIAT(),
198-
token.WithDuration(duration),
199-
token.WithUsername(user),
200-
token.WithRoles(request.GetRoles()...)),
201-
)
192+
signedToken, err := token.NewClaims().With(
193+
token.WithDefaultClaims(),
194+
token.WithCurrentIAT(),
195+
token.WithDuration(duration),
196+
token.WithUsername(user),
197+
token.WithRoles(request.GetRoles()...)).Sign(cache)
202198
if err != nil {
203199
return nil, err
204200
}
@@ -346,24 +342,25 @@ func (i *implementation) Logout(ctx context.Context, req *pbAuthenticationV1.Log
346342
return &pbSharedV1.Empty{}, nil
347343
}
348344

349-
func (i *implementation) extractTokenDetails(cache *tokens, t string) (string, []string, time.Duration, error) {
345+
func (i *implementation) extractTokenDetails(cache token.Secret, t string) (string, []string, time.Duration, error) {
350346
// Let's check if token is signed properly
351-
352-
p, err := token.ParseWithAny(t, cache.validationTokens...)
347+
p, err := cache.Validate(t)
353348
if err != nil {
354349
return "", nil, 0, err
355350
}
356351

357352
user := DefaultAdminUser
358-
if v, ok := p[token.ClaimPreferredUsername]; ok {
353+
if v, ok := p.Claims()[token.ClaimPreferredUsername]; ok {
359354
if s, ok := v.(string); ok {
360355
user = s
361356
}
362357
}
363358

364359
duration := DefaultTokenMaxTTL
365360

366-
if v, ok := p[token.ClaimEXP]; ok {
361+
claims := p.Claims()
362+
363+
if v, ok := claims[token.ClaimEXP]; ok {
367364
switch o := v.(type) {
368365
case int64:
369366
duration = time.Until(time.Unix(o, 0))
@@ -374,7 +371,7 @@ func (i *implementation) extractTokenDetails(cache *tokens, t string) (string, [
374371

375372
var roles []string
376373

377-
if v, ok := p[token.ClaimRoles]; ok {
374+
if v, ok := claims[token.ClaimRoles]; ok {
378375
switch o := v.(type) {
379376
case []string:
380377
roles = o

pkg/api/api.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/auth.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/jwt.go

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/deployment/context_impl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ func (d *Deployment) getJWTToken() (string, bool) {
295295
func (d *Deployment) GetSyncServerClient(ctx context.Context, group api.ServerGroup, id string) (client.API, error) {
296296
// Fetch monitoring token
297297
secretName := d.GetSpec().Sync.Monitoring.GetTokenSecretName()
298-
monitoringToken, err := k8sutil.GetTokenSecret(ctx, d.GetCachedStatus().Secret().V1().Read(), secretName)
298+
monitoringToken, err := k8sutil.GetTokenSecretString(ctx, d.GetCachedStatus().Secret().V1().Read(), secretName)
299299
if err != nil {
300300
d.log.Err(err).Str("secret-name", secretName).Debug("Failed to get sync monitoring secret")
301301
return nil, errors.WithStack(err)

pkg/deployment/deployment_pod_sync_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -227,7 +227,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
227227
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
228228

229229
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
230-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
230+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
231231
require.NoError(t, err)
232232

233233
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -316,7 +316,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
316316

317317
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
318318
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
319-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
319+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
320320
require.NoError(t, err)
321321

322322
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -420,7 +420,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
420420

421421
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
422422
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
423-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
423+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
424424
require.NoError(t, err)
425425

426426
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -521,7 +521,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
521521

522522
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
523523
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
524-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
524+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
525525
require.NoError(t, err)
526526

527527
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -622,7 +622,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
622622

623623
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
624624
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
625-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
625+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
626626
require.NoError(t, err)
627627

628628
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -726,7 +726,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
726726

727727
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
728728
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
729-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
729+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
730730
require.NoError(t, err)
731731

732732
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -825,7 +825,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
825825

826826
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
827827
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
828-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
828+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
829829
require.NoError(t, err)
830830

831831
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -931,7 +931,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
931931

932932
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
933933
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
934-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
934+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
935935
require.NoError(t, err)
936936

937937
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -1047,7 +1047,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
10471047

10481048
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
10491049
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
1050-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
1050+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
10511051
require.NoError(t, err)
10521052

10531053
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -1161,7 +1161,7 @@ func TestEnsurePod_Sync_Master(t *testing.T) {
11611161

11621162
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
11631163
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
1164-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
1164+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
11651165
require.NoError(t, err)
11661166

11671167
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -1272,7 +1272,7 @@ func TestEnsurePod_Sync_Worker(t *testing.T) {
12721272
testCase.createTestPodData(deployment, api.ServerGroupSyncWorkers, firstSyncWorker)
12731273

12741274
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
1275-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
1275+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
12761276
require.NoError(t, err)
12771277

12781278
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)
@@ -1367,7 +1367,7 @@ func TestEnsurePod_Sync_Worker(t *testing.T) {
13671367
testCase.createTestPodData(deployment, api.ServerGroupSyncWorkers, firstSyncWorker)
13681368

13691369
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
1370-
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
1370+
auth, err := k8sutil.GetTokenSecretString(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
13711371
require.NoError(t, err)
13721372

13731373
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe("", true, "bearer "+auth, shared.ServerPortName)

0 commit comments

Comments
 (0)