list_cloudtrail_changes
Monitor AWS resource modifications by listing CloudTrail write events for specific resources or services over a defined period.
Instructions
Lists write/mutation events (Create, Update, Delete) for a specific resource or service.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| resource_id | No | Optional: The Resource ID or Name (e.g., sg-12345, my-bucket). | |
| lookup_key | No | The attribute to lookup by (default: ResourceName if resource_id provided). | |
| lookup_value | No | The value for the lookup key (required if resource_id is omitted). | |
| days | No | Lookback period in days (default: 7). |
Implementation Reference
- src/index.ts:511-535 (registration)Registration of the list_cloudtrail_changes tool in the ListToolsRequestSchema handler, including description and input schema definition.name: "list_cloudtrail_changes", description: "Lists write/mutation events (Create, Update, Delete) for a specific resource or service.", inputSchema: { type: "object", properties: { resource_id: { type: "string", description: "Optional: The Resource ID or Name (e.g., sg-12345, my-bucket)." }, lookup_key: { type: "string", enum: ["ResourceName", "ResourceType", "EventName", "Username"], description: "The attribute to lookup by (default: ResourceName if resource_id provided)." }, lookup_value: { type: "string", description: "The value for the lookup key (required if resource_id is omitted)." }, days: { type: "number", description: "Lookback period in days (default: 7)." } } } },
- src/index.ts:1815-1864 (handler)Handler implementation for list_cloudtrail_changes tool. Queries CloudTrail events using LookupEventsCommand, filters for write/mutation events based on EventName patterns, and returns relevant event details.if (name === "list_cloudtrail_changes") { const resourceId = (args as any)?.resource_id; const lookupKey = (args as any)?.lookup_key || (resourceId ? "ResourceName" : undefined); const lookupValue = resourceId || (args as any)?.lookup_value; const days = (args as any)?.days || 7; if (!lookupKey || !lookupValue) { return { content: [{ type: "text", text: "Please provide a resource_id OR a lookup_key and lookup_value." }], isError: true }; } const startTime = new Date(Date.now() - days * 24 * 60 * 60 * 1000); const command = new LookupEventsCommand({ LookupAttributes: [{ AttributeKey: lookupKey, AttributeValue: lookupValue }], StartTime: startTime, MaxResults: 50 }); const response = await cloudTrailClient.send(command); // Filter for mutations (not ReadOnly) // Note: 'ReadOnly' field in event isn't always populated in LookupEvents response types directly in all SDK versions, // but we can infer or it is often there. Some events don't have it. // We'll primarily rely on showing the event name and letting user see. // But we can try to filter if resource JSON is parsed. const events = response.Events?.map(e => { let isReadOnly = true; // Try to guess read-only if not explicit. // Usually "Get", "Describe", "List" are read. "Create", "Update", "Delete", "Put", "Modify" are write. const name = e.EventName || ""; if (name.startsWith("Get") || name.startsWith("Describe") || name.startsWith("List")) { isReadOnly = true; } else { isReadOnly = false; } // If Resources tag is present, it's useful return { EventTime: e.EventTime, EventName: e.EventName, Username: e.Username, EventSource: e.EventSource, ResourceName: e.Resources?.[0]?.ResourceName, IsAssumedReadOnly: isReadOnly }; }).filter(e => !e.IsAssumedReadOnly) || []; // Show only changes return { content: [{ type: "text", text: JSON.stringify(events, null, 2) }] }; }