Skip to main content
Technical Preview

Overview

A client-mode connector for the Amazon DynamoDB API that keeps per-device state and history in a DynamoDB table straight from MQTT. DynamoDB uses the AWS JSON 1.0 protocol: every operation is POST / with Content-Type: application/x-amz-json-1.0 and an X-Amz-Target header naming the operation. Default BASE_ADDRESS is https://dynamodb.eu-west-1.amazonaws.com; change the region to match your table. Topics use data/amazon-dynamodb/<object>/<verb>, and replies arrive on <topic>/response.

Auth

DynamoDB requires AWS Signature Version 4 with service name dynamodb. It is not a Bearer token. The connector does not sign requests itself; an upstream signer (a Python action, edge service, or SDK) signs each request and publishes the signed headers with the body:
  • authorization: the AWS4-HMAC-SHA256 Credential=…, SignedHeaders=…, Signature=… value
  • x_amz_date: the X-Amz-Date timestamp used in the signature
  • x_amz_content_sha256: hex SHA-256 of the body
  • body: the DynamoDB request JSON. Only this field is sent to AWS.
Keep AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION in Hub secrets for the signer, and never commit keys. For temporary STS credentials, add an x-amz-security-token header to the events.
The signature covers the exact body bytes. Sign compact JSON (no spaces) and make sure the connector sends the same bytes. If they differ, AWS returns 400 InvalidSignatureException. This has not been verified on the broker runtime yet.
The IAM policy needs dynamodb:PutItem, UpdateItem, Query, GetItem, BatchWriteItem, ListTables and DescribeTable on the table, plus CreateTable if the connector creates it.

Basic Syntax

The full template also includes GetItem, BatchWriteItem, ListTables, DescribeTable and CreateTable, which use the same headers with their own X-Amz-Target.

Payload examples

DynamoDB values use attribute-value JSON: strings are {"S": "…"}, and numbers are {"N": "…"} written as strings. Write device state (topic data/amazon-dynamodb/item/put):
Update last-seen (topic data/amazon-dynamodb/item/update), body only:
Query a device, newest first (topic data/amazon-dynamodb/items/query), body only:
state, name, status and many other common words are DynamoDB reserved words. Alias them with ExpressionAttributeNames (#s) in update and query expressions.

Errors and limits

  • Errors are HTTP 400 JSON with __type and message, for example ValidationException, ResourceNotFoundException, ConditionalCheckFailedException, or ProvisionedThroughputExceededException (back off and retry).
  • Items are limited to 400 KB. BatchWriteItem accepts up to 25 requests (16 MB) and may return UnprocessedItems with HTTP 200; resend those.
  • Query returns at most 1 MB per call; page with LastEvaluatedKey → ExclusiveStartKey.
  • Scan, deletes, PartiQL, transactions and DynamoDB Streams (a separate streams.dynamodb endpoint) are not included.

Testing

Status: blocked on credentials. The factory box has no AWS keys, so the connector has not been smoke-tested against AWS. Wire format was checked against a local moto 5.2.3 DynamoDB emulator, which does not verify signatures: SigV4-signed requests for all eight events returned 200 (CreateTable, ListTables, DescribeTable, PutItem, UpdateItem with ALL_NEW, GetItem read-back, BatchWriteItem with no unprocessed items, and Query newest first). Against dynamodb.eu-west-1.amazonaws.com, an unsigned ListTables returned 400 MissingAuthenticationTokenException and a dummy-key signed one returned 400 UnrecognizedClientException, as expected. To clear the gate, sign ListTables with real lab keys (expect 200), then PutItem and Query on a lab table (expect 200).
Last modified on October 21, 2026