From 51d7f794227868b2899079cd60fe38f30bd013a4 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 27 Feb 2026 12:08:26 +0100 Subject: [PATCH 1/4] fix(cas-redirection): Avoid returning URL when CAS is not valid Signed-off-by: Javier Rodriguez --- app/controlplane/cmd/wire_gen.go | 2 +- app/controlplane/internal/server/grpc.go | 2 +- app/controlplane/internal/service/casredirect.go | 11 +++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index 843d62557..525e088a2 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -215,7 +215,7 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l integrationsService := service.NewIntegrationsService(integrationUseCase, workflowUseCase, availablePlugins, v5...) organizationService := service.NewOrganizationService(membershipUseCase, organizationUseCase, v5...) casBackendService := service.NewCASBackendService(casBackendUseCase, providers, v5...) - casRedirectService, err := service.NewCASRedirectService(casMappingUseCase, casCredentialsUseCase, bootstrap_CASServer, v5...) + casRedirectService, err := service.NewCASRedirectService(casMappingUseCase, casCredentialsUseCase, casBackendUseCase, bootstrap_CASServer, v5...) if err != nil { cleanup() return nil, nil, err diff --git a/app/controlplane/internal/server/grpc.go b/app/controlplane/internal/server/grpc.go index 70dcb936b..39c953b3e 100644 --- a/app/controlplane/internal/server/grpc.go +++ b/app/controlplane/internal/server/grpc.go @@ -97,7 +97,7 @@ type Opts struct { var ( currentUserSkipRegexp = regexp.MustCompile("(controlplane.v1.AttestationService/.*|controlplane.v1.StatusService/.*|controlplane.v1.ReferrerService/DiscoverPublicShared|controlplane.v1.AttestationStateService|controlplane.v1.SigningService)") fullyConfiguredOrgSkipRegexp = regexp.MustCompile("controlplane.v1.OCIRepositoryService/.*|controlplane.v1.ContextService/Current|/controlplane.v1.OrganizationService/.*|/controlplane.v1.AuthService/DeleteAccount|controlplane.v1.CASBackendService/.*|/controlplane.v1.UserService/.*|controlplane.v1.SigningService/.*") - fullyConfiguredCASBackendRequireRegexp = regexp.MustCompile("/controlplane.v1.AttestationService.GetUploadCreds|/controlplane.v1.AttestationService.Init|/controlplane.v1.AttestationService.Store|/controlplane.v1.CASCredentialsService.Get") + fullyConfiguredCASBackendRequireRegexp = regexp.MustCompile("/controlplane.v1.AttestationService.GetUploadCreds|/controlplane.v1.AttestationService.Init|/controlplane.v1.AttestationService.Store|/controlplane.v1.CASCredentialsService.Get|/controlplane.v1.CASRedirectService/DownloadRedirect") allowListSkipRegexp = regexp.MustCompile("controlplane.v1.ContextService/Current|/controlplane.v1.AuthService/DeleteAccount") robotAccountRequireRegexp = regexp.MustCompile("controlplane.v1.AttestationService/.*|controlplane.v1.AttestationStateService/.*|controlplane.v1.SigningService/GenerateSigningCert") allButOrganizationOperationsSkipRegexp = regexp.MustCompile("/controlplane.v1.OrganizationService/Create|/controlplane.v1.UserService/ListMemberships|/controlplane.v1.ContextService/Current|/controlplane.v1.AuthService/DeleteAccount") diff --git a/app/controlplane/internal/service/casredirect.go b/app/controlplane/internal/service/casredirect.go index 9757b0193..2978eb244 100644 --- a/app/controlplane/internal/service/casredirect.go +++ b/app/controlplane/internal/service/casredirect.go @@ -1,5 +1,5 @@ // -// Copyright 2023 The Chainloop Authors. +// Copyright 2023-2026 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -49,10 +49,11 @@ type CASRedirectService struct { casMappingUC *biz.CASMappingUseCase casCredsUseCase *biz.CASCredentialsUseCase + casBackendUC *biz.CASBackendUseCase casServerConf *conf.Bootstrap_CASServer } -func NewCASRedirectService(casmUC *biz.CASMappingUseCase, casCredsUC *biz.CASCredentialsUseCase, conf *conf.Bootstrap_CASServer, opts ...NewOpt) (*CASRedirectService, error) { +func NewCASRedirectService(casmUC *biz.CASMappingUseCase, casCredsUC *biz.CASCredentialsUseCase, casBackendUC *biz.CASBackendUseCase, conf *conf.Bootstrap_CASServer, opts ...NewOpt) (*CASRedirectService, error) { if conf == nil || conf.GetDownloadUrl() == "" { return nil, errors.New("CASServer.downloadURL configuration is missing") } @@ -62,6 +63,7 @@ func NewCASRedirectService(casmUC *biz.CASMappingUseCase, casCredsUC *biz.CASCre casMappingUC: casmUC, casCredsUseCase: casCredsUC, casServerConf: conf, + casBackendUC: casBackendUC, }, nil } @@ -110,6 +112,11 @@ func (s *CASRedirectService) GetDownloadURL(ctx context.Context, req *pb.GetDown return nil, kerrors.NotFound("not found", "CAS backend is inline") } + // check if the backend is on a valid state, if not return an error + if backend.ValidationStatus != biz.CASBackendValidationOK { + return nil, pb.ErrorCasBackendErrorReasonInvalid("CAS Storage is on a invalid state and can't download artifacts, please fix it before attempting it again") + } + // Create an URL to download the artifact from the CAS backend downloadBase, err := url.Parse(s.casServerConf.GetDownloadUrl()) if err != nil { From f56ffa97dfbba9d6f8716a87d67c326ff7d9d430 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 27 Feb 2026 12:30:25 +0100 Subject: [PATCH 2/4] code suggestions Signed-off-by: Javier Rodriguez --- app/controlplane/cmd/wire_gen.go | 2 +- app/controlplane/internal/service/casredirect.go | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index 525e088a2..843d62557 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -215,7 +215,7 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l integrationsService := service.NewIntegrationsService(integrationUseCase, workflowUseCase, availablePlugins, v5...) organizationService := service.NewOrganizationService(membershipUseCase, organizationUseCase, v5...) casBackendService := service.NewCASBackendService(casBackendUseCase, providers, v5...) - casRedirectService, err := service.NewCASRedirectService(casMappingUseCase, casCredentialsUseCase, casBackendUseCase, bootstrap_CASServer, v5...) + casRedirectService, err := service.NewCASRedirectService(casMappingUseCase, casCredentialsUseCase, bootstrap_CASServer, v5...) if err != nil { cleanup() return nil, nil, err diff --git a/app/controlplane/internal/service/casredirect.go b/app/controlplane/internal/service/casredirect.go index 2978eb244..0c2047d4b 100644 --- a/app/controlplane/internal/service/casredirect.go +++ b/app/controlplane/internal/service/casredirect.go @@ -49,11 +49,10 @@ type CASRedirectService struct { casMappingUC *biz.CASMappingUseCase casCredsUseCase *biz.CASCredentialsUseCase - casBackendUC *biz.CASBackendUseCase casServerConf *conf.Bootstrap_CASServer } -func NewCASRedirectService(casmUC *biz.CASMappingUseCase, casCredsUC *biz.CASCredentialsUseCase, casBackendUC *biz.CASBackendUseCase, conf *conf.Bootstrap_CASServer, opts ...NewOpt) (*CASRedirectService, error) { +func NewCASRedirectService(casmUC *biz.CASMappingUseCase, casCredsUC *biz.CASCredentialsUseCase, conf *conf.Bootstrap_CASServer, opts ...NewOpt) (*CASRedirectService, error) { if conf == nil || conf.GetDownloadUrl() == "" { return nil, errors.New("CASServer.downloadURL configuration is missing") } @@ -63,7 +62,6 @@ func NewCASRedirectService(casmUC *biz.CASMappingUseCase, casCredsUC *biz.CASCre casMappingUC: casmUC, casCredsUseCase: casCredsUC, casServerConf: conf, - casBackendUC: casBackendUC, }, nil } @@ -114,7 +112,7 @@ func (s *CASRedirectService) GetDownloadURL(ctx context.Context, req *pb.GetDown // check if the backend is on a valid state, if not return an error if backend.ValidationStatus != biz.CASBackendValidationOK { - return nil, pb.ErrorCasBackendErrorReasonInvalid("CAS Storage is on a invalid state and can't download artifacts, please fix it before attempting it again") + return nil, pb.ErrorCasBackendErrorReasonInvalid("CAS Storage is in a invalid state and can't download artifacts, please fix it before attempting it again") } // Create an URL to download the artifact from the CAS backend From 0fbf481b7aae62681301c09f2025e39c59702a75 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 27 Feb 2026 12:35:07 +0100 Subject: [PATCH 3/4] fix typo Signed-off-by: Javier Rodriguez --- app/controlplane/internal/service/casredirect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controlplane/internal/service/casredirect.go b/app/controlplane/internal/service/casredirect.go index 0c2047d4b..431c5a6a8 100644 --- a/app/controlplane/internal/service/casredirect.go +++ b/app/controlplane/internal/service/casredirect.go @@ -112,7 +112,7 @@ func (s *CASRedirectService) GetDownloadURL(ctx context.Context, req *pb.GetDown // check if the backend is on a valid state, if not return an error if backend.ValidationStatus != biz.CASBackendValidationOK { - return nil, pb.ErrorCasBackendErrorReasonInvalid("CAS Storage is in a invalid state and can't download artifacts, please fix it before attempting it again") + return nil, pb.ErrorCasBackendErrorReasonInvalid("CAS Storage is in an invalid state and can't download artifacts, please fix it before attempting it again") } // Create an URL to download the artifact from the CAS backend From 95497c8bf1e223a6d91bbb54c7ac517a6222f6b8 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 27 Feb 2026 12:41:25 +0100 Subject: [PATCH 4/4] remove regex Signed-off-by: Javier Rodriguez --- app/controlplane/internal/server/grpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controlplane/internal/server/grpc.go b/app/controlplane/internal/server/grpc.go index 39c953b3e..70dcb936b 100644 --- a/app/controlplane/internal/server/grpc.go +++ b/app/controlplane/internal/server/grpc.go @@ -97,7 +97,7 @@ type Opts struct { var ( currentUserSkipRegexp = regexp.MustCompile("(controlplane.v1.AttestationService/.*|controlplane.v1.StatusService/.*|controlplane.v1.ReferrerService/DiscoverPublicShared|controlplane.v1.AttestationStateService|controlplane.v1.SigningService)") fullyConfiguredOrgSkipRegexp = regexp.MustCompile("controlplane.v1.OCIRepositoryService/.*|controlplane.v1.ContextService/Current|/controlplane.v1.OrganizationService/.*|/controlplane.v1.AuthService/DeleteAccount|controlplane.v1.CASBackendService/.*|/controlplane.v1.UserService/.*|controlplane.v1.SigningService/.*") - fullyConfiguredCASBackendRequireRegexp = regexp.MustCompile("/controlplane.v1.AttestationService.GetUploadCreds|/controlplane.v1.AttestationService.Init|/controlplane.v1.AttestationService.Store|/controlplane.v1.CASCredentialsService.Get|/controlplane.v1.CASRedirectService/DownloadRedirect") + fullyConfiguredCASBackendRequireRegexp = regexp.MustCompile("/controlplane.v1.AttestationService.GetUploadCreds|/controlplane.v1.AttestationService.Init|/controlplane.v1.AttestationService.Store|/controlplane.v1.CASCredentialsService.Get") allowListSkipRegexp = regexp.MustCompile("controlplane.v1.ContextService/Current|/controlplane.v1.AuthService/DeleteAccount") robotAccountRequireRegexp = regexp.MustCompile("controlplane.v1.AttestationService/.*|controlplane.v1.AttestationStateService/.*|controlplane.v1.SigningService/GenerateSigningCert") allButOrganizationOperationsSkipRegexp = regexp.MustCompile("/controlplane.v1.OrganizationService/Create|/controlplane.v1.UserService/ListMemberships|/controlplane.v1.ContextService/Current|/controlplane.v1.AuthService/DeleteAccount")