Self-hostingAgent runbook

IAM and Pod Identity

The three IAM roles and five EKS Pod Identity associations the install needs, with their exact policies and an optional script that creates them.

Human version of this guide · Markdown

Written for a coding agent working for you. Lines marked Agent: are its checks and stop points. Everything else matches the human guide.

The pods get AWS access through EKS Pod Identity. No access keys are used. The Terraform in Install on EKS creates all of this for you; read this page if your team creates IAM itself, or to review the grants.

The namespace (agent-relay) and the ServiceAccount names are fixed: the Helm chart creates exactly these. The cluster needs the EKS Pod Identity Agent add-on.

The three roles

Role (suggested name)ServiceAccounts in agent-relayPurpose
agent-relay-sessionsagent-relay-worker, agent-relay-alleyoop, agent-relay-session-ingest-apiStore and read session data in the S3 bucket
agent-relay-search-indexeragent-relay-search-indexerWrite the search index; read session data
agent-relay-search-readeragent-relay-session-readSearch; read session data

agent-relay-alleyoop isn't used by this install. Linking it is harmless and matches the tested setup.

Trust policy (all three roles)

{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"pods.eks.amazonaws.com"},"Action":["sts:AssumeRole","sts:TagSession"]}]}

Permissions

agent-relay-sessions

{"Version":"2012-10-17","Statement":[
 {"Sid":"ListBucket","Effect":"Allow","Action":["s3:ListBucket","s3:GetBucketLocation"],"Resource":["arn:aws:s3:::<bucket>"]},
 {"Sid":"ReadWriteObjects","Effect":"Allow","Action":["s3:GetObject","s3:PutObject","s3:AbortMultipartUpload","s3:ListMultipartUploadParts","s3:DeleteObject"],"Resource":["arn:aws:s3:::<bucket>/*"]}
]}

agent-relay-search-indexer

{"Version":"2012-10-17","Statement":[
 {"Sid":"OpenSearchHttp","Effect":"Allow","Action":["es:ESHttpGet","es:ESHttpHead","es:ESHttpPost","es:ESHttpPut","es:ESHttpDelete","es:ESHttpPatch"],"Resource":["<domain arn>/*"]},
 {"Sid":"ListSessionsBucket","Effect":"Allow","Action":["s3:ListBucket"],"Resource":["arn:aws:s3:::<bucket>"]},
 {"Sid":"ReadSessionObjects","Effect":"Allow","Action":["s3:GetObject"],"Resource":["arn:aws:s3:::<bucket>/*"]}
]}

agent-relay-search-reader: the same as the indexer, with the first statement's actions limited to ["es:ESHttpGet","es:ESHttpHead","es:ESHttpPost"].

With a customer-managed KMS key on the bucket: also allow kms:Decrypt and kms:GenerateDataKey on that key for agent-relay-sessions, and kms:Decrypt for both search roles. Conditioning on kms:ViaService = s3.<region>.amazonaws.com is a good idea.

Pod Identity associations (five)

ServiceAccount (namespace agent-relay)Role
agent-relay-workeragent-relay-sessions
agent-relay-alleyoopagent-relay-sessions
agent-relay-session-ingest-apiagent-relay-sessions
agent-relay-search-indexeragent-relay-search-indexer
agent-relay-session-readagent-relay-search-reader

On the OpenSearch domain

  • Access policy: allow es:ESHttp* on <domain arn>/* for both search roles and for the IAM role that is the domain's fine-grained access control master user.
  • Inside OpenSearch: step 7 of the install maps the two search roles to OpenSearch roles with opensearch-roles-via-cluster.sh, run as that master user role.

Optional: create it with the AWS CLI

create-iam.sh creates the three roles and the five associations. It came with the files in step 1 of the install (download it on its own). It is safe to rerun: existing roles keep their names and get their inline policy replaced, and existing associations are skipped. It needs aws and jq.

CLUSTER=<cluster name> REGION=<region> BUCKET=<sessions bucket> \
DOMAIN_ARN=<opensearch domain arn> KMS_KEY_ARN=<bucket key arn, or leave empty> \
  bash create-iam.sh

Then allow the two printed role ARNs, and your master user role, es:ESHttp* in the OpenSearch domain's access policy.

Done when: it prints the two export ..._ROLE_ARN= lines, and the association list in Bring your own AWS resources shows five ServiceAccounts.

Agent: create-iam.sh changes IAM in the human's account. Show the exact command with values filled in and ASK THE HUMAN for approval before running it.

What the install needs back

Two values for settings.sh:

export INDEXER_ROLE_ARN=<arn of agent-relay-search-indexer>
export READER_ROLE_ARN=<arn of agent-relay-search-reader>

The sessions role needs no setting: the pods pick it up through Pod Identity.

If the associations were missing when the pods first started, create them and restart the pods: kubectl -n agent-relay rollout restart deploy.


Stuck? See troubleshooting or support.