Skip to main content

Architecture overview

Neo runs entirely on managed AWS services. There are no long-running servers — every entry point is either an API Gateway → Lambda invocation or an IoT Core rule that fans out to a Lambda. State lives in DynamoDB, with index overloading to keep the table count small.

High-level diagram

Layer breakdown

Auth (Cognito + JWT + SigV4)

End-user clients sign in to a Cognito User Pool, exchange the resulting JWT for short-lived AWS credentials via a Cognito Identity Pool, and use those credentials to call REST APIs (SigV4-signed) and to publish/subscribe over MQTT. The assume_role Lambda is the bridge between the user-friendly /login2 flow and AWS-native credentials.

Compute (Lambda)

Every API and IoT-rule destination is a Go Lambda binary built from a *_main.go file. The split into per-feature packages (group, node, user, notification, etc.) keeps cold-start sizes small and lets us deploy individual functions without redeploying the whole stack.

Data (DynamoDB, index-overloaded)

DynamoDB tables use partition + sort keys plus GSIs to encode multiple access patterns in a single table. The relevant indexes are:

  • rmng-user-group-assoc-by-group-id on UserGroupMappingTable
  • user_table_user_code_index on UserTable
  • rmng-group-node-assoc-by-node-id on GroupDeviceMappingTable

Device plane (IoT Core)

Devices authenticate to AWS IoT Core with X.509 certificates. Three IoT rules drive the rest of the system:

RuleTopicAction
device_to_cloud_rulerainmaker/nodes/+/to_cloudInvoke publish_input_event_handler
node_online_rule$aws/events/presence/connected/+Update NodesOnlineTable and invoke presence handler
node_offline_rule$aws/events/presence/disconnected/#Invoke presence_event_handler

For deeper dives into specific subsystems, see the spec pages under Cloud Backend → Specifications.