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 for your region with an External ID, and attach whatever permission policies your workflows need - Serval mandates no permissions of its own. Each Serval region runs in its own AWS account, so the account your role trusts depends on where your organization is hosted. Check the address you sign in at, and ask support@serval.com if you’re unsure which region you’re on.
1

Open the Connect AWS dialog in Serval

In Serval, go to Integrations → All integrations → AWS → Connect and leave the dialog open. It displays the Serval AWS Account ID for your region and your team’s External ID. Copy both: the trust policy you create next must name that account ID, which matches your region’s row in the table above. Self-hosted deployments trust the account their own worker runs in, not the value shown in the dialog.
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 for your region from the table above, 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. Pick the tab for your region and replace <EXTERNAL_ID> (including the angle brackets) with 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 Integrations → All integrations → AWS → Connect

The dialog shows two read-only values: Serval AWS Account ID and External ID (your team’s stable, Serval-generated value). These are for use in AWS - you don’t edit them. The account ID to trust for your region is in Get your credentials.
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 and the Role ARN is well-formed.
The dialog rejects a malformed Role ARN before you can submit (it must look like arn:aws:iam::123456789012:role/<name>), but a well-formed ARN for a role that doesn’t exist or doesn’t trust Serval still connects and only fails when you run the “Test AWS Connection” health check, so verify the ARN 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”
  • Role assumption fails (for example, a trust policy naming the wrong Serval account or lacking sts:TagSession, an External ID mismatch, or a nonexistent role): “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.”
  • If role assumption works but the IAM request fails for another reason: “Authenticated with AWS, but the IAM ListRoles request failed.”
List AWS Organization Accounts - verifies the role can list accounts in your AWS Organization.
  • Success: “Successfully retrieved [number] accounts from AWS Organizations”
  • Role assumption fails: “Unable to authenticate with AWS. Please verify your cross-account role ARN and external ID are correct.”
  • 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.”
  • Any other failure, such as throttling or a network problem (ignore the permission advice and read the error shown beneath the message): “Unable to access AWS Organizations. Ensure the IAM role has 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.
The dialog and Serval both reject a malformed Role ARN (anything that isn’t arn:aws:iam::<12-digit account ID>:role/<name>) before the connection is saved. A well-formed ARN for a role that doesn’t exist or doesn’t trust Serval still 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.
Each Serval region runs in its own AWS account, and the trust policy must name the one that assumes your role: 992382851720 for United States organizations (app.serval.com), 311208284913 for European Union organizations (app.eu1.serval.com), and the account your own worker runs in for self-hosted deployments. The Connect AWS dialog shows the account for the region you’re signed in to, and the trust policy must name that same account. If the dialog shows 992382851720 on a European Union tenant, that build predates the region-aware dialog, so use the table in Get your credentials instead. Serval can’t assume a role that trusts a different account, and “Test AWS Connection” fails with “Unable to authenticate with AWS. Please verify your cross-account role ARN and external ID are correct.” If you’re self-hosted, ignore the value in the dialog and confirm the worker’s account ID with your Serval contact before writing the trust policy.

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