Skip to content

Commit 06545bc

Browse files
committed
fix: add logging to authentication errors in controller and router
Log authentication failures in the controller service (Listen, GetLease, RequestLease, ReleaseLease, ListLeases) and in the Auth helpers (AuthClient, AuthExporter) which cover all ClientService call sites. Also log passphrase authentication failures in the Python exporter's PassphraseInterceptor, where the logger was defined but never called. Additionally fix the router JWT validation error code from codes.InvalidArgument to codes.Unauthenticated, which is the semantically correct code for a failed authentication. Fixes #811
1 parent f19e473 commit 06545bc

4 files changed

Lines changed: 31 additions & 3 deletions

File tree

controller/internal/service/auth/auth.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"google.golang.org/grpc/status"
1212
"k8s.io/apiserver/pkg/authorization/authorizer"
1313
kclient "sigs.k8s.io/controller-runtime/pkg/client"
14+
"sigs.k8s.io/controller-runtime/pkg/log"
1415
)
1516

1617
type Auth struct {
@@ -35,6 +36,8 @@ func NewAuth(
3536
}
3637

3738
func (s *Auth) AuthClient(ctx context.Context, namespace string) (*jumpstarterdevv1alpha1.Client, error) {
39+
logger := log.FromContext(ctx)
40+
3841
jclient, err := oidc.VerifyClientObjectToken(
3942
ctx,
4043
s.authn,
@@ -44,17 +47,22 @@ func (s *Auth) AuthClient(ctx context.Context, namespace string) (*jumpstarterde
4447
)
4548

4649
if err != nil {
50+
logger.Info("unable to authenticate client", "error", err.Error())
4751
return nil, err
4852
}
4953

5054
if namespace != jclient.Namespace {
51-
return nil, status.Error(codes.PermissionDenied, "namespace mismatch")
55+
err := status.Error(codes.PermissionDenied, "namespace mismatch")
56+
logger.Info("unable to authenticate client", "error", err.Error())
57+
return nil, err
5258
}
5359

5460
return jclient, nil
5561
}
5662

5763
func (s *Auth) AuthExporter(ctx context.Context, namespace string) (*jumpstarterdevv1alpha1.Exporter, error) {
64+
logger := log.FromContext(ctx)
65+
5866
jexporter, err := oidc.VerifyExporterObjectToken(
5967
ctx,
6068
s.authn,
@@ -64,11 +72,14 @@ func (s *Auth) AuthExporter(ctx context.Context, namespace string) (*jumpstarter
6472
)
6573

6674
if err != nil {
75+
logger.Info("unable to authenticate exporter", "error", err.Error())
6776
return nil, err
6877
}
6978

7079
if namespace != jexporter.Namespace {
71-
return nil, status.Error(codes.PermissionDenied, "namespace mismatch")
80+
err := status.Error(codes.PermissionDenied, "namespace mismatch")
81+
logger.Info("unable to authenticate exporter", "error", err.Error())
82+
return nil, err
7283
}
7384

7485
return jexporter, nil

controller/internal/service/controller_service.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ func (s *ControllerService) Listen(req *pb.ListenRequest, stream pb.ControllerSe
524524

525525
exporter, err := s.authenticateExporter(ctx)
526526
if err != nil {
527+
logger.Info("unable to authenticate exporter", "error", err.Error())
527528
return err
528529
}
529530

@@ -898,8 +899,11 @@ func (s *ControllerService) GetLease(
898899
ctx context.Context,
899900
req *pb.GetLeaseRequest,
900901
) (*pb.GetLeaseResponse, error) {
902+
logger := log.FromContext(ctx)
903+
901904
client, err := s.authenticateClient(ctx)
902905
if err != nil {
906+
logger.Info("unable to authenticate client", "error", err.Error())
903907
return nil, err
904908
}
905909

@@ -977,8 +981,11 @@ func (s *ControllerService) RequestLease(
977981
ctx context.Context,
978982
req *pb.RequestLeaseRequest,
979983
) (*pb.RequestLeaseResponse, error) {
984+
logger := log.FromContext(ctx)
985+
980986
client, err := s.authenticateClient(ctx)
981987
if err != nil {
988+
logger.Info("unable to authenticate client", "error", err.Error())
982989
return nil, err
983990
}
984991

@@ -1031,8 +1038,11 @@ func (s *ControllerService) ReleaseLease(
10311038
ctx context.Context,
10321039
req *pb.ReleaseLeaseRequest,
10331040
) (*pb.ReleaseLeaseResponse, error) {
1041+
logger := log.FromContext(ctx)
1042+
10341043
jclient, err := s.authenticateClient(ctx)
10351044
if err != nil {
1045+
logger.Info("unable to authenticate client", "error", err.Error())
10361046
return nil, err
10371047
}
10381048

@@ -1062,8 +1072,11 @@ func (s *ControllerService) ListLeases(
10621072
ctx context.Context,
10631073
req *pb.ListLeasesRequest,
10641074
) (*pb.ListLeasesResponse, error) {
1075+
logger := log.FromContext(ctx)
1076+
10651077
jclient, err := s.authenticateClient(ctx)
10661078
if err != nil {
1079+
logger.Info("unable to authenticate client", "error", err.Error())
10671080
return nil, err
10681081
}
10691082

controller/internal/service/router_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (s *RouterService) authenticate(ctx context.Context) (string, error) {
7171
)
7272

7373
if err != nil || !parsed.Valid {
74-
return "", status.Errorf(codes.InvalidArgument, "invalid jwt token")
74+
return "", status.Errorf(codes.Unauthenticated, "invalid jwt token")
7575
}
7676

7777
return parsed.Claims.GetSubject()

python/packages/jumpstarter/jumpstarter/exporter/auth.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ async def intercept_service(self, continuation, handler_call_details):
2525
provided = metadata.get(PASSPHRASE_METADATA_KEY)
2626

2727
if provided is None or not hmac.compare_digest(provided, self._passphrase):
28+
logger.warning(
29+
"authentication failed: invalid or missing passphrase for method %s",
30+
handler_call_details.method,
31+
)
2832
# Resolve the real handler to preserve the RPC type, then reject
2933
handler = await continuation(handler_call_details)
3034
if handler is None:

0 commit comments

Comments
 (0)