Authenticate in LDAP Server using AWS EKS tokens. Like aws-iam-authenticator, but for LDAP.
- Validates EKS tokens by calling AWS STS
 - Enforces allowed ARN prefixes
 - Extracts LDAP identity from ARN
 - Optional DN suffix and CN prefix checks for strict Bind DN validation
 - Lightweight LDAP server
 
It works just like aws-iam-authenticator.
- Client performs LDAP Bind with DN 
<prefix><username>[,ou=<group>]<suffix>and password set to an EKS token (k8s-aws-v1.<...>). - Server validates LDAP DN against configured suffix.
 - Server decodes the token to a presigned STS URL, validates it, and calls STS with 
x-k8s-aws-id=<EKS_CLUSTER_ID>. - Server validates STS address against allowlist.
 - On success, server receives the caller ARN and validates it against configured rules (prefixes).
 - Server tries to extract LDAP identity from ARN and validates it against configured rules (cn, ou).
 
Configure via environment variables:
EKS_CLUSTER_ID(required): EKS cluster name/ID used in thex-k8s-aws-idheaderSTS_HOSTS(optional, comma-separated): Allowlist of STS origins. Default:https://sts.amazonaws.comARN_PREFIXES(optional, comma-separated): Allowed ARN prefixes. Default:arn:aws:LDAP_HOST(optional): Listen host. Default:0.0.0.0LDAP_PORT(optional): Listen port. Default:3893LDAP_SUFFIX(optional): Suffix that must match the Bind DN, e.g.,dc=evil,dc=corpLDAP_PREFIX(optional): Required CN prefix in Bind DN, e.g.cn=aws_iam_LOG_LEVEL(optional):debug|info|warn|error. Default:infoREQUEST_TIMEOUT_SECONDS(optional): STS request timeout. Default:10
Requirements: Go 1.21+
go build -o dist/aws-ldap-authenticator ./cmd/aws-ldap-authenticatorTo build docker image:
goreleaser release --snapshot --cleanImage will be named as goreleaser.ko.local:0.1.0-SNAPSHOT-XXX
export EKS_CLUSTER_ID="my-eks-cluster"
export STS_HOSTS="https://sts.eu-central-1.amazonaws.com"
export ARN_PREFIXES="arn:aws:"
export LDAP_PREFIX="cn=aws_iam_"
export LDAP_SUFFIX=",dc=evil,dc=corp"
./dist/aws-ldap-authenticatorIt listens on LDAP_HOST:LDAP_PORT (default 0.0.0.0:3893).
You can also use air to run the server with hot reloading. Place .env file in the root directory and run air. Ensure that the .env file is respected. I use mise for this.
Install via the published Helm chart (Helm 3):
helm repo add aws-ldap-authenticator https://rgeraskin.github.io/aws-ldap-authenticator/
helm repo update
helm install aws-ldap-authenticator aws-ldap-authenticator/aws-ldap-authenticator \
  --create-namespace --namespace aws-ldap-authenticator \
  --version 0.1.0- 
Bring up Postgres with Docker and configure LDAP in
pg_hba.confto point to this authenticator. Seedocker-compose.ymlfor the example configuration.pg_hba.confhost rule looks like this:host all /^aws_iam_.+ all ldap ldapurl="ldap://host.docker.internal:3893" ldapprefix="cn=" ldapsuffix=",dc=evil,dc=corp"Restart Postgres after editing
pg_hba.conf. - 
Create a user in Postgres with
CREATE USER aws_iam_john.doe; - 
Start the server with
./dist/aws-ldap-authenticatorwith example environment variables like in the example above. - 
Get token with
TOKEN=$(aws eks get-token --cluster-name my-eks-cluster --query 'status.token' --output text) - 
Login to Postgres with
PGPASSWORD="$TOKEN" pgcli -h 127.0.0.1 -p 5432 postgres -U aws_iam_john.doe 
Use with Postgres in Kubernetes (CNPG)
CNPG operator should be installed in advance.
- Deploy the server with Helm:
helm repo add aws-ldap-authenticator https://rgeraskin.github.io/aws-ldap-authenticator/ helm repo update helm install aws-ldap-authenticator aws-ldap-authenticator/aws-ldap-authenticator \ --create-namespace --namespace aws-ldap-authenticator \ --version 0.1.0
 - Deploy the Postgres cluster with Helm. See cnpg-values.yaml for the example configuration.
helm repo add cnpg https://cloudnative-pg.github.io/charts helm repo update helm install cnpg-cluster cnpg/cluster -f cnpg-values.yaml
 - Get token with 
TOKEN=$(aws eks get-token --cluster-name my-eks-cluster --query 'status.token' --output text) - Login to Postgres with 
PGPASSWORD="$TOKEN" pgcli -h <CNPG_LB_IP> -p 5432 postgres -U aws_iam_john.doe 
Possible ARN formats:
| name | description | example | format | cn | ou | 
|---|---|---|---|---|---|
| Root User | Using the AWS root account credentials (not advised) | arn:aws:iam::123456789012:root | 
arn:aws:iam::<account-id>:root | 
root | 
(empty) | 
| IAM User | Logged in with long-term access keys of an IAM user | arn:aws:iam::123456789012:user/jane.doe | 
arn:aws:iam::<account-id>:user/<user-name> | 
jane.doe | 
(empty) | 
| IAM Role (Assumed) | When calling with temporary creds from sts:AssumeRole | arn:aws:sts::123456789012:assumed-role/AdminRole/Alice | 
arn:aws:sts::<account-id>:assumed-role/<role-name>/<session-name> | 
Alice | 
AdminRole | 
| Cross-Account Role (Assumed) | When assuming a role in another AWS account | arn:aws:sts::123456789012:assumed-role/AdminRole/Alice | 
arn:aws:sts::<account-id>:assumed-role/<role-name>/<session-name> | 
Alice | 
AdminRole | 
| Federated User | Temporary creds from SAML, OIDC, or custom federation | arn:aws:sts::123456789012:federated-user/GoogleOIDC:jane | 
arn:aws:sts::<account-id>:federated-user/<user-name> | 
jane | 
(empty) | 
| Service-Linked Role | When AWS services assume roles on your behalf | arn:aws:iam::123456789012:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling | 
arn:aws:iam::<account-id>:role/aws-service-role/<service-name><role-name> | 
AWSServiceRoleForAutoScaling | 
autoscaling.amazonaws.com/ | 
If LDAP_SUFFIX is set, the DN must end with it. If an ou is present, it must equal the role/group extracted from the ARN. No additional RDNs are allowed.
- Only allow trusted STS endpoints via 
STS_HOSTS - Allow only trusted ARN prefixes via 
ARN_PREFIXES - Prefer running behind a network boundary or ingress; consider StartTLS/LDAPS termination in front if needed
 - Tokens are short‑lived; rotate and scope role permissions appropriately
 - Debug logs may include metadata; avoid enabling 
debugin production 
Log level is controlled by LOG_LEVEL. Logs include timestamps and caller information.
MIT License. See LICENSE.