diff --git a/packages/parser/src/schemas/s3.ts b/packages/parser/src/schemas/s3.ts index 0505f635be..c7d0b78541 100644 --- a/packages/parser/src/schemas/s3.ts +++ b/packages/parser/src/schemas/s3.ts @@ -8,7 +8,7 @@ const S3Identity = z.object({ }); const S3RequestParameters = z.object({ - sourceIPAddress: z.string().ip(), + sourceIPAddress: z.union([z.string().ip(), z.literal('s3.amazonaws.com')]), }); const S3ResponseElements = z.object({ @@ -24,7 +24,7 @@ const S3Message = z.object({ size: z.number().optional(), urlDecodedKey: z.string().optional(), eTag: z.string().optional(), - sequencer: z.string(), + sequencer: z.string().optional(), // Only present in PUT and DELETE events versionId: z.optional(z.string()), }), bucket: z.object({ diff --git a/packages/parser/tests/events/s3/s3-lifecycle-event.json b/packages/parser/tests/events/s3/s3-lifecycle-event.json new file mode 100644 index 0000000000..6fb7d482dd --- /dev/null +++ b/packages/parser/tests/events/s3/s3-lifecycle-event.json @@ -0,0 +1,36 @@ +{ + "Records": [ + { + "eventVersion": "2.3", + "eventSource": "aws:s3", + "awsRegion": "us-west-2", + "eventTime": "1970-01-01T00:00:00.000Z", + "eventName": "LifecycleExpiration:Delete", + "userIdentity": { + "principalId": "s3.amazonaws.com" + }, + "requestParameters": { + "sourceIPAddress": "s3.amazonaws.com" + }, + "responseElements": { + "x-amz-request-id": "C3D13FE58DE4C810", + "x-amz-id-2": "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD" + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "testConfigRule", + "bucket": { + "name": "amzn-s3-demo-bucket", + "ownerIdentity": { + "principalId": "A3NL1KOZZKExample" + }, + "arn": "arn:aws:s3:::amzn-s3-demo-bucket" + }, + "object": { + "key": "expiration/delete", + "sequencer": "0055AED6DCD90281E5" + } + } + } + ] +} diff --git a/packages/parser/tests/unit/schema/s3.test.ts b/packages/parser/tests/unit/schema/s3.test.ts index 2335934d03..c59a799280 100644 --- a/packages/parser/tests/unit/schema/s3.test.ts +++ b/packages/parser/tests/unit/schema/s3.test.ts @@ -97,6 +97,20 @@ describe('Schema: S3', () => { expect(result).toStrictEqual(event); }); + it('parses an S3 LifeCycle event with a deleted object', () => { + // Prepare + const event = getTestEvent({ + eventsPath, + filename: 's3-lifecycle-event', + }); + + // Act + const result = S3Schema.parse(event); + + // Assess + expect(result).toStrictEqual(event); + }); + it('parses an S3 Object Lambda with an IAM user', () => { // Prepare const event = structuredClone(baseLambdaEvent);