Cloud Accounts API Pro+
Manage cloud accounts for multi-account cloud discovery. Each cloud account represents a set of AWS credentials for scanning resources in a specific AWS account.
Endpoints Summary
| Method | Endpoint | Description |
|---|---|---|
GET | /api/cloud-accounts | List cloud accounts |
POST | /api/cloud-accounts | Add a cloud account |
GET | /api/cloud-accounts/:id | Get account details |
PATCH | /api/cloud-accounts/:id | Update a cloud account |
DELETE | /api/cloud-accounts/:id | Remove a cloud account |
POST | /api/cloud-accounts/:id/validate | Validate credentials |
Authentication
All endpoints require a Bearer token in the Authorization header.
Authorization: Bearer <your-api-token>List Cloud Accounts
GET /api/cloud-accountsReturns all cloud accounts for the current organization.
Example:
curl -X GET "https://api.controlinfra.com/api/cloud-accounts" \
-H "Authorization: Bearer YOUR_TOKEN"Response:
{
"accounts": [
{
"_id": "665b1c2d3e4f5a6b7c8d9e0f",
"name": "Production",
"awsAccountId": "123456789012",
"credentialType": "assumeRole",
"roleArn": "arn:aws:iam::123456789012:role/ControlinfraReadOnly",
"status": "active",
"lastValidated": "2025-01-15T10:00:00Z",
"regions": ["us-east-1", "us-west-2"],
"createdAt": "2025-01-01T00:00:00Z"
},
{
"_id": "665b1c2d3e4f5a6b7c8d9e10",
"name": "Staging",
"awsAccountId": "987654321098",
"credentialType": "accessKey",
"status": "active",
"lastValidated": "2025-01-14T08:00:00Z",
"regions": ["us-east-1"],
"createdAt": "2025-01-05T00:00:00Z"
}
]
}Add a Cloud Account
POST /api/cloud-accountsRequest Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Friendly account name |
awsAccountId | string | Yes | 12-digit AWS account ID |
credentialType | string | Yes | accessKey or assumeRole |
accessKeyId | string | Conditional | AWS access key ID (if credentialType is accessKey) |
secretAccessKey | string | Conditional | AWS secret key (if credentialType is accessKey) |
roleArn | string | Conditional | IAM role ARN (if credentialType is assumeRole) |
externalId | string | No | External ID for AssumeRole (recommended) |
regions | string[] | No | Enabled regions (defaults to all) |
Example (AssumeRole):
curl -X POST "https://api.controlinfra.com/api/cloud-accounts" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production",
"awsAccountId": "123456789012",
"credentialType": "assumeRole",
"roleArn": "arn:aws:iam::123456789012:role/ControlinfraReadOnly",
"externalId": "controlinfra-abc123",
"regions": ["us-east-1", "us-west-2"]
}'Example (Access Key):
curl -X POST "https://api.controlinfra.com/api/cloud-accounts" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Staging",
"awsAccountId": "987654321098",
"credentialType": "accessKey",
"accessKeyId": "AKIA...",
"secretAccessKey": "wJalr...",
"regions": ["us-east-1"]
}'Response: 201 Created
{
"_id": "665b1c2d3e4f5a6b7c8d9e0f",
"name": "Production",
"awsAccountId": "123456789012",
"credentialType": "assumeRole",
"status": "pending_validation",
"createdAt": "2025-01-15T10:00:00Z"
}WARNING
Credentials are encrypted at rest and never returned in API responses after creation.
Get Account Details
GET /api/cloud-accounts/:idExample:
curl -X GET "https://api.controlinfra.com/api/cloud-accounts/665b1c2d3e4f5a6b7c8d9e0f" \
-H "Authorization: Bearer YOUR_TOKEN"Update a Cloud Account
PATCH /api/cloud-accounts/:idUpdate account properties. Only provided fields are updated.
Request Body:
| Field | Type | Description |
|---|---|---|
name | string | Friendly account name |
regions | string[] | Enabled regions |
roleArn | string | Updated IAM role ARN |
accessKeyId | string | Updated access key ID |
secretAccessKey | string | Updated secret key |
Example:
curl -X PATCH "https://api.controlinfra.com/api/cloud-accounts/665b1c2d3e4f5a6b7c8d9e0f" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production (Primary)",
"regions": ["us-east-1", "us-west-2", "eu-west-1"]
}'Delete a Cloud Account
DELETE /api/cloud-accounts/:idRemoves the cloud account and its stored credentials. Discovered resources from this account are retained but marked as disconnected.
Example:
curl -X DELETE "https://api.controlinfra.com/api/cloud-accounts/665b1c2d3e4f5a6b7c8d9e0f" \
-H "Authorization: Bearer YOUR_TOKEN"Response: 204 No Content
Validate Credentials
POST /api/cloud-accounts/:id/validateTest the stored credentials by attempting to call AWS STS GetCallerIdentity.
Example:
curl -X POST "https://api.controlinfra.com/api/cloud-accounts/665b1c2d3e4f5a6b7c8d9e0f/validate" \
-H "Authorization: Bearer YOUR_TOKEN"Response:
{
"valid": true,
"awsAccountId": "123456789012",
"arn": "arn:aws:sts::123456789012:assumed-role/ControlinfraReadOnly/session",
"validatedAt": "2025-01-15T12:00:00Z"
}Error Response (invalid credentials):
{
"valid": false,
"error": "The security token included in the request is expired",
"validatedAt": "2025-01-15T12:00:00Z"
}Plan Limits
| Plan | Max Cloud Accounts | Max Regions |
|---|---|---|
| Free | 0 | 0 |
| Pro | 1 | 1 |
| Team | Unlimited | Unlimited |
| Enterprise | Unlimited | Unlimited |
Exceeding plan limits returns 403 Forbidden with a plan upgrade message.