11//
2- // Copyright 2025 The Chainloop Authors.
2+ // Copyright 2024- 2025 The Chainloop Authors.
33//
44// Licensed under the Apache License, Version 2.0 (the "License");
55// you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import (
2626
2727 v1 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
2828 "github.com/chainloop-dev/chainloop/app/controlplane/pkg/unmarshal"
29+ "github.com/chainloop-dev/chainloop/pkg/policies/engine"
2930 "github.com/chainloop-dev/chainloop/pkg/resourceloader"
3031 opaAst "github.com/open-policy-agent/opa/v1/ast"
3132 "github.com/open-policy-agent/opa/v1/format"
@@ -43,6 +44,7 @@ type PolicyToLint struct {
4344 Path string
4445 YAMLFiles []* File
4546 RegoFiles []* File
47+ WASMFiles []* File
4648 Format bool
4749 Config string
4850 Errors []ValidationError
@@ -108,21 +110,21 @@ func Lookup(absPath, config string, format bool) (*PolicyToLint, error) {
108110 return nil , err
109111 }
110112
111- // Load referenced rego files from all YAML files
112- if err := policy .loadReferencedRegoFiles (filepath .Dir (resolvedPath )); err != nil {
113+ // Load referenced policy files (rego or wasm) from all YAML files
114+ if err := policy .loadReferencedPolicyFiles (filepath .Dir (resolvedPath )); err != nil {
113115 return nil , err
114116 }
115117
116118 // Verify we found at least one valid file
117- if len (policy .YAMLFiles ) == 0 && len (policy .RegoFiles ) == 0 {
118- return nil , fmt .Errorf ("no valid .yaml/.yml or .rego files found" )
119+ if len (policy .YAMLFiles ) == 0 && len (policy .RegoFiles ) == 0 && len ( policy . WASMFiles ) == 0 {
120+ return nil , fmt .Errorf ("no valid .yaml/.yml, .rego, or .wasm files found" )
119121 }
120122
121123 return policy , nil
122124}
123125
124- // Loads referenced rego files from YAML files in the policy
125- func (p * PolicyToLint ) loadReferencedRegoFiles (baseDir string ) error {
126+ // Loads referenced policy files (rego or wasm) from YAML files in the policy
127+ func (p * PolicyToLint ) loadReferencedPolicyFiles (baseDir string ) error {
126128 seen := make (map [string ]struct {})
127129 for _ , yamlFile := range p .YAMLFiles {
128130 var parsed v1.Policy
@@ -131,14 +133,14 @@ func (p *PolicyToLint) loadReferencedRegoFiles(baseDir string) error {
131133 continue
132134 }
133135 for _ , spec := range parsed .Spec .Policies {
134- regoPath := spec .GetPath ()
135- if regoPath != "" {
136+ policyPath := spec .GetPath ()
137+ if policyPath != "" {
136138 // If path is relative, make it relative to the YAML file's directory
137- if ! filepath .IsAbs (regoPath ) {
138- regoPath = filepath .Join (baseDir , regoPath )
139+ if ! filepath .IsAbs (policyPath ) {
140+ policyPath = filepath .Join (baseDir , policyPath )
139141 }
140142
141- resolvedPath , err := resourceloader .GetPathForResource (regoPath )
143+ resolvedPath , err := resourceloader .GetPathForResource (policyPath )
142144 if err != nil {
143145 return err
144146 }
@@ -173,8 +175,18 @@ func (p *PolicyToLint) processFile(filePath string) error {
173175 Path : filePath ,
174176 Content : content ,
175177 })
178+ case ".wasm" :
179+ // Detect if file is actually WASM using magic bytes
180+ policyType := engine .DetectPolicyType (content )
181+ if policyType != engine .PolicyTypeWASM {
182+ return fmt .Errorf ("file has .wasm extension but is not a valid WASM file" )
183+ }
184+ p .WASMFiles = append (p .WASMFiles , & File {
185+ Path : filePath ,
186+ Content : content ,
187+ })
176188 default :
177- return fmt .Errorf ("unsupported file extension %s, must be .yaml/.yml or .rego " , ext )
189+ return fmt .Errorf ("unsupported file extension %s, must be .yaml/.yml, .rego, or .wasm " , ext )
178190 }
179191
180192 return nil
@@ -185,6 +197,9 @@ func (p *PolicyToLint) Validate() {
185197 for _ , regoFile := range p .RegoFiles {
186198 p .validateRegoFile (regoFile )
187199 }
200+
201+ // WASM files are binary and cannot be linted
202+ // Only verify they have valid WASM magic bytes (already done in processFile)
188203}
189204
190205func (p * PolicyToLint ) validateRegoFile (file * File ) {
0 commit comments