@@ -36,9 +36,14 @@ const (
3636 validateAction = "validate"
3737 groupsEndpoint = "groups"
3838
39- digestParam = "digest"
40- orgNameParam = "organization_name"
41- organizationHeader = "Chainloop-Organization"
39+ digestParam = "digest"
40+ orgNameParam = "organization_name"
41+ // includeAllVersionsParam is the provider's query parameter that, when set,
42+ // makes the provider skip CLI-version compatibility resolution and return the
43+ // true latest revision. The wire name is "include_all_versions" but its real
44+ // effect is "ignore CLI compatibility gating" (see WithIgnoreCLICompatibility).
45+ includeAllVersionsParam = "include_all_versions"
46+ organizationHeader = "Chainloop-Organization"
4247)
4348
4449// PolicyProvider represents an external policy provider
8893 ErrUnauthorized = fmt .Errorf ("unauthorized request to policy provider" )
8994)
9095
91- // Resolve calls the remote provider for retrieving a policy
92- func (p * PolicyProvider ) Resolve (policyName , policyOrgName string , authOpts ProviderAuthOpts ) (* schemaapi.Policy , * PolicyReference , error ) {
96+ // ResolveOption configures a policy or policy-group resolution request.
97+ type ResolveOption func (* resolveOptions )
98+
99+ type resolveOptions struct {
100+ ignoreCLICompatibility bool
101+ }
102+
103+ func newResolveOptions (opts []ResolveOption ) resolveOptions {
104+ var o resolveOptions
105+ for _ , opt := range opts {
106+ if opt != nil {
107+ opt (& o )
108+ }
109+ }
110+ return o
111+ }
112+
113+ // WithIgnoreCLICompatibility makes the provider skip CLI-version compatibility
114+ // resolution and return the true latest revision instead of the latest revision
115+ // compatible with the requesting CLI version. It is meant for non-CLI callers
116+ // such as the web UI or the control plane. On the wire this sets the
117+ // include_all_versions query parameter.
118+ func WithIgnoreCLICompatibility () ResolveOption {
119+ return func (o * resolveOptions ) {
120+ o .ignoreCLICompatibility = true
121+ }
122+ }
123+
124+ // Resolve calls the remote provider for retrieving a policy.
125+ // See WithIgnoreCLICompatibility for the available resolution options.
126+ func (p * PolicyProvider ) Resolve (policyName , policyOrgName string , authOpts ProviderAuthOpts , opts ... ResolveOption ) (* schemaapi.Policy , * PolicyReference , error ) {
93127 if policyName == "" || authOpts .Token == "" {
94128 return nil , nil , fmt .Errorf ("both policyname and auth opts are mandatory" )
95129 }
@@ -108,7 +142,7 @@ func (p *PolicyProvider) Resolve(policyName, policyOrgName string, authOpts Prov
108142 }
109143 // we want to override the orgName with the one in the response
110144 // since we might have resolved it implicitly
111- providerDigest , orgName , err := p .queryProvider (url , digest , policyOrgName , authOpts , & policy )
145+ providerDigest , orgName , err := p .queryProvider (url , digest , policyOrgName , authOpts , & policy , opts ... )
112146 if err != nil {
113147 return nil , nil , fmt .Errorf ("failed to resolve policy: %w" , err )
114148 }
@@ -189,8 +223,9 @@ func (p *PolicyProvider) ValidateAttachment(att *schemaapi.PolicyAttachment, aut
189223 return nil
190224}
191225
192- // ResolveGroup calls remote provider for retrieving a policy group definition
193- func (p * PolicyProvider ) ResolveGroup (groupName , groupOrgName string , authOpts ProviderAuthOpts ) (* schemaapi.PolicyGroup , * PolicyReference , error ) {
226+ // ResolveGroup calls remote provider for retrieving a policy group definition.
227+ // See WithIgnoreCLICompatibility for the available resolution options.
228+ func (p * PolicyProvider ) ResolveGroup (groupName , groupOrgName string , authOpts ProviderAuthOpts , opts ... ResolveOption ) (* schemaapi.PolicyGroup , * PolicyReference , error ) {
194229 if groupName == "" || authOpts .Token == "" {
195230 return nil , nil , fmt .Errorf ("both policyname and token are mandatory" )
196231 }
@@ -209,7 +244,7 @@ func (p *PolicyProvider) ResolveGroup(groupName, groupOrgName string, authOpts P
209244 }
210245 // we want to override the orgName with the one in the response
211246 // since we might have resolved it implicitly
212- providerDigest , orgName , err := p .queryProvider (url , digest , groupOrgName , authOpts , & group )
247+ providerDigest , orgName , err := p .queryProvider (url , digest , groupOrgName , authOpts , & group , opts ... )
213248 if err != nil {
214249 return nil , nil , fmt .Errorf ("failed to resolve group: %w" , err )
215250 }
@@ -218,7 +253,9 @@ func (p *PolicyProvider) ResolveGroup(groupName, groupOrgName string, authOpts P
218253}
219254
220255// returns digest, orgname, error
221- func (p * PolicyProvider ) queryProvider (url * url.URL , digest , orgName string , authOpts ProviderAuthOpts , out proto.Message ) (string , string , error ) {
256+ func (p * PolicyProvider ) queryProvider (url * url.URL , digest , orgName string , authOpts ProviderAuthOpts , out proto.Message , opts ... ResolveOption ) (string , string , error ) {
257+ options := newResolveOptions (opts )
258+
222259 query := url .Query ()
223260 if digest != "" {
224261 query .Set (digestParam , digest )
@@ -228,6 +265,10 @@ func (p *PolicyProvider) queryProvider(url *url.URL, digest, orgName string, aut
228265 query .Set (orgNameParam , orgName )
229266 }
230267
268+ if options .ignoreCLICompatibility {
269+ query .Set (includeAllVersionsParam , "true" )
270+ }
271+
231272 url .RawQuery = query .Encode ()
232273
233274 req , err := http .NewRequest ("GET" , url .String (), nil )
0 commit comments