forked from TrueCloudLab/policy-engine
[#57] iam: Add policy validation checks
Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
This commit is contained in:
parent
2ec958cbfd
commit
9040e48504
3 changed files with 64 additions and 3 deletions
|
@ -315,6 +315,7 @@ func TestConverters(t *testing.T) {
|
||||||
|
|
||||||
t.Run("valid mixed iam/s3 actions", func(t *testing.T) {
|
t.Run("valid mixed iam/s3 actions", func(t *testing.T) {
|
||||||
p := Policy{
|
p := Policy{
|
||||||
|
Version: "2012-10-17",
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Principal: map[PrincipalType][]string{AWSPrincipalType: {principal}},
|
Principal: map[PrincipalType][]string{AWSPrincipalType: {principal}},
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
|
|
|
@ -46,6 +46,8 @@ type (
|
||||||
PrincipalType string
|
PrincipalType string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const policyVersion = "2012-10-17"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GeneralPolicyType PolicyType = iota
|
GeneralPolicyType PolicyType = iota
|
||||||
IdentityBasedPolicyType
|
IdentityBasedPolicyType
|
||||||
|
@ -222,11 +224,20 @@ func (p Policy) Validate(typ PolicyType) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Policy) validate() error {
|
func (p Policy) validate() error {
|
||||||
|
if p.Version != policyVersion {
|
||||||
|
return fmt.Errorf("invalid policy version, expected '%s', actual: '%s'", policyVersion, p.Version)
|
||||||
|
}
|
||||||
|
|
||||||
if len(p.Statement) == 0 {
|
if len(p.Statement) == 0 {
|
||||||
return errors.New("'Statement' is missing")
|
return errors.New("'Statement' is missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sids := make(map[string]struct{}, len(p.Statement))
|
||||||
for _, statement := range p.Statement {
|
for _, statement := range p.Statement {
|
||||||
|
if _, ok := sids[statement.SID]; ok && statement.SID != "" {
|
||||||
|
return fmt.Errorf("duplicate 'SID': %s", statement.SID)
|
||||||
|
}
|
||||||
|
sids[statement.SID] = struct{}{}
|
||||||
if !statement.Effect.IsValid() {
|
if !statement.Effect.IsValid() {
|
||||||
return fmt.Errorf("unknown effect: '%s'", statement.Effect)
|
return fmt.Errorf("unknown effect: '%s'", statement.Effect)
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,6 +218,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "valid permission boundaries",
|
name: "valid permission boundaries",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
||||||
|
@ -230,6 +231,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "general invalid effect",
|
name: "general invalid effect",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: "dummy",
|
Effect: "dummy",
|
||||||
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
||||||
|
@ -242,6 +244,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "general invalid principal block",
|
name: "general invalid principal block",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
||||||
|
@ -256,6 +259,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "general invalid not principal",
|
name: "general invalid not principal",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
||||||
|
@ -269,6 +273,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "general invalid principal type",
|
name: "general invalid principal type",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
||||||
|
@ -282,6 +287,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "general invalid action block",
|
name: "general invalid action block",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
Action: []string{"s3:*", "cloudwatch:*", "ec2:*"},
|
||||||
|
@ -295,6 +301,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "general invalid resource block",
|
name: "general invalid resource block",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Resource: []string{Wildcard},
|
Resource: []string{Wildcard},
|
||||||
|
@ -307,6 +314,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "invalid resource block",
|
name: "invalid resource block",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Resource: []string{},
|
Resource: []string{},
|
||||||
|
@ -319,6 +327,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "missing resource block",
|
name: "missing resource block",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
}},
|
}},
|
||||||
|
@ -332,9 +341,43 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
typ: GeneralPolicyType,
|
typ: GeneralPolicyType,
|
||||||
isValid: false,
|
isValid: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "duplicate sid",
|
||||||
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
|
Statement: []Statement{
|
||||||
|
{
|
||||||
|
SID: "sid",
|
||||||
|
Effect: AllowEffect,
|
||||||
|
Action: []string{"s3:*"},
|
||||||
|
Resource: []string{Wildcard},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SID: "sid",
|
||||||
|
Effect: AllowEffect,
|
||||||
|
Action: []string{"cloudwatch:*"},
|
||||||
|
Resource: []string{Wildcard},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
typ: GeneralPolicyType,
|
||||||
|
isValid: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "missing version",
|
||||||
|
policy: Policy{
|
||||||
|
Statement: []Statement{{
|
||||||
|
Effect: AllowEffect,
|
||||||
|
Action: []string{"s3:*"},
|
||||||
|
Resource: []string{Wildcard},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
typ: GeneralPolicyType,
|
||||||
|
isValid: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "identity based valid",
|
name: "identity based valid",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:PutObject"},
|
Action: []string{"s3:PutObject"},
|
||||||
|
@ -348,6 +391,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
name: "identity based invalid because of id presence",
|
name: "identity based invalid because of id presence",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
ID: "some-id",
|
ID: "some-id",
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:PutObject"},
|
Action: []string{"s3:PutObject"},
|
||||||
|
@ -360,6 +404,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "identity based invalid because of principal presence",
|
name: "identity based invalid because of principal presence",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:PutObject"},
|
Action: []string{"s3:PutObject"},
|
||||||
|
@ -373,6 +418,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "identity based invalid because of not principal presence",
|
name: "identity based invalid because of not principal presence",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:PutObject"},
|
Action: []string{"s3:PutObject"},
|
||||||
|
@ -386,6 +432,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "resource based valid principal",
|
name: "resource based valid principal",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: DenyEffect,
|
Effect: DenyEffect,
|
||||||
Action: []string{"s3:PutObject"},
|
Action: []string{"s3:PutObject"},
|
||||||
|
@ -400,6 +447,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
name: "resource based valid not principal",
|
name: "resource based valid not principal",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
ID: "some-id",
|
ID: "some-id",
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: DenyEffect,
|
Effect: DenyEffect,
|
||||||
Action: []string{"s3:PutObject"},
|
Action: []string{"s3:PutObject"},
|
||||||
|
@ -414,6 +462,7 @@ func TestValidatePolicies(t *testing.T) {
|
||||||
name: "resource based invalid missing principal",
|
name: "resource based invalid missing principal",
|
||||||
policy: Policy{
|
policy: Policy{
|
||||||
ID: "some-id",
|
ID: "some-id",
|
||||||
|
Version: policyVersion,
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
Effect: AllowEffect,
|
Effect: AllowEffect,
|
||||||
Action: []string{"s3:PutObject"},
|
Action: []string{"s3:PutObject"},
|
||||||
|
|
Loading…
Reference in a new issue