diff --git a/internal/service/policy/service.go b/internal/service/policy/service.go index a9f6616aca71da37771186bf4a345af04aa1fc38..a12c7f56b90964e3c91182f52642df7b5d7f1872 100644 --- a/internal/service/policy/service.go +++ b/internal/service/policy/service.go @@ -2,7 +2,10 @@ package policy import ( "context" + "os" + "strings" + "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/rego" "go.uber.org/zap" @@ -18,13 +21,19 @@ type Storage interface { type Service struct { storage Storage - logger *zap.Logger + + runtimeObj *ast.Term // object to pass to each rego query + + logger *zap.Logger } func New(storage Storage, logger *zap.Logger) *Service { + runtimeObj := getRuntimeObject() + return &Service{ - storage: storage, - logger: logger, + storage: storage, + runtimeObj: runtimeObj, + logger: logger, } } @@ -52,6 +61,7 @@ func (s *Service) Evaluate(ctx context.Context, req *policy.EvaluateRequest) (*p query, err := rego.New( rego.Module(pol.Filename, pol.Rego), rego.Query("result = data.gaiax.result"), + rego.Runtime(s.runtimeObj), ).PrepareForEval(ctx) if err != nil { logger.Error("error preparing rego query", zap.Error(err)) @@ -139,3 +149,21 @@ func (s *Service) Unlock(ctx context.Context, req *policy.UnlockRequest) error { return nil } + +// getRuntimeObject adds environment variables to an OPA object +// which later is passed to rego query's runtime +func getRuntimeObject() *ast.Term { + obj := ast.NewObject() + env := ast.NewObject() + for _, s := range os.Environ() { + parts := strings.SplitN(s, "=", 2) + if len(parts) == 1 { + env.Insert(ast.StringTerm(parts[0]), ast.NullTerm()) + } else if len(parts) > 1 { + env.Insert(ast.StringTerm(parts[0]), ast.StringTerm(parts[1])) + } + } + obj.Insert(ast.StringTerm("env"), ast.NewTerm(env)) + + return ast.NewTerm(obj) +}