AWS appsync medium security documentation change
Summary
Restructured documentation with expanded details about onPublish/onSubscribe handlers, error handling, and authorization examples. Added context object definitions, code samples, and security enforcement patterns.
Security assessment
Added explicit examples of authorization checks in onSubscribe handler (e.g., restricting channels based on Cognito username via util.unauthorized()). This demonstrates security controls for subscription authorization. Also added error handling examples that enforce message validation, which prevents malformed/invalid data propagation.
Diff
diff --git a/appsync/latest/eventapi/channel-namespace-handlers.md b/appsync/latest/eventapi/channel-namespace-handlers.md index f6593a180..a3d6734bc 100644 --- a//appsync/latest/eventapi/channel-namespace-handlers.md +++ b//appsync/latest/eventapi/channel-namespace-handlers.md @@ -5 +5 @@ -Using the onPublish event handlerUsing the onSubscribe event handlerData source integration +OverviewonPublish handleronSubscribe handlerError handling @@ -7 +7 @@ Using the onPublish event handlerUsing the onSubscribe event handlerData source -# An overview of channel namespace handlers and event processing +# Process real-time events with AWS AppSync event handlers @@ -9 +9 @@ Using the onPublish event handlerUsing the onSubscribe event handlerData source -You can define event handlers on channel namespaces. Event handlers are functions that run on AWS AppSync's JavaScript runtime and enable you to run custom business logic. You can use an event handler to process published events or process and authorize subscribe requests. +###### Topics @@ -11 +11 @@ You can define event handlers on channel namespaces. Event handlers are function -## Using the onPublish event handler + * Overview @@ -13 +13 @@ You can define event handlers on channel namespaces. Event handlers are function -The onPublish handler runs when events are received on a channel. The handler is called with the list of events. You can use the handler to either filter events or transform the events before they are sent to subscribed clients. + * onPublish handler @@ -15 +15 @@ The onPublish handler runs when events are received on a channel. The handler is -The default API behavior for the onPublish handler simply forwards all received events to be broadcast. The onPublish function receives a context object as its first argument. + * onSubscribe handler @@ -17 +17,25 @@ The default API behavior for the onPublish handler simply forwards all received -The following code demonstrates the default behavior for the onPublish handler. + * Error handling + + + + +## Overview + +AWS AppSync Event handlers let you run custom business logic on real-time events. + +These JavaScript functions: + + * Run on the AWS AppSync runtime + + * Process published events + + * Authorize subscription requests + + + + +This topic covers _simple_ event handlers without data source integration. For information about integrating with data sources like DynamoDB tables and Lambda functions, see: + + * [Data source integrations](https://docs.aws.amazon.com/appsync/latest/eventapi/data-source-integrations.html) + + * [Direct Lambda integrations](https://docs.aws.amazon.com/appsync/latest/eventapi/direct-lambda-integrations.html) @@ -20,3 +43,0 @@ The following code demonstrates the default behavior for the onPublish handler. - export function onPublish(ctx) { - return ctx.events - } @@ -24 +44,0 @@ The following code demonstrates the default behavior for the onPublish handler. -The Context object holds a list of events that are being handled. The type of each event is the following. @@ -25,0 +46,29 @@ The Context object holds a list of events that are being handled. The type of ea +###### Note + +Event handlers run after the incoming request is authorized through your configured authorization mode. + +## onPublish handler + +Use the `onPublish` handler to process and filter events before they reach subscribers. This handler runs each time an event is published to a channel. + +The handler uses this signature: + + + function onPublish(context: Context): OutgoingEvent[] | null + + + type Context = { + events: IncomingEvent[]; // Array of events to process + channel: string; // Channel the events were published to + identity: Identity; // Information about the publisher + info: { + channel: { + path: string; // Full channel path + segments: string[]; // Path segments + } + } + channelNamespace: { + name: string + } + operation: 'SUBSCRIBE' | 'PUBLISH' + } @@ -27,10 +76 @@ The Context object holds a list of events that are being handled. The type of ea - type IncomingEvent<T> = { - /** - * The ID associated with the event. - */ - id: String; - /** - * The payload associated with the event. - */ - payload: T; - }; +The handler receives a context object with: @@ -38 +78 @@ The Context object holds a list of events that are being handled. The type of ea -**Processing events** + * `events` \- Array of events to process @@ -40 +80 @@ The Context object holds a list of events that are being handled. The type of ea -The onPublish handler can act as an interceptor that can modify the list of events before they are broadcast. The following processing rules apply. + * `channel` \- Target channel name @@ -42 +82 @@ The onPublish handler can act as an interceptor that can modify the list of even - * Your function must return an array. + * `identity` \- Publisher information @@ -44 +83,0 @@ The onPublish handler can act as an interceptor that can modify the list of even - * Each event must match the Event type shape, and must have an ID that matches the ID of an incoming event. @@ -46 +84,0 @@ The onPublish handler can act as an interceptor that can modify the list of even - * Duplicate event IDs are not allowed. @@ -48 +85,0 @@ The onPublish handler can act as an interceptor that can modify the list of even - * Null objects in the returned array are dropped. @@ -49,0 +87 @@ The onPublish handler can act as an interceptor that can modify the list of even +For more information on the context object reference, see [the Context Reference Guide](https://docs.aws.amazon.com/https://docs.aws.amazon.com/appsync/latest/eventapi/context-reference.html). @@ -50,0 +89 @@ The onPublish handler can act as an interceptor that can modify the list of even +### Common onPublish tasks @@ -51,0 +91 @@ The onPublish handler can act as an interceptor that can modify the list of even +#### Forward all events @@ -53 +93 @@ The onPublish handler can act as an interceptor that can modify the list of even -The type of outgoing events is the following. +The default API behavior for the `onPublish` handler _forwards all received events_. The onPublish function needs a context object as a parameter. @@ -56,15 +96,2 @@ The type of outgoing events is the following. - export type OutgoingEvent<T extends any = any> = { - /** - * The ID associated with the event. - */ - id: String; - /** - * The payload associated with the event. Not required if an error is defined. - */ - payload?: T; - /** - * The error associated with the event. Populating this field with a value will - * result in this error being marked as a failure and not propogated through the - * system. - */ - error?: String; + export function onPublish(ctx) { + return ctx.events @@ -73 +100 @@ The type of outgoing events is the following. -**Filtering** +#### Filter specific events @@ -75 +102 @@ The type of outgoing events is the following. -You can filter out events, and only return the list of events you want subscribers to receive. For example, the handler below filters events and only forwards those that have “odds” greater than zero. +Filter out events and return only those matching specific criteria. In the following example, the handler filters the events and only forwards those that have _odds greater than 0.5_. @@ -79 +106 @@ You can filter out events, and only return the list of events you want subscribe - return ctx.events.filter((event) => event.payload.odds > 0) + return ctx.events.filter((event) => event.payload.odds > 0.5) @@ -82 +109 @@ You can filter out events, and only return the list of events you want subscribe -**Transforming** +#### Transform events @@ -84 +111 @@ You can filter out events, and only return the list of events you want subscribe -You can also use a handler to transform events. Do this by mapping your events to the shape that you want. For example, the handler below formats each event to include a timestamp and changes the format of the message property. +Transform events by mapping them to a new shape. In the following example, the handler below formats each event to include a _timestamp_ and changes the message to upper case format. @@ -93 +121 @@ You can also use a handler to transform events. Do this by mapping your events t - message: event.payload.message.toUpperCase() + message: event.payload.message.toUpperCase(), @@ -99 +127 @@ You can also use a handler to transform events. Do this by mapping your events t -###### Note +### Important rules for onPublish @@ -101 +129 @@ You can also use a handler to transform events. Do this by mapping your events t -Returning an event with an unknown id value results in an error. + * Avoid duplicate event IDs @@ -103 +131,9 @@ Returning an event with an unknown id value results in an error. -**Returning an error** + * Events with an `error` property won't broadcast + + * `Null` values in the returned array are ignored + + * Returns an array of events or null + + * Match each returned event ID to an incoming event + + * Using an unknown event ID will result in an error @@ -105 +140,0 @@ Returning an event with an unknown id value results in an error. -To explicitly reject an event and notify the publisher that it was not accepted, add an error property containing an error message to the processed event. The following example, rejects any event that does not include a message property. @@ -108,8 +142,0 @@ To explicitly reject an event and notify the publisher that it was not accepted, - export function onPublish(ctx) { - return ctx.events.map(event => { - if (!event.payload.message || event.payload.message.length === 0) { - event.error = "A message must be provided" - } - return event - }) - } @@ -117 +144 @@ To explicitly reject an event and notify the publisher that it was not accepted, -## Using the onSubscribe event handler +## onSubscribe handler @@ -119 +146 @@ To explicitly reject an event and notify the publisher that it was not accepted, -The onSubscribe handler is called each time a client attempts to subscribe to a channel. You can use this handler to run custom business logic, such as logging specific information, or applying additional static authorization checks. +Use the `onSubscribe` handler to authorize and process subscription requests before allowing channel subscriptions. The handler in the following example runs when the client subscribes. @@ -121 +148,12 @@ The onSubscribe handler is called each time a client attempts to subscribe to a -In the following example, the onSubscribe handler logs a message whan an admin user subscribes to a channel. +The handler uses this signature: + + + function onSubscribe(context: Context): void + +For more information on the context object reference, see [the Context Reference Guide](https://docs.aws.amazon.com/https://docs.aws.amazon.com/appsync/latest/eventapi/context-reference.html). +