Skip to content

Commit af29a75

Browse files
wcrumTylerGillson
andcommitted
feat: Add AWS STS authentication method for AWS validation (#129)
* Initial Commit * Update aws.go Updates time.Duration to time.Seconds * Move STS Struct, Update Comments * Update go.sum * Update Deepcopy and Comments * Seperate STS Authentication * Update Based on Review * Update CRD Validators --------- Signed-off-by: Will <30413278+wcrum@users.noreply.github.com> Signed-off-by: Tyler Gillson <tyler.gillson@gmail.com> Co-authored-by: Tyler Gillson <tyler.gillson@gmail.com>
1 parent debfe69 commit af29a75

6 files changed

Lines changed: 96 additions & 9 deletions

File tree

api/v1alpha1/awsvalidator_types.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ type AwsAuth struct {
4040
SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"`
4141
// Option 2: specify a service account (EKS)
4242
ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"`
43+
// STS authentication properties (optional, to be provided in conjunction with Option 1 or 2)
44+
StsAuth *AwsSTSAuth `json:"stsAuth,omitempty" yaml:"stsAuth,omitempty"`
45+
}
46+
47+
type AwsSTSAuth struct {
48+
// The Amazon Resource Name (ARN) of the role to assume.
49+
RoleArn string `json:"roleArn" yaml:"roleArn"`
50+
// An identifier for the assumed role session.
51+
RoleSessionName string `json:"roleSessionName" yaml:"roleSessionName"`
52+
// The duration, in seconds, of the role session.
53+
// +kubebuilder:default=3600
54+
// +kubebuilder:validation:Minimum=900
55+
// +kubebuilder:validation:Maximum=43200
56+
DurationSeconds int `json:"durationSeconds" yaml:"durationSeconds"`
57+
// A unique identifier that might be required when you assume a role in another account.
58+
ExternalId string `json:"externalId,omitempty" yaml:"externalId,omitempty"`
4359
}
4460

4561
type IamRoleRule struct {

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/validation.spectrocloud.labs_awsvalidators.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,32 @@ spec:
4242
serviceAccountName:
4343
description: 'Option 2: specify a service account (EKS)'
4444
type: string
45+
stsAuth:
46+
description: STS authentication properties (optional, to be provided
47+
in conjunction with Option 1 or 2)
48+
properties:
49+
durationSeconds:
50+
default: 3600
51+
description: The duration, in seconds, of the role session.
52+
maximum: 43200
53+
minimum: 900
54+
type: integer
55+
externalId:
56+
description: A unique identifier that might be required when
57+
you assume a role in another account.
58+
type: string
59+
roleArn:
60+
description: The Amazon Resource Name (ARN) of the role to
61+
assume.
62+
type: string
63+
roleSessionName:
64+
description: An identifier for the assumed role session.
65+
type: string
66+
required:
67+
- durationSeconds
68+
- roleArn
69+
- roleSessionName
70+
type: object
4571
type: object
4672
defaultRegion:
4773
type: string

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ go 1.20
44

55
require (
66
github.com/L30Bola/aws-policy v0.0.0-20230126045340-5e6118545ac1
7+
github.com/aws/aws-sdk-go-v2 v1.22.1
8+
github.com/aws/aws-sdk-go-v2/credentials v1.15.1
79
github.com/aws/aws-sdk-go-v2/config v1.22.0
810
github.com/aws/aws-sdk-go-v2/service/ec2 v1.130.0
11+
github.com/aws/aws-sdk-go-v2/service/sts v1.25.0
912
github.com/aws/aws-sdk-go-v2/service/efs v1.23.0
1013
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.20.0
1114
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.24.0
@@ -23,16 +26,13 @@ require (
2326
)
2427

2528
require (
26-
github.com/aws/aws-sdk-go-v2 v1.22.1 // indirect
27-
github.com/aws/aws-sdk-go-v2/credentials v1.15.1 // indirect
2829
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.2 // indirect
2930
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.1 // indirect
3031
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.1 // indirect
3132
github.com/aws/aws-sdk-go-v2/internal/ini v1.5.0 // indirect
3233
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.1 // indirect
3334
github.com/aws/aws-sdk-go-v2/service/sso v1.17.0 // indirect
3435
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.19.0 // indirect
35-
github.com/aws/aws-sdk-go-v2/service/sts v1.25.0 // indirect
3636
github.com/aws/smithy-go v1.16.0 // indirect
3737
github.com/beorn7/perks v1.0.1 // indirect
3838
github.com/cespare/xxhash/v2 v2.2.0 // indirect

internal/controller/awsvalidator_controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func (r *AwsValidatorReconciler) Reconcile(ctx context.Context, req ctrl.Request
8888
failed := &types.MonotonicBool{}
8989

9090
// IAM rules
91-
awsApi, err := aws_utils.NewAwsApi(validator.Spec.DefaultRegion)
91+
awsApi, err := aws_utils.NewAwsApi(r.Log, validator)
9292
if err != nil {
9393
r.Log.V(0).Error(err, "failed to get AWS client")
9494
} else {
@@ -126,7 +126,7 @@ func (r *AwsValidatorReconciler) Reconcile(ctx context.Context, req ctrl.Request
126126

127127
// Service Quota rules
128128
for _, rule := range validator.Spec.ServiceQuotaRules {
129-
awsApi, err := aws_utils.NewAwsApi(rule.Region)
129+
awsApi, err := aws_utils.NewAwsApi(r.Log, validator)
130130
if err != nil {
131131
r.Log.V(0).Error(err, "failed to reconcile Service Quota rule")
132132
continue
@@ -148,7 +148,7 @@ func (r *AwsValidatorReconciler) Reconcile(ctx context.Context, req ctrl.Request
148148

149149
// Tag rules
150150
for _, rule := range validator.Spec.TagRules {
151-
awsApi, err := aws_utils.NewAwsApi(rule.Region)
151+
awsApi, err := aws_utils.NewAwsApi(r.Log, validator)
152152
if err != nil {
153153
r.Log.V(0).Error(err, "failed to reconcile Tag rule")
154154
continue

internal/utils/aws/aws.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@ package aws
22

33
import (
44
"context"
5+
"time"
56

7+
"github.com/aws/aws-sdk-go-v2/aws"
68
"github.com/aws/aws-sdk-go-v2/config"
9+
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
710
"github.com/aws/aws-sdk-go-v2/service/ec2"
811
"github.com/aws/aws-sdk-go-v2/service/efs"
912
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
1013
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
1114
"github.com/aws/aws-sdk-go-v2/service/iam"
1215
"github.com/aws/aws-sdk-go-v2/service/servicequotas"
16+
"github.com/aws/aws-sdk-go-v2/service/sts"
17+
"github.com/go-logr/logr"
18+
"github.com/spectrocloud-labs/validator-plugin-aws/api/v1alpha1"
1319
)
1420

1521
type AwsApi struct {
@@ -22,11 +28,16 @@ type AwsApi struct {
2228
}
2329

2430
// NewAwsApi creates an AwsApi object that aggregates AWS service clients
25-
func NewAwsApi(region string) (*AwsApi, error) {
26-
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
31+
func NewAwsApi(log logr.Logger, validator *v1alpha1.AwsValidator) (*AwsApi, error) {
32+
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithDefaultRegion(validator.Spec.DefaultRegion))
2733
if err != nil {
2834
return nil, err
2935
}
36+
37+
if validator.Spec.Auth.StsAuth != nil {
38+
awsStsConfig(&cfg, validator.Spec.Auth.StsAuth)
39+
}
40+
3041
return &AwsApi{
3142
IAM: iam.NewFromConfig(cfg),
3243
EC2: ec2.NewFromConfig(cfg),
@@ -36,3 +47,17 @@ func NewAwsApi(region string) (*AwsApi, error) {
3647
SQ: servicequotas.NewFromConfig(cfg),
3748
}, nil
3849
}
50+
51+
func awsStsConfig(cfg *aws.Config, auth *v1alpha1.AwsSTSAuth) {
52+
creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(*cfg), auth.RoleArn, func(o *stscreds.AssumeRoleOptions) {
53+
o.Duration = time.Duration(auth.DurationSeconds) * time.Second
54+
o.RoleSessionName = auth.RoleSessionName
55+
56+
if auth.ExternalId != "" {
57+
o.ExternalID = &auth.ExternalId
58+
}
59+
60+
})
61+
62+
cfg.Credentials = aws.NewCredentialsCache(creds)
63+
}

0 commit comments

Comments
 (0)