Skip to content

Connect AWS ​

Connecting an AWS account lets Kadmo run agents on EC2 machines in that account. You create an IAM user with a least-privilege policy, paste its access key into the app, and name the subnet agents launch in. From then on Kadmo handles each agent machine's whole life: launch, reboot, stop, start and terminate. This guide covers the account setup, the exact policy, where the keys go in the app, what Kadmo creates, and the fix for every error the app shows.

In this release

The app reaches agents over Kadmo's private network. An AWS connection therefore needs an agent subnet that is peered with Kadmo's network, and agents launch only in that subnet's region. Kadmo sets up the peering with you: book a call before you plan the account. Until the subnet is set, the AWS card reads "Not set: agents cannot launch until it is". See The agent subnet.

Before you start ​

  • An AWS account in which you can create IAM users and policies, with console or CLI access.
  • The admin role on your Kadmo account: cloud connections are admin-only.
  • About ten minutes.

Run agents away from your production workloads: set up a dedicated AWS account first, then do Steps 1 to 4 inside it.

The policy below grants its actions on Resource: "*". In a shared account that means the Kadmo user could describe or terminate any EC2 instance there, not only agents. An account of their own removes that risk and keeps your existing setup untouched.

BenefitWhy it matters
Blast-radius isolationResource: "*" then reaches only agent resources; your production instances live in an account these credentials cannot see
No interferenceKadmo creates security groups, key pairs and tags; in a clean account they never collide with existing infrastructure or drift detection
Cost separationThe account's bill is the agent spend: filter by linked account in Cost Explorer, or set an AWS Budget on it alone
Quota isolationvCPU quotas are per account and region, so agents cannot use up production launch capacity, and the other way round
Clean teardownClose the account and everything in it is gone

Create the member account (AWS Organizations) ​

  1. In your management account, open AWS Organizations → AWS accounts → Add an AWS account → Create an AWS account.
  2. Name it, for example kadmo-agents, and give it a unique e-mail address. Plus-addressing works well, for example aws+kadmo-agents@example.com.
  3. Keep the default IAM role name OrganizationAccountAccessRole.

Or with the CLI:

bash
aws organizations create-account \
  --email aws+kadmo-agents@example.com \
  --account-name "Kadmo Agents"

# repeat until the state is SUCCEEDED, then note the new account ID
aws organizations list-create-account-status --states SUCCEEDED

To work in the new account, use Switch role in the console (the account ID and the role OrganizationAccountAccessRole), or add a CLI profile:

toml
# ~/.aws/config
[profile kadmo-agents]
role_arn = arn:aws:iam::<member-account-id>:role/OrganizationAccountAccessRole
source_profile = management

Then do Steps 1 to 4 inside that account. Do not reuse an IAM user or access key from another account.

First-run checklist for a fresh account ​

The app checks these before every launch, but fixing them first avoids a failed first agent:

CheckWhyFix
vCPU quotasA new account can start at or near 0, and a quota of 0 blocks the launchIn the agents' region, Service Quotas → Amazon EC2: raise Running On-Demand Standard instances (L-1216C47A) and, for spot agents, All Standard Spot Instance Requests (L-34B43A08). Agents use 2 to 4 vCPUs each
Region opt-inNewer regions are disabled by defaultEnable the region under Billing → Account → AWS Regions
Root userA new member account has only a root userTurn on MFA for root, then stop using it: do Steps 1 to 3 through OrganizationAccountAccessRole

Without AWS Organizations ​

You can still open a separate AWS account and use it only for agents. If a second account is not an option, the dedicated IAM user below is the minimum: it separates credentials, but not blast radius, quotas or billing.

Step 1: Create the IAM policy ​

  1. Open the IAM console → Policies → Create policy.
  2. On the JSON tab, paste this policy. It is exactly the set of actions the app checks for:
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "KadmoAgentManagement",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeRegions",
        "ec2:DescribeInstances",
        "ec2:DescribeInstanceTypes",
        "ec2:RunInstances",
        "ec2:TerminateInstances",
        "ec2:RebootInstances",
        "ec2:StartInstances",
        "ec2:StopInstances",
        "ec2:DescribeSpotInstanceRequests",
        "ec2:CancelSpotInstanceRequests",
        "ec2:CreateSecurityGroup",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:RevokeSecurityGroupIngress",
        "ec2:DeleteSecurityGroup",
        "ec2:DescribeSecurityGroups",
        "ec2:CreateKeyPair",
        "ec2:DeleteKeyPair",
        "ec2:DescribeKeyPairs",
        "ec2:CreateTags",
        "ec2:DescribeImages",
        "ec2:DescribeSubnets",
        "sts:GetCallerIdentity"
      ],
      "Resource": "*"
    }
  ]
}
  1. Click Next, name the policy KadmoAgentManagement, and click Create policy.

Optional permissions ​

Everything works without these. Each one turns a check the app otherwise skips into a real answer:

ActionWhat it adds
iam:SimulatePrincipalPolicyCheck permissions (Settings → Cloud) dry-runs every action above and lists the missing ones by name. Without it, the check confirms the credentials only
servicequotas:GetServiceQuotaThe launch check reads your vCPU quota (on-demand or spot). Without it you see a warning instead
ec2:DescribeInstanceTypeOfferingsThe wizard marks sizes your region does not offer and reveals more sizes. Without it, sizes are not checked and AWS decides at launch
ec2:GetSpotPlacementScoresThe wizard warns when spot capacity for your size is scarce right now

Add them in the same statement's Action list.

Step 2: Create the IAM user ​

  1. Open IAM → Users → Create user.
  2. Enter a name, for example kadmo-agent-manager.
  3. On Permissions, choose Attach policies directly, find KadmoAgentManagement and select it.
  4. Finish creating the user.

Step 3: Create an access key ​

  1. Open the new user → Security credentials.
  2. Click Create access key and choose Application running outside AWS.
  3. Click Create access key.
  4. Copy the Access key ID and the Secret access key. AWS shows the secret only once.

Never commit access keys to a repository. Paste them only into the app.

Step 4: Connect in the app ​

  1. In the app, open Integrations and, in the Cloud group, open the AWS card. (On an empty Agent Fleet page, Connect next to AWS goes to the same place.)
  2. Click Connect AWS account. The Connect AWS account panel opens.
  3. Fill in:
FieldWhat to enter
Display nameA name for this connection, for example kadmo-agents
Access key IDFrom Step 3 (starts with AKIA)
Secret access keyFrom Step 3
Default regionThe region your agents run in: the region of the agent subnet
Agent subnetThe subnet agents launch in, as subnet-… (see below). You can also add it later
  1. Click Connect & validate. The app checks the key against AWS, stores it encrypted, and then reads the subnet. "AWS account connected with its agent subnet." means you are done.

The agent subnet ​

"The subnet agents launch in: the one peered with Kadmo, in the default region. Agents cannot launch until it is set."

  • The subnet must be in the connection's default region, and every agent of this connection launches in that region.
  • When you save it, the app reads the subnet with ec2:DescribeSubnets and records its VPC and address range. Agents never launch in a default VPC.
  • Change or clear it later with Agent subnet on the AWS card (Save subnet).

The AWS card ​

Once connected, the card shows the Connection, Region, Status, when it was Validated, and the Agent subnet with its address range. Its buttons:

ButtonWhat it does
ValidateChecks the stored credentials again: "Credentials valid ✓"
Agent subnetSets, changes or clears the subnet
Rotate credentialsReplaces the access key (Rotate & validate) and keeps the connection's name
DisconnectRemoves the connection. Refused while agents still use it

Settings → Cloud has the same connection under Providers, with Check permissions, which lists every missing action from Step 1.

What Kadmo creates in your account ​

ResourceName and tagsWhen
Security group, one per account and VPC, shared by every agentkadmo-acct-<account-id>At the first launch in the subnet's VPC
Key pair, one per agentkadmo-agent-<agent-name>At launch. The private key is kept, encrypted, for Settings → Agents → SSH Access
EC2 instanceName kadmo-agent-<agent-name>; tags kadmo:managed, kadmo:agent, kadmo:tierAt launch: Ubuntu 24.04 LTS, a 40 GB gp3 disk deleted with the instance, a public address, in your agent subnet
Spot request (spot agents only)Tags kadmo:managed, kadmo:agentAt launch. Persistent: an interrupted spot agent stops and starts again when capacity returns

The security group admits:

PortFromWhy
9876 (TCP) and ICMPKadmo's app network onlyThe app talks to the agent runtime at the agent's private address
22 (SSH) and 3389 (RDP)The addresses on your firewall allowlist and, where Kadmo's deployment names them, Kadmo's operations rangesSo people can reach the machine directly

The address you launch from is added to the allowlist automatically. Edit the list under Settings → Cloud → Firewall allowlist (Add, Add my current IP, Save allowlist). You never type a Kadmo address into AWS: the app writes the rules.

Destroy on an agent's page terminates its instance, cancels its spot request and deletes its key pair. Disconnecting the account removes the shared security group.

Troubleshooting ​

Each row is a message the app shows and its fix.

When you connect or validate ​

MessageCauseFix
"Credential validation failed" with InvalidClientTokenIdThe access key ID is wrong or deletedCreate a new access key (Step 3) and connect again, or use Rotate credentials
"Credential validation failed" with SignatureDoesNotMatchThe secret access key is wrongCopy the secret again, or create a new key
"Credential validation failed" with AuthFailureThe key is inactiveCheck the user under IAM → Users
"Credential validation failed" with UnauthorizedOperationThe policy is not attached, or lacks ec2:DescribeRegions or sts:GetCallerIdentityAttach the full Step 1 policy
"Missing permissions: …" (Check permissions)The policy lacks the listed actions; the connection is marked invalidAdd the listed actions, or re-attach the Step 1 policy, then Check permissions again
"⚠ Legacy connection: missing ec2:RevokeSecurityGroupIngress …"An older policyAdd the action; until then the firewall allowlist cannot remove entries
"Validation failed: …" (AWS card)The stored key no longer worksRotate credentials with a working key

When you set the agent subnet ​

MessageFix
"Agent subnet must be a subnet id (subnet-…)"Enter the subnet ID, not its name or address range
"Pick the default region the agent subnet is in" / "Set the connection's default region before its agent subnet"Choose the Default region first
"Subnet … was not found in … with this connection's credentials"The subnet is in another region or another account; pick the right default region or subnet
"Could not read the subnet from AWS"The policy lacks ec2:DescribeSubnets; add it
"Account connected, but the agent subnet was not saved"The connection exists; fix the subnet and click Save subnet

When you create an agent ​

These appear in the wizard's Machine step or on Launch:

MessageFix
"This connection names no agent subnet — set one on the connection before launching"Set the agent subnet
"Agents launch in the connection's subnet, in … — pick that region"Pick the connection's default region in the wizard
"Region not enabled — opt in at …"Enable the region under Billing → Account → AWS Regions
"vCPU quota is 0 — request increase via Service Quotas console"Raise L-1216C47A (on-demand) or L-34B43A08 (spot) in that region
"Could not verify vCPU quota — proceed with caution or check Service Quotas console"A warning only. Add servicequotas:GetServiceQuota to get a real answer
"… is not offered in … — pick another machine size or region."Pick another size or region, or Load N more sizes
"Could not verify instance type availability: …"A warning only. Add ec2:DescribeInstanceTypeOfferings to get a real answer
"Spot capacity for … scores N/10 right now — elevated reclaim risk."A warning: choose on-demand or another region for a steadier agent
"Could not check spot capacity score — connection lacks the optional ec2:GetSpotPlacementScores permission."A warning only; add the action if you want the check
"Ubuntu 24.04 LTS AMI not found — provider may not stock it yet"Pick another region
UnauthorizedOperation on launch, reboot, stop or destroyThe policy lacks the action; re-attach the full Step 1 policy
"Cannot delete connection: agents are still referencing it"Destroy or move the agents first, then disconnect

Security notes ​

  • Credentials are stored encrypted (AES-256-GCM) and never returned by the app.
  • Use one IAM user per environment, and prefer a dedicated account.
  • Rotate the access key regularly: create a new key in IAM, then Rotate credentials in the app, then delete the old key.

Next step ​

Create your first agent with the create-agent wizard.