The previous default policy required both AccountTypes=["human"] and Roles=["user"], but MCIAS validate responses don't reliably include these fields. For a private registry, any successfully authenticated caller should have content access. Admin-only operations (policy management) still require the admin role. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
163 lines
3.7 KiB
Go
163 lines
3.7 KiB
Go
package policy
|
|
|
|
import "testing"
|
|
|
|
// fakeRuleStore implements RuleStore for testing.
|
|
type fakeRuleStore struct {
|
|
rules []Rule
|
|
err error
|
|
}
|
|
|
|
func (f *fakeRuleStore) LoadEnabledPolicyRules() ([]Rule, error) {
|
|
return f.rules, f.err
|
|
}
|
|
|
|
func TestEngineDefaultsOnly(t *testing.T) {
|
|
e := NewEngine()
|
|
|
|
// Admin should be allowed.
|
|
effect, _ := e.Evaluate(PolicyInput{
|
|
Subject: "admin-uuid",
|
|
AccountType: "human",
|
|
Roles: []string{"admin"},
|
|
Action: ActionPush,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("admin push with defaults: got %s, want allow", effect)
|
|
}
|
|
|
|
// System account should be allowed (rule -2: authenticated users).
|
|
effect, _ = e.Evaluate(PolicyInput{
|
|
Subject: "system-uuid",
|
|
AccountType: "system",
|
|
Action: ActionPull,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("system pull with defaults: got %s, want allow", effect)
|
|
}
|
|
}
|
|
|
|
func TestEngineWithCustomRules(t *testing.T) {
|
|
e := NewEngine()
|
|
e.SetRules([]Rule{
|
|
{
|
|
ID: 1,
|
|
Priority: 50,
|
|
Effect: Allow,
|
|
SubjectUUID: "ci-uuid",
|
|
Actions: []Action{ActionPull, ActionPush},
|
|
},
|
|
})
|
|
|
|
// System account with matching rule should be allowed.
|
|
effect, _ := e.Evaluate(PolicyInput{
|
|
Subject: "ci-uuid",
|
|
AccountType: "system",
|
|
Action: ActionPull,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("ci pull with custom rule: got %s, want allow", effect)
|
|
}
|
|
|
|
// Different subject is still allowed via default rule -2 (authenticated users).
|
|
effect, _ = e.Evaluate(PolicyInput{
|
|
Subject: "other-uuid",
|
|
AccountType: "system",
|
|
Action: ActionPull,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("other pull: got %s, want allow", effect)
|
|
}
|
|
}
|
|
|
|
func TestEngineReload(t *testing.T) {
|
|
e := NewEngine()
|
|
|
|
store := &fakeRuleStore{
|
|
rules: []Rule{
|
|
{
|
|
ID: 1,
|
|
Priority: 50,
|
|
Effect: Allow,
|
|
SubjectUUID: "ci-uuid",
|
|
Actions: []Action{ActionPull},
|
|
},
|
|
},
|
|
}
|
|
if err := e.Reload(store); err != nil {
|
|
t.Fatalf("Reload: %v", err)
|
|
}
|
|
|
|
// ci-uuid should now be allowed.
|
|
effect, _ := e.Evaluate(PolicyInput{
|
|
Subject: "ci-uuid",
|
|
AccountType: "system",
|
|
Action: ActionPull,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("ci pull after reload: got %s, want allow", effect)
|
|
}
|
|
|
|
// Reload again with new rules (simulating DB change).
|
|
store.rules = []Rule{
|
|
{
|
|
ID: 2,
|
|
Priority: 50,
|
|
Effect: Allow,
|
|
SubjectUUID: "deploy-uuid",
|
|
Actions: []Action{ActionPull},
|
|
},
|
|
}
|
|
if err := e.Reload(store); err != nil {
|
|
t.Fatalf("Reload (second): %v", err)
|
|
}
|
|
|
|
// ci-uuid custom rule is gone, but still allowed via default rule -2.
|
|
effect, _ = e.Evaluate(PolicyInput{
|
|
Subject: "ci-uuid",
|
|
AccountType: "system",
|
|
Action: ActionPull,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("ci pull after second reload: got %s, want allow", effect)
|
|
}
|
|
|
|
// deploy-uuid should now be allowed.
|
|
effect, _ = e.Evaluate(PolicyInput{
|
|
Subject: "deploy-uuid",
|
|
AccountType: "system",
|
|
Action: ActionPull,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("deploy pull after reload: got %s, want allow", effect)
|
|
}
|
|
}
|
|
|
|
func TestEngineReloadDisabledExcluded(t *testing.T) {
|
|
e := NewEngine()
|
|
|
|
// Store returns no rules (all disabled or none exist).
|
|
store := &fakeRuleStore{rules: nil}
|
|
if err := e.Reload(store); err != nil {
|
|
t.Fatalf("Reload: %v", err)
|
|
}
|
|
|
|
// No custom rules, but system account is allowed via default rule -2.
|
|
effect, _ := e.Evaluate(PolicyInput{
|
|
Subject: "ci-uuid",
|
|
AccountType: "system",
|
|
Action: ActionPull,
|
|
Repository: "myapp",
|
|
})
|
|
if effect != Allow {
|
|
t.Fatalf("system pull with no custom rules: got %s, want allow", effect)
|
|
}
|
|
}
|