About AWS Role Ingestion
AWS Role Ingestion is the part of Serval’s AWS integration that discovers IAM roles in your connected AWS accounts and makes them requestable in Serval. Serval ingests every role carrying a tag with keyserval, together with its policy documents and maximum session duration, and lets approved users start short-lived, just-in-time (JIT) AWS sessions for those roles. This page covers the role sync, the AWS-side setup, and the bridge service that mints JIT sessions. For connecting the AWS account itself, see the AWS integration page; for access-policy configuration, see AWS Role Access.
Authentication: Cross-account IAM role (STS AssumeRole with an External ID) for role ingestion. JIT sessions use OIDC federation (STS AssumeRoleWithWebIdentity) against your Okta identity provider - brokered by Serval’s cloud endpoints on Serval cloud, or by the self-hosted bridge service that runs alongside your worker on self-hosted deployments.
Data sync: Scheduled full sync every 4 hours (with a 30-minute offset). There is no delta sync, so changes in AWS can take up to 4 hours to appear in Serval.
What the AWS Role Ingestion integration enables
| Capability | Description |
|---|---|
| IAM role ingestion | The built-in workflow “Fetch AWS IAM Roles for Resource Sync” ingests every IAM role tagged with key serval from each connected account, including inline policy documents, attached managed policy documents, and the role’s maximum session duration. |
| Assume Role entitlement | Each ingested role surfaces exactly one requestable entitlement named “Assume Role” (“Ability to assume this AWS IAM role”) in Serval’s access-request flow. |
| Temporary (JIT) AWS sessions | Approved users mint short-lived AWS credentials (Access Key ID, Secret Access Key, Session Token) for a role using their OIDC identity (Okta in the standard setup). Session length is the shorter of the remaining approved access time and the role’s maximum session duration, defaulting to 1 hour, with an AWS-enforced 15-minute minimum. |
| Deferred deprovision timer | The granted access window starts counting down when the user opens their first AWS session, not when the request is approved. |
| CloudTrail-attributable sessions | JIT sessions minted through the self-hosted bridge use the requester’s email (truncated to 64 characters) as the session name, so activity in CloudTrail is attributable per user. Sessions minted through Serval cloud appear under the shared session name serval-user-access. |
| Pre-built install workflows | The AWS integration ships two installable workflows: “Create AWS IAM Role” (installer approval by default) and “List AWS Organization Accounts” (no approval by default). |
Get your credentials
Set up an ingestion role in each AWS account Serval should read roles from. If you want users to mint AWS sessions, also complete the JIT setup. AWS documents the cross-account pattern in Delegate access across AWS accounts using IAM roles and the External ID pattern in How to use an external ID for third-party access.- Ingestion role (required)
- JIT access via the Serval bridge (self-hosted)
Create the role
Set the trusted account and External ID
992382851720 on Serval cloud, or the account your own worker runs in if self-hosted. Tick Require external ID and paste the External ID shown in Serval’s Connect AWS dialog.Skip permissions and create
Add the TagSession trust statement
sts:TagSession for the same account principal. A complete trust policy looks like this (replace <WORKER_ACCOUNT_ID> with the trusted account from the previous step and <EXTERNAL_ID> with the External ID from Serval’s Connect AWS dialog):Add the read-only inline policy
*: iam:ListRoles, iam:GetRole, iam:ListRolePolicies, iam:GetRolePolicy, iam:ListAttachedRolePolicies, iam:GetPolicy, iam:GetPolicyVersion.Tag the roles Serval should manage
serval (the value may be empty) to every role Serval should ingest and grant. Untagged roles are ignored entirely.Self-hosted only: grant the worker its STS permissions
serval-worker-sa - the worker chart does not create one for you), reference it from the worker deployment, and add an EKS Pod Identity association binding it to an IAM role that allows sts:AssumeRole and sts:TagSession on Resource *. This is required for ingestion itself, even if you never set up JIT sessions.Example Terraform for the worker IAM role, its assume-role/permission policies, and the Pod Identity association:Connect in Serval
Role ingestion uses the standard AWS connection - follow the connect flow on the AWS integration page to open the Connect AWS dialog, then fill it in as follows.Copy the read-only values
992382851720) and External ID. Use both in your ingestion role’s trust policy. The External ID is a deterministic 64-character value derived from your team, so it is identical on every reconnect and safe to hardcode in Terraform trust policies.Your AWS Account ID (required)
Your AWS Account Name (required)
Role ARN (required)
Verifying the connection
Run the connection health checks after connecting. Test AWS Connection - confirms Serval can assume your cross-account role and read IAM. This is the authoritative check before debugging role ingestion.- Success: “Successfully authenticated with AWS”
- Failure (role assumption fails): “Unable to authenticate with AWS. Please verify your cross-account role ARN and external ID are correct.”
- Failure (role assumed, but the inline policy is missing the IAM read permission the sync also needs): “Connection successful, but IAM role lacks iam:ListRoles permission.”
- Success: “Successfully retrieved [number] accounts from AWS Organizations”
- Failure (missing access): “Unable to access AWS Organizations. Ensure the IAM role has organizations:ListAccounts permission.”
- Failure (permission only): “Connection successful, but IAM role lacks organizations:ListAccounts permission.”
- Failure (standalone account): “This AWS account is not part of an AWS Organization.” This is expected for accounts outside an AWS Organization and is not a connectivity problem.
Gotchas and troubleshooting
Only roles tagged 'serval' are ingested
Only roles tagged 'serval' are ingested
serval exactly; the value is ignored and may be empty. An account full of roles syncs zero resources until tagging is done, and untagging a role removes it on the next full sync. Check tags before debugging the connection.Changes can take up to 4 hours to appear
Changes can take up to 4 hours to appear
The default AWS trust policy is insufficient - add sts:TagSession
The default AWS trust policy is insufficient - add sts:TagSession
JIT session length is not a flat 3 hours
JIT session length is not a flat 3 hours
The access clock starts at first session, not at approval
The access clock starts at first session, not at approval
A role showing no policies may be a permissions gap
A role showing no policies may be a permissions gap
iam:GetRolePolicy, iam:GetPolicy, or iam:GetPolicyVersion permissions rather than a truly policy-less role.Older setup guides list six unneeded IAM actions
Older setup guides list six unneeded IAM actions
iam:ListRoleTags, rds:DescribeDBInstances, rds:DescribeDBClusters, ec2:DescribeInstances, eks:DescribeCluster, and eks:ListClusters appeared in earlier versions of the inline policy, but no shipped ingestion workflow uses them (tags come back on iam:GetRole). Only the seven actions listed above are required for role ingestion. The optional install workflows have their own needs - organizations:ListAccounts for “List AWS Organization Accounts”, and iam:CreateRole plus iam:PutRolePolicy for “Create AWS IAM Role” - and your own custom workflows may need more.CloudTrail shows many short sessions - that is normal
CloudTrail shows many short sessions - that is normal
serval-user-access.The bridge service is named serval-bridge, not svbridge-api
The bridge service is named serval-bridge, not svbridge-api
serval-bridge (port 80, forwarding to 8080); svbridge-api is the container name inside the deployment. The bridge must be reachable by users over your VPN, and its OIDC secrets live in the bridge-secrets Kubernetes secret.There is no /oidc/auth/logout route
There is no /oidc/auth/logout route
/oidc/auth/login and /oidc/auth/callback only. Configure the Okta sign-in redirect to /oidc/auth/callback and treat any sign-out redirect URI as unused.Okta login email must match the Serval account email
Okta login email must match the Serval account email
Where a mistyped Role ARN actually surfaces
Where a mistyped Role ARN actually surfaces
arn: with the error “invalid role ARN format”; since that ARN is ingested from AWS itself, hitting this error usually indicates corrupted or stale ingested data rather than a setup typo.Session initiation fails with a bridge connection error
Session initiation fails with a bridge connection error
AWS traffic does not go through Serval's HTTP proxy
AWS traffic does not go through Serval's HTTP proxy
*.amazonaws.com) directly with short-lived 15-minute credentials instead of routing through Serval’s host-allow-listed proxy. If you restrict the worker’s egress, allow iam.amazonaws.com, organizations.us-east-1.amazonaws.com, and sts.us-west-1.amazonaws.com (the self-hosted bridge likewise calls sts.us-west-1.amazonaws.com). Custom workflows that use other AWS submodules (EC2, S3, Lambda, RDS) call those services’ regional endpoints too.Need help? Contact support@serval.com for assistance with your AWS Role Ingestion integration.

