github.com/opentofu/opentofu@v1.7.1/internal/encryption/keyprovider/aws_kms/config_assumerole.go (about) 1 package aws_kms 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "github.com/aws/aws-sdk-go-v2/aws/arn" 9 awsbase "github.com/hashicorp/aws-sdk-go-base/v2" 10 ) 11 12 type AssumeRole struct { 13 RoleARN string `hcl:"role_arn"` 14 Duration string `hcl:"duration,optional"` 15 ExternalID string `hcl:"external_id,optional"` 16 Policy string `hcl:"policy,optional"` 17 PolicyARNs []string `hcl:"policy_arns,optional"` 18 SessionName string `hcl:"session_name,optional"` 19 Tags map[string]string `hcl:"tags,optional"` 20 TransitiveTagKeys []string `hcl:"transitive_tag_keys,optional"` 21 } 22 23 type AssumeRoleWithWebIdentity struct { 24 RoleARN string `hcl:"role_arn,optional"` 25 Duration string `hcl:"duration,optional"` 26 Policy string `hcl:"policy,optional"` 27 PolicyARNs []string `hcl:"policy_arns,optional"` 28 SessionName string `hcl:"session_name,optional"` 29 WebIdentityToken string `hcl:"web_identity_token,optional"` 30 WebIdentityTokenFile string `hcl:"web_identity_token_file,optional"` 31 } 32 33 func parseAssumeRoleDuration(val string) (dur time.Duration, err error) { 34 if len(val) == 0 { 35 return dur, nil 36 } 37 dur, err = time.ParseDuration(val) 38 if err != nil { 39 return dur, fmt.Errorf("invalid assume_role duration %q: %w", val, err) 40 } 41 42 minDur := 15 * time.Minute 43 maxDur := 12 * time.Hour 44 if (minDur > 0 && dur < minDur) || (maxDur > 0 && dur > maxDur) { 45 return dur, fmt.Errorf("assume_role duration must be between %s and %s, had %s", minDur, maxDur, dur) 46 } 47 return dur, nil 48 } 49 50 func validatePolicyARNs(arns []string) error { 51 for _, v := range arns { 52 arn, err := arn.Parse(v) 53 if err != nil { 54 return err 55 } 56 if !strings.HasPrefix(arn.Resource, "policy/") { 57 return fmt.Errorf("arn must be a valid IAM Policy ARN, got %q", v) 58 } 59 } 60 return nil 61 } 62 63 func (r *AssumeRole) asAWSBase() (*awsbase.AssumeRole, error) { 64 if r == nil { 65 return nil, nil 66 } 67 68 duration, err := parseAssumeRoleDuration(r.Duration) 69 if err != nil { 70 return nil, err 71 } 72 73 err = validatePolicyARNs(r.PolicyARNs) 74 if err != nil { 75 return nil, err 76 } 77 78 assumeRole := &awsbase.AssumeRole{ 79 RoleARN: r.RoleARN, 80 Duration: duration, 81 ExternalID: r.ExternalID, 82 Policy: r.Policy, 83 PolicyARNs: r.PolicyARNs, 84 SessionName: r.SessionName, 85 Tags: r.Tags, 86 TransitiveTagKeys: r.TransitiveTagKeys, 87 } 88 return assumeRole, nil 89 } 90 func (r *AssumeRoleWithWebIdentity) asAWSBase() (*awsbase.AssumeRoleWithWebIdentity, error) { 91 if r == nil { 92 return nil, nil 93 } 94 95 if r.WebIdentityToken != "" && r.WebIdentityTokenFile != "" { 96 return nil, fmt.Errorf("conflicting config attributes: only web_identity_token or web_identity_token_file can be specified, not both") 97 } 98 99 duration, err := parseAssumeRoleDuration(r.Duration) 100 if err != nil { 101 return nil, err 102 } 103 104 err = validatePolicyARNs(r.PolicyARNs) 105 if err != nil { 106 return nil, err 107 } 108 109 return &awsbase.AssumeRoleWithWebIdentity{ 110 RoleARN: stringAttrEnvFallback(r.RoleARN, "AWS_ROLE_ARN"), 111 Duration: duration, 112 Policy: r.Policy, 113 PolicyARNs: r.PolicyARNs, 114 SessionName: stringAttrEnvFallback(r.SessionName, "AWS_ROLE_SESSION_NAME"), 115 WebIdentityToken: stringAttrEnvFallback(r.WebIdentityToken, "AWS_WEB_IDENTITY_TOKEN"), 116 WebIdentityTokenFile: stringAttrEnvFallback(r.WebIdentityTokenFile, "AWS_WEB_IDENTITY_TOKEN_FILE"), 117 }, nil 118 }