> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# AWS SNS

<!-- -->

[Server](#)[ ](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/aws)

<!-- -->

[Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/aws)[ ](https://www.npmjs.com/package/@walkeros/server-destination-aws)

<!-- -->

[Package](https://www.npmjs.com/package/@walkeros/server-destination-aws)

Server-side event publishing to [AWS Simple Notification Service](https://aws.amazon.com/sns/) topics. Each event is serialized as JSON and published via the official `@aws-sdk/client-sns` SDK. Supports the AWS default credential chain, profile-based authentication, and pre-configured client injection. Idempotent topic provisioning via the `setup()` lifecycle, with declared subscriptions, KMS encryption, FIFO ordering, and per-event message attributes.

The destination ships inside `@walkeros/server-destination-aws` alongside Firehose. Import the named export `destinationSNS` and reference it via the `code` field in `flow.json`.

<!-- -->

Where this fits

SNS is a **server destination** in the walkerOS flow:

Publishes events to an SNS topic for fan-out delivery to SQS queues, Lambda functions, HTTPS endpoints, email, SMS, and custom subscribers.

## Installation[​](#installation "Direct link to Installation")

```
npm install @walkeros/server-destination-aws
```

* Integrated
* Bundled

```
import { startFlow } from '@walkeros/collector';
import { destinationSNS } from '@walkeros/server-destination-aws';

await startFlow({
  destinations: {
    sns: {
      code: destinationSNS,
      config: {
        settings: {
          topicName: 'walkeros-events',
          region: 'eu-central-1',
        },
      },
    },
  },
});
```

Add to your `flow.json` destinations:

```
"destinations": {
  "sns": {
    "package": "@walkeros/server-destination-aws",
    "import": "destinationSNS",
    "config": {
      "settings": {
        "topicName": "walkeros-events",
        "region": "eu-central-1"
      }
    }
  }
}
```

[See bundled mode setup](https://www.walkeros.io/docs/getting-started/modes/bundled.md) | [CLI reference](https://www.walkeros.io/docs/apps/cli.md)

## Configuration[​](#configuration "Direct link to Configuration")

This <!-- -->destination<!-- --> uses the standard <!-- -->destination<!-- --> config wrapper (consent, data, env, id, ...). For the shared fields see [destination<!-- --> configuration](https://www.walkeros.io/docs/destinations.md#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to Settings")

| Property     | Type     | Description                                                                                                  | More |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------ | ---- |
| `topicName*` | `string` | SNS topic name (like walkeros-events). Required.                                                             |      |
| `region`     | `string` | AWS region (like eu-central-1).                                                                              |      |
| `client`     | `any`    | Pre-configured AWS SNSClient instance.                                                                       |      |
| `config`     | `any`    | AWS SDK SNSClient configuration options.                                                                     |      |
| `topicArn`   | `string` | Topic ARN. Populated by init() from CreateTopic. Operators may pre-set to skip the runtime CreateTopic call. |      |

\* Required fields

## Mapping[​](#mapping "Direct link to Mapping")

Per-event rules under `config.mapping`. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](https://www.walkeros.io/docs/mapping.md).

| Property                 | Type                  | Description | More |
| ------------------------ | --------------------- | ----------- | ---- |
| `messageAttributes`      | `Record<string, any>` |             |      |
| `messageGroupId`         | `any`                 |             |      |
| `messageDeduplicationId` | `any`                 |             |      |

<!-- -->

## Authentication[​](#authentication "Direct link to Authentication")

Three modes, evaluated in order:

1. **Default credential chain.** Nothing to configure beyond `region`. The AWS SDK resolves credentials in the standard order: environment variables, shared credentials file, IAM role attached to the runtime (EC2, ECS, Lambda).
2. **Profile or explicit credentials via `settings.config`.** Pass `config.credentials` or `config.profile`, forwarded directly to the SDK.
3. **Pre-configured client.** Pass an existing `SNSClient` instance as `settings.client` for shared clients across destinations or custom transport.

## Setup[​](#setup "Direct link to Setup")

Provision the topic, attributes, tags, and declared subscriptions in one shot:

```
walkeros setup destination.sns -c flow.json
```

Setup is **authoritative-apply**: declared state is written to declared resources via a single idempotent `CreateTopic` call (plus one `Subscribe` call per declared subscription). Non-declared subscriptions and tags are left untouched, never listed, never logged. Operators may freely manage subscriptions or tags outside walkerOS without interference. Re-running setup against a fully provisioned topic with declared state matching actual produces zero state mutations.

The result is JSON-stringified to stdout:

```
{

  "topicArn": "arn:aws:sns:eu-central-1:000000000000:walkeros-events",

  "topicCreated": true,

  "tagsApplied": 2,

  "subscriptionsCreated": 1

}
```

`topicCreated` reflects whether the topic existed before this setup run (via a `GetTopicAttributes` probe against an STS-derived candidate ARN). `tagsApplied` and `subscriptionsCreated` count declared resources written.

### FIFO topics[​](#fifo-topics "Direct link to FIFO topics")

Set `setup.fifoTopic: true`. The destination auto-appends `.fifo` to the topic name when missing and applies `FifoTopic`/`ContentBasedDeduplication` attributes at creation. Reverse: `setup.fifoTopic: false` with a `.fifo` suffix throws a clear error.

### KMS encryption[​](#kms-encryption "Direct link to KMS encryption")

Set `setup.kmsMasterKeyId` to apply server-side encryption at creation. The AWS-managed default key alias is `alias/aws/sns`.

### Subscriptions[​](#subscriptions "Direct link to Subscriptions")

Each declared subscription is created with one idempotent `Subscribe` call. Supported protocols: `sqs`, `lambda`, `https`, `http`, `email`, `sms`. Per-subscription attributes (`rawMessageDelivery`, `filterPolicy`, `deadLetterTargetArn`) are applied at the same call.

```
"setup": {

  "subscriptions": [

    {

      "protocol": "sqs",

      "endpoint": "arn:aws:sqs:eu-central-1:000000000000:walkeros-q",

      "rawMessageDelivery": true

    }

  ]

}
```

## FIFO ordering[​](#fifo-ordering "Direct link to FIFO ordering")

`messageGroupId` and `messageDeduplicationId` are `Mapping.Value` fields resolved per event. A string path drives the value from event data; a value-config form supplies a literal:

```
"mapping": {

  "order": {

    "complete": {

      "settings": {

        "messageGroupId": "user.id",

        "messageDeduplicationId": "id"

      }

    }

  }

}
```

## Message attributes[​](#message-attributes "Direct link to Message attributes")

`messageAttributes` is a `Mapping.Map`. Each value resolves per event to the SDK's `{ DataType, StringValue }` shape. Bare strings are auto-wrapped as `{ DataType: 'String', StringValue }`:

```
"mapping": {

  "product": {

    "view": {

      "settings": {

        "messageAttributes": {

          "schema_version": { "value": { "DataType": "String", "StringValue": "v4" } },

          "tenant": "data.tenant_id"

        }

      }

    }

  }

}
```

## IAM[​](#iam "Direct link to IAM")

Setup role:

* `sns:CreateTopic`
* `sns:GetTopicAttributes` (existence probe)
* `sns:Subscribe`
* `sts:GetCallerIdentity` (account-ID resolution)

Runtime push role:

* `sns:Publish`
* `sns:CreateTopic` (init's idempotent ARN capture). Drop this if you pre-populate `settings.topicArn` from setup output.

Recommended: separate roles for setup and runtime. Setup runs from a provisioner identity; runtime push uses a least-privileged role.

## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting")

**`NotFoundException` at push time.** The topic was deleted or the runtime role lacks `sns:Publish`. Re-run `walkeros setup destination.sns` or verify IAM.

**`AccessDenied` at setup.** The setup role is missing one of the four permissions above. Check that `sts:GetCallerIdentity` is granted; SNS errors on a missing account-ID probe propagate verbatim.

**FIFO suffix error.** A topic name ending in `.fifo` was supplied with `setup.fifoTopic: false`, or vice versa. Either set `fifoTopic: true` or rename the topic.

**Subscription endpoint rejected.** AWS validates the endpoint at `Subscribe` time. SNS does NOT create the SQS queue, Lambda, or HTTPS endpoint. Provision those resources separately, then declare the subscription here.

## Next steps[​](#next-steps "Direct link to Next steps")

* [AWS SQS source](https://www.walkeros.io/docs/sources/server/sqs.md) for the consumer side. Standard pattern: SNS topic fans out to one or more SQS queues that walkerOS pulls.
* [Mapping configuration](https://www.walkeros.io/docs/mapping.md)
* [Flow configuration](https://www.walkeros.io/docs/getting-started/flow.md)
