policy

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2023 License: MIT Imports: 5 Imported by: 8

Documentation

Overview

Package policy implements types for AWS's IAM policy grammar and supports JSON serialization and deserialization. No validation is performed on the policy, so it is possible to create invalid policies.

Here is an example that creates a policy document using this package.

package main

import (
	"encoding/json"
	"fmt"
	"github.com/micahhausler/aws-iam-policy/policy"
)

func main() {
	p := policy.Policy{
		Version: policy.VersionLatest,
		Statements: policy.NewStatementOrSlice([]policy.Statement{
			{
				Sid:       "S3Access",
				Effect:    policy.EffectAllow,
				Principal: policy.NewAWSPrincipal("arn:aws:iam::123456789012:role/my-role"),
				Action:    policy.NewStringOrSlice(true, "s3:ListBucket"),
				Resource:  policy.NewStringOrSlice(true, "arn:aws:s3:::examplebucket/AWSLogs/123456789012/*"),
			},
		},
	}...)
	b, err := json.MarshalIndent(p, "", "  ")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))
}
Example (NewBucketPolicy)
package main

import (
	"encoding/json"
	"fmt"

	"github.com/micahhausler/aws-iam-policy/policy"
)

func main() {
	p := policy.Policy{
		Version: policy.VersionLatest,
		Id:      "CloudTrailBucketPolicy",
		Statements: policy.NewStatementOrSlice([]policy.Statement{
			{
				Sid:       "AWSCloudTrailWrite20150319",
				Effect:    policy.EffectAllow,
				Principal: policy.NewServicePrincipal("cloudtrail.amazonaws.com"),
				Action:    policy.NewStringOrSlice(false, "s3:PutObject"),
				Resource:  policy.NewStringOrSlice(false, "arn:aws:s3:::examplebucket/AWSLogs/123456789012/*"),
				Condition: map[string]map[string]*policy.ConditionValue{
					"StringEquals": {
						"s3:x-amz-acl": policy.NewConditionValueString(true, "bucket-owner-full-control"),
					},
				},
			},
			{
				Sid:       "AWSCloudTrailAclCheck20150319",
				Effect:    policy.EffectAllow,
				Principal: policy.NewServicePrincipal("cloudtrail.amazonaws.com"),
				Action:    policy.NewStringOrSlice(true, "s3:GetBucketAcl"),
				Resource:  policy.NewStringOrSlice(true, "arn:aws:s3:::examplebucket"),
			},
		}...),
	}
	out, _ := json.MarshalIndent(p, "", "\t")
	fmt.Println(string(out))
}
Output:

{
	"Id": "CloudTrailBucketPolicy",
	"Statement": [
		{
			"Action": [
				"s3:PutObject"
			],
			"Condition": {
				"StringEquals": {
					"s3:x-amz-acl": "bucket-owner-full-control"
				}
			},
			"Effect": "Allow",
			"Principal": {
				"Service": "cloudtrail.amazonaws.com"
			},
			"Resource": [
				"arn:aws:s3:::examplebucket/AWSLogs/123456789012/*"
			],
			"Sid": "AWSCloudTrailWrite20150319"
		},
		{
			"Action": "s3:GetBucketAcl",
			"Effect": "Allow",
			"Principal": {
				"Service": "cloudtrail.amazonaws.com"
			},
			"Resource": "arn:aws:s3:::examplebucket",
			"Sid": "AWSCloudTrailAclCheck20150319"
		}
	],
	"Version": "2012-10-17"
}
Example (StrictJSONDecoding)

This is an example of how to use the strict JSON decoding functionality to ensure that the JSON document is valid according to this package.

The strict decoding functionality is not enabled by default because it is possible that the IAM policy grammar will be extended in the future to include new fields.

If you are modifying an existing policy document, or if you are using a policy document that you did not create, you can enable strict decoding by setting the DisallowUnknownFields field on a custom json.Decoder.

This example will fail because the JSON document has a hypothetical new field "Foo" that is not part of the IAM policy statement grammar.

package main

import (
	"bytes"
	"encoding/json"
	"fmt"

	"github.com/micahhausler/aws-iam-policy/policy"
)

func main() {

	invalidPolicyJSON := []byte(`{
		"Id": "CloudTrailBucketPolicy",
		"Foo": "hypothetical new field",
		"Statement": [
			{
				"Sid": "AWSCloudTrailWrite20150319",
				"Effect": "Allow",
				"Principal": {
					"Service": "cloudtrail.amazonaws.com"
				},
				"Action": "s3:PutObject",
				"Resource": "arn:aws:s3:::examplebucket/AWSLogs/123456789012/*"
			}
		]
	}`)
	var p policy.Policy
	decoder := json.NewDecoder(bytes.NewBuffer(invalidPolicyJSON))
	decoder.DisallowUnknownFields()
	err := decoder.Decode(&p)
	if err != nil {
		fmt.Println(err)
	}
}
Output:

json: unknown field "Foo"

Index

Examples

Constants

View Source
const (
	ErrorInvalidConditionValueSlice = "field not slice of string, bool or float64"
	ErrorInvalidConditionValue      = "field neither slice of string, bool, or float64 or string, bool or float64"
)
View Source
const (
	// See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_effect.html
	EffectAllow = "Allow"
	EffectDeny  = "Deny"

	// See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_version.html
	Version2012_10_17 = "2012-10-17"
	Version2008_10_17 = "2008-10-17"
	VersionLatest     = Version2012_10_17

	ErrorInvalidStatementSlice   = "StatementOrSlice is not a slice of statements"
	ErrorInvalidStatementOrSlice = "StatementOrSlice must be a single Statement or a slice of Statements"
)
View Source
const (
	PrincipalAll = "*"

	PrincipalKindAll       = "All"
	PrincipalKindAWS       = "AWS"
	PrincipalKindCanonical = "CanonicalUser"
	PrincipalKindFederated = "Federated"
	PrincipalKindService   = "Service"
)
View Source
const (
	ErrorInvalidStringOrSlice = "field neither slice of string or string"
	ErrorInvalidStringSlice   = "field not slice of string"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type ConditionValue

type ConditionValue struct {
	// contains filtered or unexported fields
}

ConditionValue is a type that can hold an indivual or slice of string, bool or float64. When unarshalling JSON, it will preserve whether the original value was singular or a slice.

func NewConditionValueBool

func NewConditionValueBool(singular bool, values ...bool) *ConditionValue

NewConditionValueBool creates a new ConditionValue. If singular is true and there is only one element, the structure will be marshaled as a bool instead of a slice.

func NewConditionValueFloat

func NewConditionValueFloat(singular bool, values ...float64) *ConditionValue

NewConditionValueFloat creates a new ConditionValue. If singular is true and there is only one element, the structure will be marshaled as an float64 instead of a slice.

func NewConditionValueString

func NewConditionValueString(singular bool, values ...string) *ConditionValue

NewConditionValueString creates a new ConditionValue. If singular is true and there is only one element, the structure will be marshaled as a string instead of a slice.

func (*ConditionValue) AddBool added in v0.2.0

func (c *ConditionValue) AddBool(values ...bool) error

AddBool adds a slice of bools to the ConditionValue. If the ConditionValue already has strings or floats, an error is returned.

func (*ConditionValue) AddFloat added in v0.2.0

func (c *ConditionValue) AddFloat(values ...float64) error

AddFloat adds a slice of floats to the ConditionValue. If the ConditionValue already has strings or bools, an error is returned.

func (*ConditionValue) AddString added in v0.2.0

func (c *ConditionValue) AddString(values ...string) error

AddStrings adds a slice of strings to the ConditionValue. If the ConditionValue already has bools or floats, an error is returned.

func (*ConditionValue) IsSingular

func (c *ConditionValue) IsSingular() bool

IsSingular returns true if the ConditionValue is a singular value and has zero or one elements.

func (*ConditionValue) MarshalJSON

func (c *ConditionValue) MarshalJSON() ([]byte, error)

func (*ConditionValue) UnmarshalJSON

func (c *ConditionValue) UnmarshalJSON(data []byte) error

func (*ConditionValue) Values

func (c *ConditionValue) Values() ([]string, []bool, []float64)

Values returns the values of the ConditionValue.

type Policy

type Policy struct {
	Id         string            `json:"Id,omitempty"`
	Statements *StatementOrSlice `json:"Statement"`
	Version    string            `json:"Version"`
}

Policy is a policy document.

type Principal

type Principal struct {
	// contains filtered or unexported fields
}

Principal is a Principal in a policy document.

func NewAWSPrincipal

func NewAWSPrincipal(aws ...string) *Principal

NewAWSPrincipal creates a new Principal that matches an AWS account.

func NewCanonicalUserPrincipal

func NewCanonicalUserPrincipal(canonicalUser ...string) *Principal

NewCanonicalUserPrincipal creates a new Principal that matches a canonical user.

func NewFederatedPrincipal

func NewFederatedPrincipal(federated ...string) *Principal

NewFederatedPrincipal creates a new Principal that matches a federated user.

func NewGlobalPrincipal

func NewGlobalPrincipal() *Principal

NewGlobalPrincipal creates a new Principal that matches all principals.

func NewServicePrincipal

func NewServicePrincipal(service ...string) *Principal

NewServicePrincipal creates a new Principal that matches a service.

func (*Principal) AWS added in v0.3.0

func (p *Principal) AWS() *StringOrSlice

AWS returns the AWS accounts of the Principal.

func (*Principal) AddAWS

func (p *Principal) AddAWS(aws ...string)

AddAWS adds one or more AWS accounts to the Principal.

func (*Principal) AddCanonicalUser

func (p *Principal) AddCanonicalUser(canonicalUser ...string)

AddCanonicalUser adds one or more canonical users to the Principal.

func (*Principal) AddFederated

func (p *Principal) AddFederated(federated ...string)

AddFederated adds one or more federated users to the Principal.

func (*Principal) AddService

func (p *Principal) AddService(service ...string)

AddService adds one or more services to the Principal.

func (*Principal) CanonicalUser added in v0.3.0

func (p *Principal) CanonicalUser() *StringOrSlice

CanonicalUser returns the canonical users of the Principal.

func (*Principal) Federated added in v0.3.0

func (p *Principal) Federated() *StringOrSlice

Federated returns the federated users of the Principal.

func (*Principal) Kinds added in v0.3.0

func (p *Principal) Kinds() []string

Kinds returns the kinds of the Principal.

func (*Principal) MarshalJSON

func (p *Principal) MarshalJSON() ([]byte, error)

func (*Principal) Service added in v0.3.0

func (p *Principal) Service() *StringOrSlice

Service returns the services of the Principal.

func (*Principal) UnmarshalJSON

func (p *Principal) UnmarshalJSON(data []byte) error

type Statement

type Statement struct {
	Action       *StringOrSlice                        `json:"Action,omitempty"`
	Condition    map[string]map[string]*ConditionValue `json:"Condition,omitempty"`
	Effect       string                                `json:"Effect"`
	NotAction    *StringOrSlice                        `json:"NotAction,omitempty"`
	NotResource  *StringOrSlice                        `json:"NotResource,omitempty"`
	Principal    *Principal                            `json:"Principal,omitempty"`
	NotPrincipal *Principal                            `json:"NotPrincipal,omitempty"`
	Resource     *StringOrSlice                        `json:"Resource,omitempty"`
	Sid          string                                `json:"Sid,omitempty"`
}

Statement is a single statement in a policy document.

type StatementOrSlice added in v0.4.0

type StatementOrSlice struct {
	// contains filtered or unexported fields
}

StatementOrSlice represents Statements that can be marshaled to a single Statement or a slice of Statements.

func NewSingularStatementOrSlice added in v0.4.0

func NewSingularStatementOrSlice(statements Statement) *StatementOrSlice

NewSingularStatementOrSlice creates a new StatementOrSlice with a single Statement.

func NewStatementOrSlice added in v0.4.0

func NewStatementOrSlice(statements ...Statement) *StatementOrSlice

NewStatementOrSlice creates a new StatementOrSlice with a slice of Statements.

func (*StatementOrSlice) Add added in v0.4.0

func (s *StatementOrSlice) Add(statements ...Statement)

ConditionValue is a value in a condition statement.

func (*StatementOrSlice) MarshalJSON added in v0.4.0

func (s *StatementOrSlice) MarshalJSON() ([]byte, error)

func (*StatementOrSlice) Singular added in v0.4.0

func (s *StatementOrSlice) Singular() bool

Singular returns true if the StatementOrSlice is a single Statement.

func (*StatementOrSlice) UnmarshalJSON added in v0.4.0

func (s *StatementOrSlice) UnmarshalJSON(data []byte) error

func (*StatementOrSlice) Values added in v0.4.0

func (s *StatementOrSlice) Values() []Statement

Values returns the statement values of the StatementOrSlice.

type StringOrSlice

type StringOrSlice struct {
	// contains filtered or unexported fields
}

StringOrSlice is a type that can hold a string or a slice of strings. When unarshalling JSON, it will preserve whether the original value was a singular string or a slice of strings.

func NewStringOrSlice

func NewStringOrSlice(singular bool, values ...string) *StringOrSlice

NewStringOrSlice creates a new StringOrSlice. If singular is true and there is only one element, the structure will be marshaled as a string instead of a slice.

func (*StringOrSlice) Add

func (s *StringOrSlice) Add(value ...string)

func (*StringOrSlice) IsSingular

func (s *StringOrSlice) IsSingular() bool

Singular returns true if the StringOrSlice is a singular value and has zero or one value.

func (*StringOrSlice) MarshalJSON

func (s *StringOrSlice) MarshalJSON() ([]byte, error)

func (*StringOrSlice) UnmarshalJSON

func (s *StringOrSlice) UnmarshalJSON(data []byte) error

func (*StringOrSlice) Values

func (s *StringOrSlice) Values() []string

Values returns the values of the StringOrSlice.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL