Skip to main content

AWS Inventory

Overview​

AWS Inventory is a pull-based source that takes a periodic snapshot of an AWS account's assets and identities and sends one record per resource into a Praxis pipeline. These records are entity context: they describe what exists (servers, networks, users, roles), not what happened. A SIEM uses them to enrich events.

ResourceAWS APIaws.inventory.resource → Google SecOps log type
EC2 instances: IDs, private/public IPs, DNS names, tags, state, security groups, network interfaces, instance profileec2:DescribeInstances (per region)ec2_instance → AWS_EC2_INSTANCES
VPCs: CIDR blocks, state, default flag, DHCP options, tagsec2:DescribeVpcs (per region)ec2_vpc → AWS_EC2_VPCS
IAM users: groups, attached and inline policies, tags, permissions boundary, password last usediam:GetAccountAuthorizationDetails + iam:ListUsersiam_user → AWS_IAM
IAM roles: trust policy, policies, tags, role last used, description, max session durationiam:GetAccountAuthorizationDetails + iam:ListRolesiam_role → AWS_IAM
IAM groups: policies and member usersiam:GetAccountAuthorizationDetailsiam_group → AWS_IAM

Like other sources, AWS Inventory does not set a Google SecOps log type. Every record carries the attribute aws.inventory.resource; set the log type from it with Google SecOps Standardization. See Sending to Google SecOps.

Supported types: Logs

Supported platforms: Linux, Windows, macOS

Minimum collector version: 0.5.59

Authentication​

The credential is optional.

Credential typeWhen to use
AWS (aws), Assume RoleRecommended. The collector assumes a read-only IAM role in the target account, starting from its own host credentials (instance profile, environment, or a profile). Short-lived credentials, no stored keys.
AWS (aws), Access KeysQuick setup or testing. A read-only IAM user's access key ID and secret.
AWS IMDS (awsimds)The collector runs on an EC2 instance whose instance profile has the permissions below.
NoneThe collector uses the AWS SDK default chain on its host: environment variables, shared config, EKS IRSA / Pod Identity, ECS task role, then the EC2 instance profile.

Required IAM permissions​

All calls are read-only. The AWS managed policy SecurityAudit covers every one. The minimal policy is:

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"ec2:DescribeRegions",
"ec2:DescribeInstances",
"ec2:DescribeVpcs",
"iam:GetAccountAuthorizationDetails",
"iam:ListUsers",
"iam:ListRoles"
],
"Resource": "*"
}]
}
  • ec2:DescribeRegions is only needed with Collect From All Enabled Regions.
  • If iam:ListUsers or iam:ListRoles is denied, users and roles are still collected, just without PasswordLastUsed (users) or Description / MaxSessionDuration (roles).
  • The account ID comes from sts:GetCallerIdentity, which needs no permission.

Basic configuration​

ParameterTypeRequiredDefaultDescription
regionstringYesus-east-1Home region. Used for STS and IAM calls (IAM is global), and the only region EC2 resources are read from when no other regions are set.
resourceslistNoall fiveAny of ec2_instances, ec2_vpcs, iam_users, iam_roles, iam_groups.
all_regionsboolNofalseCollect EC2 instances and VPCs from every region enabled for the account. Opt-in regions that are not enabled are skipped.
regionslistNohome regionRegions to collect EC2 instances and VPCs from, e.g. us-east-1, eu-west-1. Hidden when all_regions is on.
modescheduled | manualNoscheduledscheduled: take a snapshot every interval. manual: take a snapshot only with Fetch Inventory Now. See Scheduled and manual fetching.
intervalinteger (seconds)No21600 (6h)Time between full snapshots in scheduled mode. Minimum 900 (15 minutes). Hidden in manual mode.
sync_requestintegerNo0Fetch Inventory Now: shown and used in manual mode only.
formatsecops | awsNosecopsRecord body shape. See Record format.

Scheduled and manual fetching​

Works the same way as Okta's user context fetching.

Fetch ModeWhen snapshots run
scheduled (default)At start-up, then every Snapshot Interval. The time of the last snapshot is saved on the collector, so a restart or redeploy waits out the rest of the interval instead of fetching again.
manualOnly when you raise Fetch Inventory Now. Nothing runs on a timer.

Fetching on demand​

  1. Set Fetch Mode to manual.
  2. In Fetch Inventory Now, enter a number higher than the current one (for example 1 → 2).
  3. Deploy. The collector takes one full snapshot.

The completed number is saved on the collector, so a restart or a later config change with the same number does not fetch again. If the snapshot fails, it stays pending and is retried. Raise the number again whenever you want a fresh snapshot.

Record format​

Each resource becomes one log record whose body is that resource's JSON.

  • secops (default): matches what the Google SecOps native AWS feeds produce, which is what the AWS_EC2_INSTANCES, AWS_EC2_VPCS and AWS_IAM default parsers read. The AWS fields are kept, with Go-style initialisms and the EC2 XML set names: InstanceId → InstanceID, PrivateIpAddress → PrivateIPAddress, PublicIpAddress → IPAddress, Tags → TagSet, NetworkInterfaces → NetworkInterfaceSet, and Reservation.Instances → InstancesSet. Instance records also carry collection_time. IAM groups use the iam:GetGroup shape, with the group under Group and its members under Users.
  • aws: the AWS API JSON unchanged. Use this for destinations other than Google SecOps.

In both formats, unset fields are left out and IAM policy documents (which AWS returns URL-encoded) are decoded to plain JSON.

FieldOTel destination
(resource JSON)LogRecord.Body (string)
(snapshot start time)LogRecord.Timestamp: the record describes the resource as of that snapshot
(resource kind)LogRecord.Attributes["aws.inventory.resource"]: ec2_instance, ec2_vpc, iam_user, iam_role, iam_group
Instance / VPC / user / role / group IDLogRecord.Attributes["aws.resource.id"]
IAM ARNLogRecord.Attributes["aws.resource.arn"]
(constant)Resource.Attributes["cloud.provider"] = "aws"
Account IDResource.Attributes["cloud.account.id"]
Region (EC2 resources only)Resource.Attributes["cloud.region"]

Sending to Google SecOps​

One AWS Inventory source produces records for three Google SecOps log types. Between the source and the Google SecOps destination, add one Google SecOps Standardization processor per log type, each with a condition:

Log TypeCondition
AWS_EC2_INSTANCESlog.attributes["aws.inventory.resource"] == "ec2_instance"
AWS_EC2_VPCSlog.attributes["aws.inventory.resource"] == "ec2_vpc"
AWS_IAMIsMatch(log.attributes["aws.inventory.resource"], "^iam_")

Each processor sets the log type only on the records its condition matches, so the three can run one after another. Keep Record Format on secops so the record bodies match the Google SecOps parsers.

Example configuration​

{
"region": "us-east-1", // required: home region
"resources": ["ec2_instances", "ec2_vpcs", "iam_users", "iam_roles", "iam_groups"],
"all_regions": true, // default: false
"mode": "scheduled", // default: scheduled (or "manual")
"interval": 21600, // default: 21600 (6h), minimum 900; scheduled mode only
"sync_request": 0, // manual mode: raise and deploy to fetch now
"format": "secops" // default: secops
}

Operational notes​

  • Snapshots, not streaming. Every snapshot re-sends the whole inventory. Pick an interval that matches how fast your estate changes: shorter for autoscaling fleets, longer for static ones.
  • Partial failures. If one region or resource fails (for example a region blocked by an SCP), the others are still sent and the error appears in the source's error metric. Only a snapshot where everything failed is retried, after 5 minutes and then with backoff up to 1 hour.
  • Multiple accounts. One source reads one account. Add a source per account, each with its own Assume Role credential.
  • Rate limits. Requests are paginated at the API maximum (1000 per page) as AWS recommends, and throttled calls are retried by the AWS SDK.

Metrics​

Metric NameDescription
prx_src_records_received_total{signal="logs"}Log records emitted, one per resource.
prx_src_bytes_received_totalBytes of the emitted record bodies.
prx_src_pipeline_latency_secondsArrival → downstream handoff.
prx_src_errors_total{reason}AWS API or snapshot failures by reason: auth, permission_denied, timeout, io.
prx_src_records_dropped_total{reason="backpressure"}Records dropped because the downstream pipeline refused them.