Update Policy Enforcer Configuration Keys

- Changed configuration key from `policyDir` to `policyPaths` across multiple YAML files and related code to standardize the naming convention.
- Updated documentation to reflect the new key name and its usage for specifying local directories containing `.rego` policy files.
- Adjusted tests to ensure compatibility with the updated configuration structure.
This commit is contained in:
Ayush Rawat
2026-03-03 15:02:04 +05:30
parent e22b79e137
commit a806af3228
9 changed files with 41 additions and 41 deletions

View File

@@ -89,7 +89,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
middleware: middleware:
- id: reqpreprocessor - id: reqpreprocessor
config: config:

View File

@@ -87,7 +87,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
steps: steps:
- validateSign - validateSign
- policyEnforcer - policyEnforcer

View File

@@ -69,7 +69,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
middleware: middleware:
- id: reqpreprocessor - id: reqpreprocessor
config: config:
@@ -170,7 +170,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
steps: steps:
- validateSign - validateSign
- policyEnforcer - policyEnforcer

View File

@@ -51,7 +51,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
signValidator: signValidator:
id: signvalidator id: signvalidator
publisher: publisher:
@@ -106,7 +106,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
signer: signer:
id: signer id: signer
publisher: publisher:
@@ -162,7 +162,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
signValidator: signValidator:
id: signvalidator id: signvalidator
publisher: publisher:
@@ -217,7 +217,7 @@ modules:
policyEnforcer: policyEnforcer:
id: policyenforcer id: policyenforcer
config: config:
policyDir: "./policies" policyPaths: "./policies"
signer: signer:
id: signer id: signer
publisher: publisher:

View File

@@ -18,7 +18,7 @@ All config keys are passed via `map[string]string` in the adapter YAML config.
| Key | Required | Default | Description | | Key | Required | Default | Description |
|-----|----------|---------|-------------| |-----|----------|---------|-------------|
| `policyUrls` | At least one of `policyUrls`, `policyDir`, or `policyFile` required | — | Comma-separated list of URLs, local file paths, or directory paths to `.rego` files | | `policyUrls` | At least one of `policyUrls`, `policyDir`, or `policyFile` required | — | Comma-separated list of URLs, local file paths, or directory paths to `.rego` files |
| `policyDir` | | `./policies` | Local directory containing `.rego` files | | `policyPaths` | | `./policies` | Local directory or path containing `.rego` files |
| `policyFile` | | — | Single local `.rego` file path | | `policyFile` | | — | Single local `.rego` file path |
| `query` | No | `data.policy.violations` | Rego query returning violation strings | | `query` | No | `data.policy.violations` | Rego query returning violation strings |
| `actions` | No | *(empty — all actions)* | Comma-separated beckn actions to enforce. When omitted, all actions are evaluated and the Rego policy itself decides which to gate. | | `actions` | No | *(empty — all actions)* | Comma-separated beckn actions to enforce. When omitted, all actions are evaluated and the Rego policy itself decides which to gate. |

View File

@@ -8,9 +8,9 @@ import (
// Config holds the configuration for the Policy Enforcer plugin. // Config holds the configuration for the Policy Enforcer plugin.
type Config struct { type Config struct {
// PolicyDir is a local directory containing .rego policy files (all loaded). // PolicyPaths is a local directory containing .rego policy files (all loaded).
// At least one policy source (PolicyDir, PolicyFile, or PolicyUrls) is required. // At least one policy source (PolicyPaths, PolicyFile, or PolicyUrls) is required.
PolicyDir string PolicyPaths string
// PolicyFile is a single local .rego file path. // PolicyFile is a single local .rego file path.
PolicyFile string PolicyFile string
@@ -42,7 +42,7 @@ type Config struct {
// Known config keys that are handled directly (not forwarded to RuntimeConfig). // Known config keys that are handled directly (not forwarded to RuntimeConfig).
var knownKeys = map[string]bool{ var knownKeys = map[string]bool{
"policyDir": true, "policyPaths": true,
"policyFile": true, "policyFile": true,
"policyUrls": true, "policyUrls": true,
"query": true, "query": true,
@@ -65,8 +65,8 @@ func DefaultConfig() *Config {
func ParseConfig(cfg map[string]string) (*Config, error) { func ParseConfig(cfg map[string]string) (*Config, error) {
config := DefaultConfig() config := DefaultConfig()
if dir, ok := cfg["policyDir"]; ok && dir != "" { if dir, ok := cfg["policyPaths"]; ok && dir != "" {
config.PolicyDir = dir config.PolicyPaths = dir
} }
if file, ok := cfg["policyFile"]; ok && file != "" { if file, ok := cfg["policyFile"]; ok && file != "" {
config.PolicyFile = file config.PolicyFile = file
@@ -82,12 +82,12 @@ func ParseConfig(cfg map[string]string) (*Config, error) {
} }
} }
if config.PolicyDir == "" && config.PolicyFile == "" && len(config.PolicyUrls) == 0 { if config.PolicyPaths == "" && config.PolicyFile == "" && len(config.PolicyUrls) == 0 {
// Fall back to the default ./policies directory if it exists on disk. // Fall back to the default ./policies directory if it exists on disk.
if info, err := os.Stat("./policies"); err == nil && info.IsDir() { if info, err := os.Stat("./policies"); err == nil && info.IsDir() {
config.PolicyDir = "./policies" config.PolicyPaths = "./policies"
} else { } else {
return nil, fmt.Errorf("at least one policy source is required (policyDir, policyFile, or policyUrls)") return nil, fmt.Errorf("at least one policy source is required (policyPaths, policyFile, or policyUrls)")
} }
} }

View File

@@ -24,7 +24,7 @@ func New(cfg map[string]string) (*PolicyEnforcer, error) {
return nil, fmt.Errorf("policyenforcer: config error: %w", err) return nil, fmt.Errorf("policyenforcer: config error: %w", err)
} }
evaluator, err := NewEvaluator(config.PolicyDir, config.PolicyFile, config.PolicyUrls, config.Query, config.RuntimeConfig) evaluator, err := NewEvaluator(config.PolicyPaths, config.PolicyFile, config.PolicyUrls, config.Query, config.RuntimeConfig)
if err != nil { if err != nil {
return nil, fmt.Errorf("policyenforcer: failed to initialize OPA evaluator: %w", err) return nil, fmt.Errorf("policyenforcer: failed to initialize OPA evaluator: %w", err)
} }

View File

@@ -37,12 +37,12 @@ func writePolicyDir(t *testing.T, filename, content string) string {
func TestParseConfig_RequiresPolicySource(t *testing.T) { func TestParseConfig_RequiresPolicySource(t *testing.T) {
_, err := ParseConfig(map[string]string{}) _, err := ParseConfig(map[string]string{})
if err == nil { if err == nil {
t.Fatal("expected error when no policyDir, policyFile, or policyUrls given") t.Fatal("expected error when no policyPaths, policyFile, or policyUrls given")
} }
} }
func TestParseConfig_Defaults(t *testing.T) { func TestParseConfig_Defaults(t *testing.T) {
cfg, err := ParseConfig(map[string]string{"policyDir": "/tmp"}) cfg, err := ParseConfig(map[string]string{"policyPaths": "/tmp"})
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -59,7 +59,7 @@ func TestParseConfig_Defaults(t *testing.T) {
func TestParseConfig_RuntimeConfigForwarding(t *testing.T) { func TestParseConfig_RuntimeConfigForwarding(t *testing.T) {
cfg, err := ParseConfig(map[string]string{ cfg, err := ParseConfig(map[string]string{
"policyDir": "/tmp", "policyPaths": "/tmp",
"minDeliveryLeadHours": "6", "minDeliveryLeadHours": "6",
"customParam": "value", "customParam": "value",
}) })
@@ -76,8 +76,8 @@ func TestParseConfig_RuntimeConfigForwarding(t *testing.T) {
func TestParseConfig_CustomActions(t *testing.T) { func TestParseConfig_CustomActions(t *testing.T) {
cfg, err := ParseConfig(map[string]string{ cfg, err := ParseConfig(map[string]string{
"policyDir": "/tmp", "policyPaths": "/tmp",
"actions": "confirm, select, init", "actions": "confirm, select, init",
}) })
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@@ -380,9 +380,9 @@ violations contains "blocked" if { input.context.action == "confirm"; input.bloc
dir := writePolicyDir(t, "test.rego", policy) dir := writePolicyDir(t, "test.rego", policy)
enforcer, err := New(map[string]string{ enforcer, err := New(map[string]string{
"policyDir": dir, "policyPaths": dir,
"query": "data.policy.violations", "query": "data.policy.violations",
"actions": "confirm", "actions": "confirm",
}) })
if err != nil { if err != nil {
t.Fatalf("New failed: %v", err) t.Fatalf("New failed: %v", err)
@@ -404,9 +404,9 @@ violations contains "blocked" if { input.context.action == "confirm" }
dir := writePolicyDir(t, "test.rego", policy) dir := writePolicyDir(t, "test.rego", policy)
enforcer, err := New(map[string]string{ enforcer, err := New(map[string]string{
"policyDir": dir, "policyPaths": dir,
"query": "data.policy.violations", "query": "data.policy.violations",
"actions": "confirm", "actions": "confirm",
}) })
if err != nil { if err != nil {
t.Fatalf("New failed: %v", err) t.Fatalf("New failed: %v", err)
@@ -433,9 +433,9 @@ violations contains "blocked" if { true }
dir := writePolicyDir(t, "test.rego", policy) dir := writePolicyDir(t, "test.rego", policy)
enforcer, err := New(map[string]string{ enforcer, err := New(map[string]string{
"policyDir": dir, "policyPaths": dir,
"query": "data.policy.violations", "query": "data.policy.violations",
"actions": "confirm", "actions": "confirm",
}) })
if err != nil { if err != nil {
t.Fatalf("New failed: %v", err) t.Fatalf("New failed: %v", err)
@@ -458,9 +458,9 @@ violations contains "blocked" if { true }
dir := writePolicyDir(t, "test.rego", policy) dir := writePolicyDir(t, "test.rego", policy)
enforcer, err := New(map[string]string{ enforcer, err := New(map[string]string{
"policyDir": dir, "policyPaths": dir,
"query": "data.policy.violations", "query": "data.policy.violations",
"enabled": "false", "enabled": "false",
}) })
if err != nil { if err != nil {
t.Fatalf("New failed: %v", err) t.Fatalf("New failed: %v", err)

View File

@@ -40,14 +40,14 @@ const maxPolicySize = 1 << 20
// NewEvaluator creates an Evaluator by loading .rego files from local paths // NewEvaluator creates an Evaluator by loading .rego files from local paths
// and/or URLs, then compiling them. runtimeConfig is passed to Rego as data.config. // and/or URLs, then compiling them. runtimeConfig is passed to Rego as data.config.
func NewEvaluator(policyDir, policyFile string, policyUrls []string, query string, runtimeConfig map[string]string) (*Evaluator, error) { func NewEvaluator(policyPaths, policyFile string, policyUrls []string, query string, runtimeConfig map[string]string) (*Evaluator, error) {
modules := make(map[string]string) modules := make(map[string]string)
// Load from local directory // Load from local directory
if policyDir != "" { if policyPaths != "" {
entries, err := os.ReadDir(policyDir) entries, err := os.ReadDir(policyPaths)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read policy directory %s: %w", policyDir, err) return nil, fmt.Errorf("failed to read policy directory %s: %w", policyPaths, err)
} }
for _, entry := range entries { for _, entry := range entries {
if entry.IsDir() { if entry.IsDir() {
@@ -60,7 +60,7 @@ func NewEvaluator(policyDir, policyFile string, policyUrls []string, query strin
if strings.HasSuffix(entry.Name(), "_test.rego") { if strings.HasSuffix(entry.Name(), "_test.rego") {
continue continue
} }
fpath := filepath.Join(policyDir, entry.Name()) fpath := filepath.Join(policyPaths, entry.Name())
data, err := os.ReadFile(fpath) data, err := os.ReadFile(fpath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read policy file %s: %w", fpath, err) return nil, fmt.Errorf("failed to read policy file %s: %w", fpath, err)