| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- //go:build ignore
- // +build ignore
- package policy_engine
- import (
- "encoding/json"
- "fmt"
- )
- // This file contains examples and documentation for the policy engine
- // ExampleIdentityJSON shows the existing identities.json format (unchanged)
- var ExampleIdentityJSON = `{
- "identities": [
- {
- "name": "user1",
- "credentials": [
- {
- "accessKey": "AKIAIOSFODNN7EXAMPLE",
- "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
- }
- ],
- "actions": [
- "Read:bucket1/*",
- "Write:bucket1/*",
- "Admin:bucket2"
- ]
- },
- {
- "name": "readonly-user",
- "credentials": [
- {
- "accessKey": "AKIAI44QH8DHBEXAMPLE",
- "secretKey": "je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY"
- }
- ],
- "actions": [
- "Read:bucket1/*",
- "List:bucket1"
- ]
- }
- ]
- }`
- // ExampleBucketPolicy shows an AWS S3 bucket policy with conditions
- var ExampleBucketPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowGetObjectFromSpecificIP",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::my-bucket/*",
- "Condition": {
- "IpAddress": {
- "aws:SourceIp": "192.168.1.0/24"
- }
- }
- },
- {
- "Sid": "AllowPutObjectWithSSL",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:PutObject",
- "Resource": "arn:aws:s3:::my-bucket/*",
- "Condition": {
- "Bool": {
- "aws:SecureTransport": "true"
- }
- }
- },
- {
- "Sid": "DenyDeleteFromProduction",
- "Effect": "Deny",
- "Principal": "*",
- "Action": "s3:DeleteObject",
- "Resource": "arn:aws:s3:::my-bucket/production/*"
- }
- ]
- }`
- // ExampleTimeBasedPolicy shows a policy with time-based conditions
- var ExampleTimeBasedPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowAccessDuringBusinessHours",
- "Effect": "Allow",
- "Principal": "*",
- "Action": ["s3:GetObject", "s3:PutObject"],
- "Resource": "arn:aws:s3:::my-bucket/*",
- "Condition": {
- "DateGreaterThan": {
- "aws:RequestTime": "2023-01-01T08:00:00Z"
- },
- "DateLessThan": {
- "aws:RequestTime": "2023-12-31T18:00:00Z"
- }
- }
- }
- ]
- }`
- // ExampleIPRestrictedPolicy shows a policy with IP restrictions
- var ExampleIPRestrictedPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowFromOfficeNetwork",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:*",
- "Resource": [
- "arn:aws:s3:::my-bucket",
- "arn:aws:s3:::my-bucket/*"
- ],
- "Condition": {
- "IpAddress": {
- "aws:SourceIp": [
- "203.0.113.0/24",
- "198.51.100.0/24"
- ]
- }
- }
- },
- {
- "Sid": "DenyFromRestrictedIPs",
- "Effect": "Deny",
- "Principal": "*",
- "Action": "*",
- "Resource": "*",
- "Condition": {
- "IpAddress": {
- "aws:SourceIp": [
- "192.0.2.0/24"
- ]
- }
- }
- }
- ]
- }`
- // ExamplePublicReadPolicy shows a policy for public read access
- var ExamplePublicReadPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "PublicReadGetObject",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::my-public-bucket/*"
- }
- ]
- }`
- // ExampleCORSPolicy shows a policy with CORS-related conditions
- var ExampleCORSPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowCrossOriginRequests",
- "Effect": "Allow",
- "Principal": "*",
- "Action": ["s3:GetObject", "s3:PutObject"],
- "Resource": "arn:aws:s3:::my-bucket/*",
- "Condition": {
- "StringLike": {
- "aws:Referer": [
- "https://example.com/*",
- "https://*.example.com/*"
- ]
- }
- }
- }
- ]
- }`
- // ExampleUserAgentPolicy shows a policy with user agent restrictions
- var ExampleUserAgentPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowSpecificUserAgents",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::my-bucket/*",
- "Condition": {
- "StringLike": {
- "aws:UserAgent": [
- "MyApp/*",
- "curl/*"
- ]
- }
- }
- }
- ]
- }`
- // ExamplePrefixBasedPolicy shows a policy with prefix-based access
- var ExamplePrefixBasedPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowUserFolderAccess",
- "Effect": "Allow",
- "Principal": "*",
- "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
- "Resource": "arn:aws:s3:::my-bucket/${aws:username}/*",
- "Condition": {
- "StringEquals": {
- "s3:prefix": "${aws:username}/"
- }
- }
- }
- ]
- }`
- // ExampleMultiStatementPolicy shows a complex policy with multiple statements
- var ExampleMultiStatementPolicy = `{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowListBucket",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:ListBucket",
- "Resource": "arn:aws:s3:::my-bucket",
- "Condition": {
- "StringEquals": {
- "s3:prefix": "public/"
- }
- }
- },
- {
- "Sid": "AllowGetPublicObjects",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::my-bucket/public/*"
- },
- {
- "Sid": "AllowAuthenticatedUpload",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:PutObject",
- "Resource": "arn:aws:s3:::my-bucket/uploads/*",
- "Condition": {
- "StringEquals": {
- "s3:x-amz-acl": "private"
- }
- }
- },
- {
- "Sid": "DenyInsecureConnections",
- "Effect": "Deny",
- "Principal": "*",
- "Action": "s3:*",
- "Resource": [
- "arn:aws:s3:::my-bucket",
- "arn:aws:s3:::my-bucket/*"
- ],
- "Condition": {
- "Bool": {
- "aws:SecureTransport": "false"
- }
- }
- }
- ]
- }`
- // GetAllExamples returns all example policies
- func GetAllExamples() map[string]string {
- return map[string]string{
- "basic-bucket-policy": ExampleBucketPolicy,
- "time-based-policy": ExampleTimeBasedPolicy,
- "ip-restricted-policy": ExampleIPRestrictedPolicy,
- "public-read-policy": ExamplePublicReadPolicy,
- "cors-policy": ExampleCORSPolicy,
- "user-agent-policy": ExampleUserAgentPolicy,
- "prefix-based-policy": ExamplePrefixBasedPolicy,
- "multi-statement-policy": ExampleMultiStatementPolicy,
- }
- }
- // ValidateExamplePolicies validates all example policies
- func ValidateExamplePolicies() error {
- examples := GetAllExamples()
- for name, policyJSON := range examples {
- _, err := ParsePolicy(policyJSON)
- if err != nil {
- return fmt.Errorf("invalid example policy %s: %v", name, err)
- }
- }
- return nil
- }
- // GetExamplePolicy returns a specific example policy
- func GetExamplePolicy(name string) (string, error) {
- examples := GetAllExamples()
- policy, exists := examples[name]
- if !exists {
- return "", fmt.Errorf("example policy %s not found", name)
- }
- return policy, nil
- }
- // CreateExamplePolicyDocument creates a PolicyDocument from an example
- func CreateExamplePolicyDocument(name string) (*PolicyDocument, error) {
- policyJSON, err := GetExamplePolicy(name)
- if err != nil {
- return nil, err
- }
- return ParsePolicy(policyJSON)
- }
- // PrintExamplePolicyPretty prints an example policy in pretty format
- func PrintExamplePolicyPretty(name string) error {
- policyJSON, err := GetExamplePolicy(name)
- if err != nil {
- return err
- }
- var policy interface{}
- if err := json.Unmarshal([]byte(policyJSON), &policy); err != nil {
- return err
- }
- prettyJSON, err := json.MarshalIndent(policy, "", " ")
- if err != nil {
- return err
- }
- fmt.Printf("Example Policy: %s\n", name)
- fmt.Printf("================\n")
- fmt.Println(string(prettyJSON))
- return nil
- }
- // ExampleUsage demonstrates how to use the policy engine
- func ExampleUsage() {
- // Create a new policy engine
- engine := NewPolicyEngine()
- // Set a bucket policy
- policyJSON := ExampleBucketPolicy
- err := engine.SetBucketPolicy("my-bucket", policyJSON)
- if err != nil {
- fmt.Printf("Error setting bucket policy: %v\n", err)
- return
- }
- // Evaluate a policy
- args := &PolicyEvaluationArgs{
- Action: "s3:GetObject",
- Resource: "arn:aws:s3:::my-bucket/test-object",
- Principal: "*",
- Conditions: map[string][]string{
- "aws:SourceIp": {"192.168.1.100"},
- },
- }
- result := engine.EvaluatePolicy("my-bucket", args)
- switch result {
- case PolicyResultAllow:
- fmt.Println("Access allowed")
- case PolicyResultDeny:
- fmt.Println("Access denied")
- case PolicyResultIndeterminate:
- fmt.Println("Access indeterminate")
- }
- }
- // ExampleLegacyIntegration demonstrates backward compatibility
- func ExampleLegacyIntegration() {
- // Legacy identity actions
- legacyActions := []string{
- "Read:bucket1/*",
- "Write:bucket1/uploads/*",
- "Admin:bucket2",
- }
- // Convert to policy
- policy, err := ConvertIdentityToPolicy(legacyActions, "bucket1")
- if err != nil {
- fmt.Printf("Error converting identity to policy: %v\n", err)
- return
- }
- // Create policy-backed IAM
- policyIAM := NewPolicyBackedIAM()
- // Set the converted policy
- policyJSON, _ := json.MarshalIndent(policy, "", " ")
- err = policyIAM.SetBucketPolicy("bucket1", string(policyJSON))
- if err != nil {
- fmt.Printf("Error setting bucket policy: %v\n", err)
- return
- }
- fmt.Println("Legacy identity successfully converted to AWS S3 policy")
- }
- // ExampleConditions demonstrates various condition types
- func ExampleConditions() {
- examples := map[string]string{
- "StringEquals": `"StringEquals": {"s3:prefix": "documents/"}`,
- "StringLike": `"StringLike": {"aws:UserAgent": "MyApp/*"}`,
- "NumericEquals": `"NumericEquals": {"s3:max-keys": "10"}`,
- "NumericLessThan": `"NumericLessThan": {"s3:max-keys": "1000"}`,
- "DateGreaterThan": `"DateGreaterThan": {"aws:RequestTime": "2023-01-01T00:00:00Z"}`,
- "DateLessThan": `"DateLessThan": {"aws:RequestTime": "2023-12-31T23:59:59Z"}`,
- "IpAddress": `"IpAddress": {"aws:SourceIp": "192.168.1.0/24"}`,
- "NotIpAddress": `"NotIpAddress": {"aws:SourceIp": "10.0.0.0/8"}`,
- "Bool": `"Bool": {"aws:SecureTransport": "true"}`,
- "Null": `"Null": {"s3:x-amz-server-side-encryption": "false"}`,
- }
- fmt.Println("Supported Condition Operators:")
- fmt.Println("==============================")
- for operator, example := range examples {
- fmt.Printf("%s: %s\n", operator, example)
- }
- }
- // ExampleMigrationStrategy demonstrates migration from legacy to policy-based system
- func ExampleMigrationStrategy() {
- fmt.Println("Migration Strategy:")
- fmt.Println("==================")
- fmt.Println("1. Keep existing identities.json unchanged")
- fmt.Println("2. Legacy actions are automatically converted to AWS policies internally")
- fmt.Println("3. Add bucket policies for advanced features:")
- fmt.Println(" - IP restrictions")
- fmt.Println(" - Time-based access")
- fmt.Println(" - SSL-only access")
- fmt.Println(" - User agent restrictions")
- fmt.Println("4. Policy evaluation precedence:")
- fmt.Println(" - Explicit Deny (highest priority)")
- fmt.Println(" - Explicit Allow")
- fmt.Println(" - Default Deny (lowest priority)")
- }
- // PrintAllExamples prints all example policies
- func PrintAllExamples() {
- examples := GetAllExamples()
- for name := range examples {
- fmt.Printf("\n")
- PrintExamplePolicyPretty(name)
- fmt.Printf("\n")
- }
- }
|