@@ -14,6 +14,11 @@ import (
1414 workflowsyncerv2 "github.com/smartcontractkit/chainlink/v2/core/services/workflows/syncer/v2"
1515)
1616
17+ const (
18+ allowListBasedAuthRetryCount = 3
19+ allowListBasedAuthRetryInterval = 3 * time .Second
20+ )
21+
1722// AllowListBasedAuth validates Vault requests against the workflow registry's onchain allowlist.
1823type AllowListBasedAuth interface {
1924 AuthorizeRequest (ctx context.Context , req jsonrpc.Request [json.RawMessage ]) (* AuthResult , error )
@@ -22,6 +27,8 @@ type AllowListBasedAuth interface {
2227type allowListBasedAuth struct {
2328 workflowRegistrySyncer workflowsyncerv2.WorkflowRegistrySyncer
2429 lggr logger.Logger
30+ retryCount int
31+ retryInterval time.Duration
2532}
2633
2734// AuthorizeRequest authorizes a request using AllowListBasedAuth.
@@ -43,14 +50,10 @@ func (r *allowListBasedAuth) AuthorizeRequest(ctx context.Context, req jsonrpc.R
4350 r .lggr .Errorw ("AllowListBasedAuth workflowRegistrySyncer is nil" , "method" , req .Method , "requestID" , req .ID )
4451 return nil , errors .New ("internal error: workflowRegistrySyncer is nil" )
4552 }
46- allowedRequests := r .workflowRegistrySyncer .GetAllowlistedRequests (ctx )
47- allowedRequestsStrs := make ([]string , 0 , len (allowedRequests ))
48- for _ , rr := range allowedRequests {
49- allowedReqStr := fmt .Sprintf ("AuthorizedOwner: %s, RequestDigest: %s, ExpiryTimestamp: %d" , rr .Owner .Hex (), hex .EncodeToString (rr .RequestDigest [:]), rr .ExpiryTimestamp )
50- allowedRequestsStrs = append (allowedRequestsStrs , allowedReqStr )
53+ allowlistedRequest , allowedRequestsStrs , err := r .findAllowlistedItemWithRetry (ctx , req , requestDigest , requestDigestBytes32 )
54+ if err != nil {
55+ return nil , err
5156 }
52- r .lggr .Debugw ("AllowListBasedAuth loaded allowlisted requests" , "method" , req .Method , "requestID" , req .ID , "allowedRequests" , allowedRequestsStrs )
53- allowlistedRequest := r .fetchAllowlistedItem (allowedRequests , requestDigestBytes32 )
5457 if allowlistedRequest == nil {
5558 r .lggr .Debugw ("AllowListBasedAuth request digest not allowlisted" ,
5659 "method" , req .Method ,
@@ -75,6 +78,40 @@ func (r *allowListBasedAuth) AuthorizeRequest(ctx context.Context, req jsonrpc.R
7578 }, nil
7679}
7780
81+ func (r * allowListBasedAuth ) findAllowlistedItemWithRetry (ctx context.Context , req jsonrpc.Request [json.RawMessage ], requestDigest string , requestDigestBytes32 [32 ]byte ) (* workflow_registry_wrapper_v2.WorkflowRegistryOwnerAllowlistedRequest , []string , error ) {
82+ for attempt := 0 ; attempt <= r .retryCount ; attempt ++ {
83+ allowedRequests := r .workflowRegistrySyncer .GetAllowlistedRequests (ctx )
84+ allowedRequestsStrs := make ([]string , 0 , len (allowedRequests ))
85+ for _ , rr := range allowedRequests {
86+ allowedReqStr := fmt .Sprintf ("AuthorizedOwner: %s, RequestDigest: %s, ExpiryTimestamp: %d" , rr .Owner .Hex (), hex .EncodeToString (rr .RequestDigest [:]), rr .ExpiryTimestamp )
87+ allowedRequestsStrs = append (allowedRequestsStrs , allowedReqStr )
88+ }
89+ r .lggr .Debugw ("AllowListBasedAuth loaded allowlisted requests" , "method" , req .Method , "requestID" , req .ID , "attempt" , attempt + 1 , "allowedRequests" , allowedRequestsStrs )
90+
91+ allowlistedRequest := r .fetchAllowlistedItem (allowedRequests , requestDigestBytes32 )
92+ if allowlistedRequest != nil {
93+ return allowlistedRequest , allowedRequestsStrs , nil
94+ }
95+ if attempt == r .retryCount {
96+ return nil , allowedRequestsStrs , nil
97+ }
98+
99+ r .lggr .Debugw ("AllowListBasedAuth request digest not yet allowlisted, retrying" ,
100+ "method" , req .Method ,
101+ "requestID" , req .ID ,
102+ "digestHexStr" , requestDigest ,
103+ "attempt" , attempt + 1 ,
104+ "maxAttempts" , r .retryCount + 1 ,
105+ "retryInterval" , r .retryInterval )
106+ if err := sleepWithContext (ctx , r .retryInterval ); err != nil {
107+ r .lggr .Debugw ("AllowListBasedAuth retry canceled" , "method" , req .Method , "requestID" , req .ID , "error" , err )
108+ return nil , nil , err
109+ }
110+ }
111+
112+ return nil , nil , nil
113+ }
114+
78115func (r * allowListBasedAuth ) fetchAllowlistedItem (allowListedRequests []workflow_registry_wrapper_v2.WorkflowRegistryOwnerAllowlistedRequest , digest [32 ]byte ) * workflow_registry_wrapper_v2.WorkflowRegistryOwnerAllowlistedRequest {
79116 for _ , item := range allowListedRequests {
80117 if item .RequestDigest == digest {
@@ -89,5 +126,19 @@ func NewAllowListBasedAuth(lggr logger.Logger, workflowRegistrySyncer workflowsy
89126 return & allowListBasedAuth {
90127 workflowRegistrySyncer : workflowRegistrySyncer ,
91128 lggr : logger .Named (lggr , "VaultAllowListBasedAuth" ),
129+ retryCount : allowListBasedAuthRetryCount ,
130+ retryInterval : allowListBasedAuthRetryInterval ,
131+ }
132+ }
133+
134+ func sleepWithContext (ctx context.Context , d time.Duration ) error {
135+ timer := time .NewTimer (d )
136+ defer timer .Stop ()
137+
138+ select {
139+ case <- ctx .Done ():
140+ return ctx .Err ()
141+ case <- timer .C :
142+ return nil
92143 }
93144}
0 commit comments