<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
## EKS Pod Identity
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### About me
https://rewanthtammana.com/
Rewanth Tammana is a security ninja, open-source contributor, & independent consultant. Previously, Senior Security Architect at Emirates NBD. Passionate about DevSecOps, Application, and Container Security. Added 17,000+ lines of code to Nmap. Holds industry certifications like CKS, CKA, etc.
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### About me
https://twitter.com/rewanthtammana
Speaker & trainer at international security conferences worldwide including Black Hat, Defcon, Hack In The Box (Dubai and Amsterdam), CRESTCon UK, PHDays, Nullcon, Bsides, CISO Platform, null chapters and multiple others.
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### About me
https://linkedin.com/in/rewanthtammana
One of the MVP researchers on Bugcrowd (2018) and identified vulnerabilities in several organizations. Published an IEEE research paper on an offensive attack in Machine Learning and Security. Also, part of the renowned Google Summer of Code program.
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Topics of interest
* Eagles view on Kubernetes, managed vs self-hosted
* Least privilege access in EKS
* IRSA vs EKS Pod Identity
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Kubernetes

[Reference](https://mohan08p.medium.com/simplified-kubernetes-architecture-3febe12480eb)
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Self hosted vs managed Kubernetes

[Reference](https://www.capgemini.com/us-en/insights/expert-perspectives/run-your-own-or-managed-kubernetes-why-microsoft-aks-may-be-the-right-orchestration-platform-for-you/)
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Kubernetes

[Reference](https://www.quobyte.com/storage-explained/what-is-kubernetes/)
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### EKS/cloud managed service
| Component | Managed By |
|---|---|
| Control Plane | Cloud Provider |
| Worker Nodes | End User |
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Securing EKS
Different components to secure
* IAM
* Logging
* Secrets Management
* Monitoring
* Encryption
* Misconfigurations
* Network Policy
* ...
* ......
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create EKS cluster
How many use AWS CLI?
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### EKSCTL
```bash
eksctl create cluster
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
## Least privilege access
* Ensuring least-privilege access in Kubernetes can be complex.
* RBAC is decent for Kubernetes specific operations but when Kubernetes has to connect with external resources, it's not the best solution.
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
## Kubernetes RBAC

[Reference](https://engineering.dynatrace.com/blog/kubernetes-security-part-1-role-based-access-control-rbac/)
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Use case
An application running on Kubernetes fetching random images from the internet every 30 seconds and uploading them to an S3 bucket.
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### How would you do it?
* Using IAM User Credentials through Environment Variables <!-- .element: class="fragment" -->
* Assign permissions to the EKS worker nodes <!-- .element: class="fragment" -->
* IAM Roles for Service Accounts (IRSA) <!-- .element: class="fragment" -->
* [NEW - Re:Invent 2023] EKS Pod Identity <!-- .element: class="fragment" -->
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### IRSA
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### OIDC (OpenID Connect)
OIDC is an identity protocol that utilizes the authorization and authentication mechanisms of OAuth 2.0
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### AWS IAM OpenID Connect provider
* Helps to keep AWS account secure
* No need to distribute or embed long-term security credentials, such as access keys, in your application
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### OIDC (OpenID Connect)

[Reference](https://youtu.be/CPbvxxslDTU)
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Check IAM OIDC provider status
```bash
eksctl get cluster $cluster_name -ojson | jq -r '.[].Tags["alpha.eksctl.io/cluster-oidc-enabled"]'
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create IAM OIDC provider
```bash
eksctl utils associate-iam-oidc-provider --cluster $cluster_name --approve
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create an IAM service account with s3 write policy
```bash
eks_service_account=s3-write-service-account
eksctl create iamserviceaccount --name $eks_service_account --namespace default --cluster $cluster_name --attach-policy-arn $policy_arn --approve
```
<!--  -->
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create an IAM service account with s3 write policy

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create Kubernetes Job
```bash
echo "apiVersion: batch/v1
kind: Job
metadata:
name: environment-variables-job
spec:
template:
spec:
serviceAccountName: $eks_service_account
containers:
- name: environment-variables-container
image: rewanthtammana/secure-eks:ok-amd64
env:
- name: AWS_REGION
value: us-east-1
- name: S3_BUCKET_NAME
value: $bucket_name
restartPolicy: Never" | kubectl apply -f-
```
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create Kubernetes Job

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
## CloudFormation, JWT, X509 & more
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine CloudFormation of IAM SA

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine CloudFormation of IAM SA

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine service account
```bash
kubectl get sa $eks_service_account -oyaml
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine secrets associated with the service account
```bash
sa_secret_name=$(kubectl get sa $eks_service_account -ojson | jq -r '.secrets[0].name')
kubectl get secrets $sa_secret_name -oyaml
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine X.509 ca.crt in the secret associated with the service account
```bash
kubectl get secret $sa_secret_name -o json | jq -r '.data."ca.crt"' | base64 -d
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Check the subject & issuer of the certificate
```bash
openssl x509 -in certificate.pem -subject -issuer -noout
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Check the expiry of the certificate
```bash
openssl x509 -in certificate.pem -dates -noout
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine the token in the secret associated with the service account
```bash
kubectl get secret $sa_secret_name -o json | jq -r '.data."token"' | base64 -d
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine the JWT token in jwt.io

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Pros
Really good & best way to achieve least privilege access controls
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Cons
Cons - Managing it can get tricky and hard

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### EKS Pod Identity
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Enable the add on
```bash
eksctl create addon --name eks-pod-identity-agent --cluster $CLUSTER_NAME
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Daemonset
```bash
kubectl get ds -A
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Get Pod Identity Association
```bash
export CLUSTER_NAME=pod-identity-demo
eksctl get podidentityassociation --cluster $CLUSTER_NAME
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create Pod Identity Association
```bash
export SERVICE_ACCOUNT_NAME=anything
eksctl create podidentityassociation --cluster $CLUSTER_NAME --namespace default --service-account-name $SERVICE_ACCOUNT_NAME --permission-policy-arns $policy_arn
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create AWS Policy
```bash
export BUCKET_NAME=random-pod-identity-demo
echo "{
\"Version\": \"2012-10-17\",
\"Statement\": [
{
\"Effect\": \"Allow\",
\"Action\": [
\"s3:PutObject\"
],
\"Resource\": [
\"arn:aws:s3:::$BUCKET_NAME/*\"
]
}
]
}" > s3-$BUCKET_NAME-access.json
export POLICY_NAME=pod-identity-bucket-s3-write-policy
export create_policy_output=$(aws iam create-policy --policy-name $POLICY_NAME --policy-document file://s3-$BUCKET_NAME-access.json)
export policy_arn=$(echo $create_policy_output | jq -r '.Policy.Arn')
echo $policy_arn
```
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create AWS Policy

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Create Kubernetes Job
```bash
aws s3 mb s3://$BUCKET_NAME --region us-east-1
kubectl create sa $SERVICE_ACCOUNT_NAME
echo "apiVersion: batch/v1
kind: Job
metadata:
name: pod-identity-demo
spec:
template:
spec:
serviceAccountName: $SERVICE_ACCOUNT_NAME
containers:
- name: pod-identity-demo-container
image: rewanthtammana/secure-eks:pod-identity-demo
env:
- name: AWS_REGION
value: us-east-1
- name: S3_BUCKET_NAME
value: $BUCKET_NAME
restartPolicy: Never" | kubectl apply -f-
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Check job status
```bash
kubectl get jobs
kubectl get po -l job-name=pod-identity-demo
kubectl logs -l job-name=pod-identity-demo
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine Cloudformation
```bash
aws cloudformation describe-stack-resources --stack-name eksctl-pod-identity-demo-podidentityrole-ns-default-sa-anything
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Examine Role & Policy
```bash
export role_name=$(aws cloudformation describe-stack-resources --stack-name eksctl-pod-identity-demo-podidentityrole-ns-default-sa-anything | jq -r '.StackResources[].PhysicalResourceId')
echo $role_name
aws iam list-attached-role-policies --role-name $role_name
```

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### IRSA vs EKS Pod Identity

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Inside of Application Pod

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Inside of Pod Identity Webhook
```bash
kubectl get ds -n kube-system eks-pod-identity-agent -oyaml
```
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Inside of Pod Identity Webhook

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Quiz Time
We created service accounts & let them assume a role with IRSA.
* What about non-EKS clusters? Self-hosted services on AWS?
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Non-EKS clusters on AWS
* [Zalando IAM Controller](https://github.com/zalando-incubator/kube-aws-iam-controller)
* [Kiam](https://github.com/uswitch/kiam)
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Zalando
Using custom Assume role
```
+-------------+
| |
+--> | <app-role1> |
+-----------------+ +-------------------+ | | |
| | | | | +-------------+
| <instance-role> | -- assumes --> | <controller-role> | -- assumes --+
| | | | | +-------------+
+-----------------+ +-------------------+ | | |
+--> | <app-role2> |
| |
+-------------+
```
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Recap

---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Additional resources
[Securing AWS EKS: Implementing Least-Privilege Access with IRSA](https://blog.rewanthtammana.com/securing-aws-eks-implementing-least-privilege-access-with-irsa)
[Rethinking Authentication: AWS ReInvent 2023 Unveils EKS Pod Identity](https://blog.rewanthtammana.com/rethinking-authentication-aws-reinvent-2023-unveils-eks-pod-identity)
[Github - Secure EKS](https://github.com/rewanthtammana/secure-eks)
---
<!-- .slide: data-background="https://hackmd.io/_uploads/HJx9kGiLT.png"-->
<!-- .slide: data-transition="zoom" -->
### Thank You!

Google: [Rewanth Tammana](https://www.google.com/search?q=rewanth+tammana&sca_esv=575386901&sxsrf=AM9HkKmnGZBGWzwOS8jWMPYp_YgzN4l8og%3A1697865818064&source=hp&ei=WmAzZbizAeHk1e8Pt5ygiA4&iflsig=AO6bgOgAAAAAZTNuas_v-XYaB2vpwWaiYRGIPtXHOTZW&ved=0ahUKEwi4yNaHs4aCAxVhcvUHHTcOCOEQ4dUDCAo&uact=5&oq=rewanth+tammana&gs_lp=Egdnd3Mtd2l6Ig9yZXdhbnRoIHRhbW1hbmEyBhAAGBYYHkjxC1AAWOsKcAB4AJABAJgB3gGgAagSqgEGMC4xMy4xuAEDyAEA-AEBwgIHECMYigUYJ8ICCBAAGIoFGJECwgIREC4YgAQYsQMYgwEYxwEY0QPCAgsQABiABBixAxiDAcICCxAuGIAEGLEDGIMBwgILEC4YigUYsQMYgwHCAg4QABiKBRixAxiDARiRAsICCBAAGIAEGLEDwgILEAAYigUYsQMYgwHCAggQLhixAxiABMICCxAuGIAEGMcBGNEDwgIFEAAYgATCAgUQLhiABMICCxAuGIAEGMcBGK8BwgIHEAAYgAQYCsICDRAuGIAEGLEDGIMBGArCAgoQLhixAxiABBgKwgINEAAYgAQYsQMYgwEYCsICBxAuGIAEGArCAgcQABgNGIAEwgIHEC4YDRiABMICCRAAGA0YgAQYCsICCRAuGA0YgAQYCsICBhAAGB4YDcICCBAAGAUYHhgNwgIIEAAYCBgeGA3CAgoQABgIGB4YDRgK&sclient=gws-wiz)
Website: [rewanthtammana.com](https://rewanthtammana.com/)
{"title":"EKS Pod Identity","description":"EKS Pod Identity","contributors":"[{\"id\":\"c83db8ee-5e83-4b4d-ab67-7ab40f2ab65a\",\"add\":37889,\"del\":53324}]"}