sns-payload-validator

Verifies AWS SNS message signatures for HTTP/S and Lambda payloads.

SDK
npm
v2.1.0
13stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
35/100Needs Attention
Development Activity28
Maintenance28
Community16
Maturity56
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
67/100Good
Architecture68
Code Quality88
Innovation55
Learning Curve55

sns-payload-validator is a focused Node.js library that verifies the authenticity of Amazon SNS messages before your application acts on them. It checks the message Type, SignatureVersion, SigningCertURL, and Signature fields against Amazon’s official verification process, downloading and optionally caching the signing certificate to confirm each payload actually originated from AWS SNS rather than a spoofed request.

It supports both SNS SignatureVersion 1 (SHA1) and Version 2 (SHA256) signing schemes, and normalizes the field-name differences between HTTP/S POST payloads and Lambda event payloads (SigningCertURL vs SigningCertUrl, UnsubscribeURL vs UnsubscribeUrl) so the same validator works in either delivery mode. The library exposes async/await, Promise, and callback interfaces, ships hand-written TypeScript declarations, and is exercised daily against a live AWS account to catch upstream signing changes.

What You Get

  • Signature verification - Validates the Type, SignatureVersion, SigningCertURL, and Signature fields against AWS’s documented SNS verification process.
  • Dual signature version support - Handles both SignatureVersion 1 (SHA1withRSA) and SignatureVersion 2 (SHA256withRSA) signing schemes.
  • HTTP/S and Lambda compatibility - Normalizes the SigningCertURL/SigningCertUrl and UnsubscribeURL/UnsubscribeUrl casing differences between webhook POST bodies and Lambda events.
  • Certificate caching - Optionally caches downloaded signing certificates in an LRU cache to avoid re-fetching them on every request.
  • Flexible call styles - Returns a Promise, accepts an async/await flow, or takes a Node-style callback.

Common Use Cases

  • Webhook signature verification - An HTTP/S endpoint receiving SNS-forwarded webhook POSTs validates each payload before trusting its contents.
  • Lambda event validation - A Lambda function triggered by an SNS subscription verifies the event’s signature before processing the message body.
  • Subscription confirmation handling - A service auto-confirms new SNS subscriptions by validating and then visiting the SubscribeURL from a SubscriptionConfirmation message.
  • Custom proxy environments - An application behind a corporate proxy supplies a custom request agent so certificate downloads succeed without direct internet access.

Under The Hood

Architecture The library centers on a single Validator class exported from lib/index.js, constructed with useCache, maxCerts, and requestAgent options and validated with explicit TypeError guards. Its validate() method normalizes string payloads via JSON.parse, delegates key-list selection to the small, separately-testable lib/keys.js module (getKeys), then runs internals.validateSignature, which resolves the correct verifier (createVerifier) and either serves a cached PEM certificate or fetches one over HTTPS from the AWS-issued SigningCertURL before calling internals.verify. The internals object acts as a private namespace holding a module-level keys array set on each validate() call - a subtly stateful but effectively single-purpose design, since it exists purely to pass the selected field list from getKeys into createVerifier for that call. There is no framework or DI container; the whole flow is a short, linear pipeline (parse, get keys, resolve cert, verify signature) with no abstraction for a core change to break beyond the certUrlPattern regex, which acts as the sole gate against a spoofed certificate host.

Tech Stack The package targets Node.js (18/20/21 per its CI matrix) and ships as plain CommonJS with hand-authored TypeScript declaration files (lib/index.d.ts, interfaces/index.d.ts) rather than a compiled TypeScript build. Its only runtime dependency is lru-cache for certificate caching; it otherwise relies solely on Node’s built-in https and crypto modules to download certificates and verify RSA signatures. Development tooling centers on the Hapi ecosystem - @hapi/lab as the test runner enforcing full coverage, and @hapi/code for assertions - plus nock for HTTP mocking and node-forge for generating real certificates and signatures in tests. There’s no bundler or transpilation step; the package is published to npm as-is, with GitHub Actions running the matrix across three operating systems and reporting coverage to Coveralls.

Code Quality Tests cover both the promise and callback validate() paths across Notification, SubscriptionConfirmation, and UnsubscribeConfirmation message types, both SignatureVersion 1 and 2, and both HTTP/S and Lambda field-name variants, using realistic fixtures generated with node-forge. The project’s own test script enforces full code coverage as a hard CI gate, and CI runs the suite across ubuntu/windows/macos and multiple Node versions with Coveralls reporting. Naming is consistent camelCase with a clear internals/public-class split, ESLint is configured via a shareable Hapi config, and hand-written TypeScript declarations give consumers static type safety despite the implementation itself being plain JavaScript.

API Design The public surface is a single Validator class with one validate() method that adapts to Promise, async/await, or Node-style callback calling conventions and accepts either a JSON string or a parsed object - minimal ceremony to get started. Its most distinguishing choice is quietly reconciling the two payload shapes AWS actually sends: it accepts casing differences between HTTP/S webhooks and Lambda events, and supports both signature schemes, sparing consumers from having to know AWS’s undocumented format quirks themselves. The README documents every calling style with runnable examples, and the module is validated daily against a live AWS SNS account via a companion tester repository - a genuinely useful trust signal, though the implementation itself follows AWS’s documented verification steps rather than introducing a novel technique.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search