auth/auth.go (78 lines of code) (raw):

/* * Package responsible for returning an AWS SDK session with credentials * given an AWS region, K8s namespace, and K8s service account. * * This package requries that the K8s service account be associated with an IAM * role via IAM Roles for Service Accounts (IRSA). */ package auth import ( "context" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" "github.com/aws/aws-sdk-go/service/sts/stsiface" "github.com/aws/secrets-store-csi-driver-provider-aws/credential_provider" k8sv1 "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/klog/v2" ) const ( ProviderName = "secrets-store-csi-driver-provider-aws" ) // Auth is the main entry point to retrieve an AWS session. The caller // initializes a new Auth object with NewAuth passing the region, namespace, pod name, // K8s service account and usePodIdentity flag (and request context). The caller can then obtain AWS // sessions by calling GetAWSSession. type Auth struct { region, nameSpace, svcAcc, podName, preferredAddressType string usePodIdentity bool k8sClient k8sv1.CoreV1Interface stsClient stsiface.STSAPI ctx context.Context } // Factory method to create a new Auth object for an incomming mount request. func NewAuth( ctx context.Context, region, nameSpace, svcAcc, podName, preferredAddressType string, usePodIdentity bool, k8sClient k8sv1.CoreV1Interface, ) (auth *Auth, e error) { var stsClient stsiface.STSAPI if !usePodIdentity { // Get an initial session to use for STS calls when using IRSA sess, err := session.NewSession(aws.NewConfig(). WithSTSRegionalEndpoint(endpoints.RegionalSTSEndpoint). WithRegion(region), ) if err != nil { return nil, err } stsClient = sts.New(sess) } return &Auth{ region: region, nameSpace: nameSpace, svcAcc: svcAcc, podName: podName, preferredAddressType: preferredAddressType, usePodIdentity: usePodIdentity, k8sClient: k8sClient, stsClient: stsClient, ctx: ctx, }, nil } // Get the AWS session credentials associated with a given pod's service account. // // The returned session is capable of automatically refreshing creds as needed // by using a private TokenFetcher helper. func (p Auth) GetAWSSession() (awsSession *session.Session, e error) { var credProvider credential_provider.CredentialProvider if p.usePodIdentity { klog.Infof("Using Pod Identity for authentication in namespace: %s, service account: %s", p.nameSpace, p.svcAcc) var err error credProvider, err = credential_provider.NewPodIdentityCredentialProvider(p.region, p.nameSpace, p.svcAcc, p.podName, p.preferredAddressType, p.k8sClient) if err != nil { return nil, err } } else { klog.Infof("Using IAM Roles for Service Accounts for authentication in namespace: %s, service account: %s", p.nameSpace, p.svcAcc) credProvider = credential_provider.NewIRSACredentialProvider(p.stsClient, p.region, p.nameSpace, p.svcAcc, p.k8sClient, p.ctx) } config, err := credProvider.GetAWSConfig() if err != nil { return nil, err } // Include the provider in the user agent string. sess, err := session.NewSession(config) if err != nil { return nil, err } sess.Handlers.Build.PushFront(func(r *request.Request) { request.AddToUserAgent(r, ProviderName) }) return session.Must(sess, err), nil }