Authentication and Credentials

Understanding AWS credentials in ACK

When an ACK service controller communicates with an AWS service API, the controller uses a set of AWS Credentials.

This document explains the process by which these credentials are determined by the ACK service controller and how ACK users can configure the ACK service controller to use a particular set of credentials.

Background

Each ACK service controller uses the aws-sdk-go library to call the AWS service APIs.

When initiating communication with an AWS service API, the ACK controller creates a new aws-sdk-go Session object. This Session object is automatically configured during construction by code in the aws-sdk-go library that looks for credential information in the following places, in this specific order:

  1. If the AWS_PROFILE environment variable is set, find that specified profile in the configured credentials file and use that profile’s credentials.

  2. If the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are both set, these values are used by aws-sdk-go to set the AWS credentials.

  3. If the AWS_WEB_IDENTITY_TOKEN_FILE environment variable is set, aws-sdk-go will load the credentials from the JSON web token (JWT) present in the file pointed to by this environment variable. Note that this environment variable is set to the value /var/run/secrets/eks.amazonaws.com/serviceaccount/token by the IAM Roles for Service Accounts (IRSA) pod identity webhook and the contents of this file are automatically rotated by the webhook with temporary credentials.

  4. If there is a credentials file present at the location specified in the AWS_SHARED_CREDENTIALS_FILE environment variable (or $HOME/.aws/credentials if empty), aws-sdk-go will load the “default” profile present in the credentials file.

Configuring credentials

There are multiple ways in which you can configure an ACK service controller to use a particular set of AWS credentials:

  • Web identity token file (recommended)
  • Shared credentials file
  • Access key and secret access key environment variables (not recommended)
Understand the AWS credentials file format
It is important to understand the AWS credentials file format, especially if you choose not to use the web identity token file method of credential configuration.

Our recommended approach for configuring the AWS credentials that an ACK service controller will use to communicate with AWS services is to use the IAM Roles for Service Accounts (IRSA) functionality provided by the IAM Pod Identity Webhook and OIDC connector.

Using IRSA means that you only need to configure the IAM Role that is associated with the Kubernetes Service Account of the ACK service controller’s Kubernetes Pod. The Pod Identity Webhook will be responsible for automatically injecting and periodically rotating the web identity token file into your ACK service controller’s Pod.

Learn how to configure IRSA.

Understand the AWS credentials file format
IRSA is enabled and installed on EKS clusters by default, however must be manually configured if you are using a non-EKS cluster. See the IRSA self-hosted documentation for information about installing the pod identity webhook in non-EKS clusters.

Use a shared credentials file

If you are not using IAM Roles for Service Accounts (IRSA) or are running in an environment where IRSA isn’t feasible (such as running KinD clusters within Kubernetes Pods using Docker-in-Docker), you can choose to instruct the ACK service controller to use AWS credentials found in a shared credentials file.

When using a shared credentials file, the ACK service controller will need read access to a known credentials file location.

If you do not set the AWS_SHARED_CREDENTIALS_FILE environment variable, the controller will look for a readable file at $HOME/.aws/credentials.

Practically, this means that the Deployment spec you use to deploy the ACK service controller should have a volume mount that mounts a readonly file containing the credentials file.

Let’s assume you have stored your local AWS credentials file content in a Kubernetes Secret named aws-creds:

CREDS_CONTENT=$(cat ~/.aws/credentials)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: aws-creds
type: Opaque
stringData:
  credentials-file: |
  $CREDS_CONTENT
EOF

You would want to mount a readonly volume into the Deployment for your ACK service controller. Here’s how you might do this for a sample ACK controller:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ack-s3-controller
spec:
  replicas: 1
  template:
    spec:
      containers:
      - command:
        - ./bin/controller
        image: controller:latest
        name: controller
        ports:
          - name: http
            containerPort: 8080
        resources:
          limits:
            cpu: 100m
            memory: 300Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: aws-creds
          mountPath: "/root/.aws/credentials"
          readOnly: true
      volumes:
      - name: aws-creds
        secret:
          secretName: aws-creds

You can instruct the service controller to use a specific profile within the shared credentials file by setting the AWS_PROFILE environment variable for the Pod:

      env:
        - name: AWS_PROFILE
          value: my-profile

Finally, you can choose to manually set the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and optionally the AWS_SESSION_TOKEN environment variables on the ACK service controller’s Pod:

kubectl -n ack-system set env deployment/ack-s3-controller \
    AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" \
    AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" \
    AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN"

Edit this page on GitHub