Skip to main content

About AWS

Amazon Web Services (AWS) is a public-cloud platform offering on-demand compute, storage, database, identity, and networking services. The Serval AWS integration is multi-product: connecting an AWS account once gives your workflows access to nine AWS services - EC2, IAM, S3, Lambda, RDS, RDS Data, SSO Admin, Identity Store, and Organizations - limited only by the permissions on the IAM role you delegate. Each connected AWS account is its own app instance keyed by its 12-digit account ID, so multi-account organizations connect each account individually and workflows can target one account or all of them. Authentication: Cross-account IAM role assumption (STS AssumeRole with an External ID). Serval never stores long-lived AWS keys - only your Role ARN and a Serval-generated External ID, exchanged at runtime for short-lived 15-minute session credentials. Data sync: No user or identity sync. The only background sync ingests IAM roles tagged with the key “serval” (including their inline and attached policies) to power temporary role access; everything else is on-demand from workflows.

What the AWS integration enables

Anything defined in the AWS API for these nine services can be accessed through Serval.

Get your credentials

Serval connects to AWS by assuming an IAM role in your account, following AWS’s standard pattern for delegating access to another AWS account. You create the role, tell it to trust Serval’s AWS account with an External ID, and attach whatever permission policies your workflows need - Serval mandates no permissions of its own.
1

Open the Connect AWS dialog in Serval

In Serval, go to Apps → Connect AWS and leave the dialog open. It displays the Serval AWS Account ID (992382851720) and your team’s External ID - you’ll need both in the AWS console.
2

Create a cross-account role in AWS

In the AWS console, go to IAM → Roles → Create role and choose Another AWS account as the trusted entity.
3

Enter the Serval account and External ID

Enter the Serval AWS Account ID shown in the dialog, tick Require external ID, and paste the External ID from the dialog.
4

Attach permission policies

Attach the policies that grant the actions you want Serval to perform - for example, IAMReadOnlyAccess for read-only IAM workflows. The role’s policies define exactly which AWS APIs Serval can call.
5

Name and create the role

Name the role and click Create role.
6

Add the TagSession statement to the trust policy

Open the new role, go to Trust relationships → Edit trust policy, and add an sts:TagSession statement alongside the existing sts:AssumeRole statement. Both statements use the Serval account principal; keep the sts:ExternalId condition on the AssumeRole statement. The full document should look like this, with <replace-with-your-external-id> (including the angle brackets) swapped for the External ID shown in the Connect AWS dialog:
7

Copy the Role ARN

Copy the Role ARN and your 12-digit AWS account ID, then return to the Connect AWS dialog in Serval.
The External ID is deterministic per Serval team - it never changes across reconnects, so it’s safe to hardcode in Terraform-managed trust policies.
If you want Serval to run the connection health checks and ingest roles for temporary access, include iam:ListRoles (connection check), organizations:ListAccounts (Organizations check), and the IAM read actions iam:GetRole, iam:ListRolePolicies, iam:GetRolePolicy, iam:ListAttachedRolePolicies, iam:GetPolicy, and iam:GetPolicyVersion (role ingestion) in the role’s policies.

Connect in Serval

1

Open Apps → Connect AWS

The dialog shows two read-only values: Serval AWS Account ID (992382851720) and External ID (your team’s stable, Serval-generated value). These are for use in AWS - you don’t edit them.
2

Your AWS Account ID (required)

Enter your 12-digit AWS account ID. This becomes the connection’s identifier in Serval.
3

Your AWS Account Name (required)

Enter a display label to tell accounts apart in Serval (for example, “Production”). It’s a label only and doesn’t affect the connection.
4

Role ARN (required)

Paste the Role ARN of the cross-account role you created.
5

Submit

Submit is disabled until all three required fields are filled in.
The dialog does not validate the Role ARN’s format - any non-empty value is accepted at connect time. A typo’d ARN will appear to connect successfully and only surface as a failure when you run the “Test AWS Connection” health check, so verify the ARN carefully before submitting.
To connect additional AWS accounts, repeat the connect flow once per account - each account is a separate connection.

Verifying the connection

After connecting, run the health checks from the app instance page. Test AWS Connection - verifies Serval can assume your cross-account role by making a minimal IAM read call.
  • Success: “Successfully authenticated with AWS”
  • Failure: “Unable to authenticate with AWS. Please verify your cross-account role ARN and external ID are correct.”
  • If role assumption works but the role can’t read IAM: “Connection successful, but IAM role lacks iam:ListRoles permission.”
List AWS Organization Accounts - verifies the role can list accounts in your AWS Organization.
  • Success: “Successfully retrieved [number] accounts from AWS Organizations”
  • Failure: “Unable to access AWS Organizations. Ensure the IAM role has organizations:ListAccounts permission.”
  • Standalone account (not in an Organization): “This AWS account is not part of an AWS Organization.”
  • Permission missing but auth working: “Connection successful, but IAM role lacks organizations:ListAccounts permission.”
“Test AWS Connection” is the authoritative connectivity signal. If it passes but “List AWS Organization Accounts” fails with “This AWS account is not part of an AWS Organization.”, your connection is healthy - that result is expected for standalone accounts.

Gotchas and troubleshooting

Standalone AWS accounts that aren’t part of an AWS Organization will always fail the “List AWS Organization Accounts” check with “This AWS account is not part of an AWS Organization.” This does not mean the connection is broken - “Test AWS Connection” is the check that matters for connectivity.
The IAM role sync filters to roles carrying a tag with the key “serval” - an account full of roles syncs zero resources until they’re tagged. If a connected account’s role list looks empty in Serval, check tags before debugging the connection.
Neither the dialog nor the backend validates ARN format - only that the Role ARN and External ID are non-empty. A typo’d ARN connects “successfully” and fails later at “Test AWS Connection” with “Unable to authenticate with AWS. Please verify your cross-account role ARN and external ID are correct.”
No region is stored on the connection - every workflow API action takes an explicit region. IAM is global so any region works for it, but a region must still be provided. Health checks default to us-east-1.
The External ID is derived from your Serval team ID, so the same team always sees the same value - it survives reconnects. This is intentional so the ID can live in Terraform-managed trust policies without breaking.
Each AWS account is its own app instance keyed by the 12-digit account ID. Multi-account organizations repeat the connect flow for each account; workflows can then target a specific account or iterate over all connected accounts.
Every role assumption requests a 15-minute session with a unique session name, and credentials refresh automatically on expiry - long-running workflows reassume the role transparently. Each assumption appears as a separate session in CloudTrail, so don’t be alarmed by many short sessions.
Unlike most integrations, AWS requests aren’t routed through Serval’s host-allow-listed HTTP proxy: AWS request signing must happen client-side, so the workflow worker uses short-lived credentials to call AWS service endpoints (*.amazonaws.com) directly. The effective outbound surface is the endpoints of the nine supported services, plus AWS STS for the credential exchange Serval performs on your connection’s behalf.
The Serval AWS Account ID is what your trust policy must trust on Serval cloud - it’s Serval’s production account, and the dialog always displays it. Self-hosted deployments instead trust the AWS account their Serval worker runs in, even though the dialog still shows the cloud account ID - if you’re self-hosted, confirm the correct account ID with your Serval contact before writing the trust policy.

Need help? Contact support@serval.com for assistance with your AWS integration.