A lightweight proxy server that exposes AWS IAM credentials from a Kubernetes pod using IRSA (IAM Role for ServiceAccount) through a simple HTTP API compatible with AWS credential_process.
- Exposes temporary AWS credentials via HTTP API
- Compatible with AWS credential_process in .aws/config
- Supports optional security features:
- Bearer token authentication
- IP whitelisting
- Health check endpoint
- Graceful shutdown
- Minimal container image
- Add the Helm repository:
helm repo add kotaicode https://kotaico.de/iam-proxy
helm repo update
- Create a values file (e.g.,
my-values.yaml
):
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/YOUR_ROLE_NAME
config:
securityToken: "your-secure-token" # Optional
allowedIPs: # Optional
- "10.0.0.0/8"
- "172.16.0.0/12"
- Install the chart:
helm install iam-proxy kotaicode/iam-proxy -f my-values.yaml
For more configuration options, see the values.yaml file.
You can run the proxy directly using Docker. Choose the appropriate image for your architecture:
For AMD64:
docker run -p 8080:8080 \
-e SECURITY_TOKEN=your-secure-token \
-e ALLOWED_IPS=10.0.0.0/8,172.16.0.0/12 \
ghcr.io/kotaicode/iam-proxy:latest-amd64
For ARM64:
docker run -p 8080:8080 \
-e SECURITY_TOKEN=your-secure-token \
-e ALLOWED_IPS=10.0.0.0/8,172.16.0.0/12 \
ghcr.io/kotaicode/iam-proxy:latest-arm64
Here's a practical example of setting up and using the IAM proxy:
- Create a service account with the desired IAM role:
# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: iam-proxy
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/YOUR_ROLE_NAME
kubectl apply -f serviceaccount.yaml
- Run the proxy pod with the service account:
kubectl run iam-proxy --rm -i --tty \
--image ghcr.io/kotaicode/iam-proxy:latest-amd64 \
--serviceaccount=iam-proxy \
--port=8080
- Forward the pod's port to your local machine:
kubectl port-forward pod/iam-proxy 8080:8080
- Test the credentials endpoint:
curl -s http://localhost:8080/credentials
You should see the temporary AWS credentials in the response. These credentials will have the permissions associated with the IAM role specified in the service account annotation.
Environment variables:
PORT
: Server port (default: 8080)LOG_LEVEL
: Logging level (default: info)SECURITY_TOKEN
: Bearer token for authentication (optional)ALLOWED_IPS
: Comma-separated list of allowed IP addresses (optional)
Add to your ~/.aws/config
:
[profile irsa-proxy]
credential_process = curl -s -H "Authorization: Bearer your-secure-token" http://localhost:8080/credentials
region = eu-central-1
- Go 1.21 or later
- Docker
- Task (optional, for using Taskfile)
- Helm (for local development)
# Using Task
task build
# Or manually
go build -o bin/iam-proxy ./cmd/main.go
# Using Task
task run
# Or manually
./bin/iam-proxy
task test
# Build image
task docker
# Push to GitHub Container Registry
task docker-push
- Install GoReleaser:
brew install goreleaser
- Test the release process:
task release-dry-run
- Create a new release:
VERSION=0.1.0 task release
This will:
- Create and push a version tag
- Trigger GitHub Actions workflow
- Build binaries for multiple platforms
- Create Docker images
- Create a GitHub release with all artifacts
- Install dependencies:
helm dependency update helm/iam-proxy
- Test the chart:
helm lint helm/iam-proxy
helm template iam-proxy helm/iam-proxy -f examples/values.yaml
- Install locally:
helm install iam-proxy helm/iam-proxy -f examples/values.yaml
- Always use HTTPS in production
- Configure IP whitelisting when possible
- Use a strong security token
- Consider using client certificates for additional security
- Monitor access logs for suspicious activity
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.