Access DynamoDB using IAM Role for Service Accounts

Access DynamoDB using IAM Role for Service Accounts

Overview

This tutorial will enable any developer or an administrator to configure an IAM role for Kubernetes service accounts (IRSA) in EKS which could then be used to configure fine grained access to Dynamo database from the Curity Identity Server.

IRSA allows for fine grained permissions restricted to a service account which is then tied to the Curity Identity Server running in a pod in a Kubernetes cluster unlike assigning IAM roles to EC2 instances (Kubernetes nodes).

The problem with assigning IAM roles to EC2 instances is that it violates the least privilege principle since any application (pod) running on the EC2 instance will have access to the resources granted by the IAM role which could result in undesirable behavior.

On the other hand, using IRSA has following benefits:

  • IRSA allows you to create fine grained IAM policies defining the exact access required and only the pods that use the particular service account can access the resources granted by the IAM role/policies.
  • Since no other pod(s) running on the same EC2 instance can access the security credentials, the access credentials retrieved from the AWS Secure token service (STS) are only available to the containers running in the pod. This provides strong credential isolation.
  • AWS services like cloudwatch and cloudtrail could be enabled to generate audit logs for the permission usage.

Use IRSA as the DynamoDB access method when integrating the Curity Identity Server in EKS with a DynamoDB to implement the principal of least privilege.

EKS version support

Support for IAM role for service accounts is available in AWS EKS version 1.13 or higher.

DynamoDB Access Methods

The Curity Identity Server provides several methods to access DynamoDB :

  • AWS Secret key identifier and secret
  • AWS Config Profile
  • AWS EC2 instance metadata service
  • Default credential provider
  • Web Identity token credentials aka IAM role for service accounts

This article provides instructions on how to use Web Identity token credentials and configure IAM role for service accounts DynamoDB access method.

Service Account Setup Configuration

To use IAM roles for service accounts, an OIDC provider must be created first and associated with the EKS cluster where the Curity Identity Server is deployed.

1. Get the OIDC provider URL

aws eks describe-cluster --name curity-dynamo-irsa --query "cluster.identity.oidc.issuer" --output text 

The above command returns the OIDC provider URL, e.g., https://oidc.eks.eu-west-1.amazonaws.com/id/25C49CB104xxxxxxxxxxx

2. Check if the EKS cluster is already associated with the IAM OIDC provider

oidc_provider_id=$(aws eks describe-cluster --name curity-dynamo-irsa --region eu-west-1 --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
aws iam list-open-id-connect-providers | grep $oidc_provider_id

If the oidc_provider_id is available in the list of open-id-connect-providers, then the EKS cluster is already associated with an IAM OIDC provider, and you can skip the next step.

3. Associate EKS cluster with the IAM OIDC provider

eksctl utils associate-iam-oidc-provider --cluster curity-dynamo-irsa --approve

Next step is to create a fine-grained IAM policy and a Kubernetes service account.

4. Create an IAM policy and define the needed permissions

The following IAM policy json provides full permissions to DynamoDB tables pre-fixed with curity-

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Sid": "AllAPIActionsAllowed",
          "Effect": "Allow",
          "Action": [
              "dynamodb:*"
          ],
          "Resource": "arn:aws:dynamodb:*:*:table/curity-*"
      }   
  ]
}

The following command creates the IAM policy in the AWS account and stores the policy ARN in the variable called dynamo_iam_policy

dynamo_iam_policy=$(aws iam create-policy --policy-name dynamo-iam-policy --policy-document file://dynamo-iam-policy.json | jq -r '.Policy.Arn') 

5. Create an IAM Role and bind it to the service account

Run the following command to create the Kubernetes service account using the eksctl tool

  eksctl create iamserviceaccount \
    --name dynamo-sa \
    --namespace curity \ # namespace where the Curity Identity Server is deployed.
    --cluster curity-dynamo-irsa \
    --attach-policy-arn "$dynamo_iam_policy" \
    --approve

The above command creates a service account, binds it to an IAM role, and adds the policy dynamo_iam_policy to that role.

Multiple IAM policies

You can specify multiple --attach-policy-arn flags to add more than one IAM policy to the IAM role

6. Verify the service account creation

kubectl --namespace curity get sa dynamo-sa --output yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxxxxxx:role/eksctl-curity-dynamo-irsa-addon-iamserviceac-Role1-1G3T9FCM6PSAD 
  creationTimestamp: "2022-08-23T05:20:30Z"
  labels:
    app.kubernetes.io/managed-by: eksctl
  name: dynamo-sa
  namespace: curity
  resourceVersion: "193383"
  uid: a8f5ced4-a403-416a-acbc-70e772a9fdc6
secrets:
- name: dynamo-sa-token-hrfcd

The service account annotation eks.amazonaws.com/role-arn contains the ARN of the newly created IAM role. You could verify the IAM role and associated permissions by searching for the IAM role in AWS Administration Console and inspecting the details.

7. Bind the service account to the runtime deployment of the Curity Identity Server.

kubectl -n curity set serviceaccount deployment curity-idsvr-runtime dynamo-sa

After binding the service account to the Curity Identity Server, the Amazon EKS Pod Identity Webhook injects several environment variables into the pod.

List the environment variables with the following command:

kubectl --namespace curity get pod curity-idsvr-runtime-xxxxxxx -o yaml
apiVersion: v1
kind: Pod
...
spec:
  containers:
  - args:
    - /opt/idsvr/bin/idsvr
    - -s
    - default
    - --no-admin
    env:
    ...
    - name: AWS_STS_REGIONAL_ENDPOINTS
      value: regional
    - name: AWS_DEFAULT_REGION
      value: eu-west-1
    - name: AWS_REGION
      value: eu-west-1
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::xxxxxxx:role/eksctl-curity-dynamo-irsa-addon-iamserviceac-Role1-1G3T9FCM6PSAD
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
...

These environment variables allow AWS SDK to perform the sts:AssumeRoleWithWebIdentity call to get temporary credentials to access DynamoDB from the Curity Identity Server.

Summary

You have learned how to create Web Identity token credentials in Kubernetes and benefit from the enhanced security provided by the IAM role for Kubernetes service accounts. For further details about using DynamoDB with the Curity Identity Server, please refer to the product documentation.