AWS Provider
Deploy Hot Updater on AWS with DynamoDB, S3, CloudFront, and Lambda@Edge, then connect your app.
Overview
Use this preset to provision an OTA server on AWS. For a new app, start with Choose infrastructure. Provision the provider resources here, then connect your app with the verified URL and key.
Prerequisites
You need the following resources and access. An AI agent can prepare missing resources through its available provider tools.
- Node.js: The CLI requires 20.19+. Agent setup uses a client-key helper that requires Node 22.18+ or Node 24+; prepare it before provisioning resources.
- AWS Account: Sign up at AWS if you don't have one.
- AWS CLI (terminal setup): Install the AWS CLI and sign in or configure a profile.
Required AWS permissions
Hot Updater requires specific AWS IAM permissions for setup and ongoing usage:
1. Initialization (one-time setup)
Used for hot-updater init:
AmazonS3FullAccess: Create and read S3 buckets.AmazonDynamoDBFullAccess_v2: Create and configure the metadata table.AWSLambda_FullAccess: Create and update Lambda functions.CloudFrontFullAccess: Manage CloudFront distributions.IAMFullAccess: Create IAM roles for Lambda@Edge.AmazonSSMFullAccess: Access SSM Parameters used for CloudFront key pairs.
2. Ongoing usage
Used for hot-updater deploy and hot-updater console:
AmazonS3FullAccess: Manage bundle artifacts in the S3 bucket.- DynamoDB table access for metadata queries and writes.
cloudfront:CreateInvalidation: Invalidate CloudFront cache after deployments.
For ongoing usage, create a separate access token with limited permissions. Here's a minimal policy example for CloudFront invalidation:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["cloudfront:CreateInvalidation"],
"Resource": "arn:aws:cloudfront::<ACCOUNT_ID>:distribution/<DISTRIBUTION_ID>"
}
]
}If this permission is missing, you may encounter the following error:
AccessDenied: User: arn:aws:sts::***:assumed-role/***/*** is not authorized to perform: cloudfront:CreateInvalidation on resource: arn:aws:cloudfront::***:distribution/*** because no identity-based policy allows the cloudfront:CreateInvalidation actionStep 1: Install required packages
Complete Install packages in the React Native project before running init or an agent scaffold. Install the CLI, React Native SDK, and the build adapter that matches your app, then install this provider:
npm install @hot-updater/aws --save-devAn agent can perform these steps after inspecting the app's package manager and build configuration.
Step 2: Configure AWS
Choose how to set up AWS:
Install the Hot Updater skill, then ask your coding agent:
$hot-updater Set up infrastructure on AWS for this project.The agent inspects your app, discovers existing configuration and resources,
and asks only for missing choices or access. It uses hot-updater agent infra setup
to generate the deployment templates, then applies and verifies them with available
provider tools. If authentication is needed, sign in through the provider or save
credentials in a local ignored file; do not paste secrets into the conversation.
See Agent Infrastructure for setup and resume.
After setup, review the local configuration. Interactive init writes the settings
below to .env.hotupdater; an agent merges the needed settings into your project.
Resource selections and the authentication mode are persisted for deterministic
reruns. AWS credentials are included only for account/access-key mode and only
when you consent to storing them.
HOT_UPDATER_DYNAMODB_TABLE_NAME=hot-updater-v1
HOT_UPDATER_AWS_AUTH_MODE=local-session
HOT_UPDATER_AWS_LAMBDA_NAME=hot-updater-v1-edge
HOT_UPDATER_S3_BUCKET_NAME=your-s3-bucket-name
HOT_UPDATER_S3_REGION=your-region
HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID=your-distribution-id
HOT_UPDATER_API_KEY=your-api-keyManaged init reuses HOT_UPDATER_API_KEY when supplied or creates an API key,
registers it in DynamoDB, and persists the plaintext value locally. Send this
API key in the app's x-api-key request header. It does not authorize
management or Insights-query routes. To list, add, or revoke keys later, run
hot-updater api-key from the app directory.
If you choose a shared AWS profile or SSO, the generated env file also includes:
HOT_UPDATER_AWS_PROFILE=your-profile-nameIf you choose the current AWS CLI/default session mode, no extra credential env variables are written. The generated config uses the AWS SDK default provider chain directly.
If you choose account/access-key mode and consent to persistence, the generated env file also includes:
# The generated key may be over-privileged or temporary depending on how you authenticated during init.
HOT_UPDATER_S3_ACCESS_KEY_ID=your-access-key-id
HOT_UPDATER_S3_SECRET_ACCESS_KEY=your-secret-access-keyKeep provider credentials from .env.hotupdater in the CLI, CI, or server environment.
Configure the update server URL and client API key explicitly in the app as shown
below. Treat both as extractable from the app bundle; never include provider credentials.
See Security.
Optional: Bundle signing
Managed AWS init does not create or enable a signing key. The
built-in local config works
without a signing adapter. For non-exportable key custody, use the
AWS KMS signer from
hot-updater/signing; signing is independent of storage and database choice.
Embed the chosen public key in a native release before deploying signed
bundles. Signing credentials belong in the deploy environment, never in the
React Native app.
Step 3: Add HotUpdater to your project
After provisioning, record these outputs for Set up your app:
| Output | Value |
|---|---|
| Client base URL | https://<your-cloudfront-distribution-url> |
| Client request header | x-api-key |
| Client API key | The saved HOT_UPDATER_API_KEY in your ignored .env.hotupdater |
| Deploy configuration | hot-updater.config.ts and the selected provider resources |
Use the actual URL returned by deployment. Configure the SDK and native bundle
loader through Set up your app, using the selected
build adapter and the same update strategy as hot-updater.config.ts. Only the
client API key belongs in the mobile app's build-time configuration; provider
credentials stay in the deploy environment.
The managed AWS runtime exposes /version publicly. OTA update checks,
Insights ingestion, and Remote Config fetches require x-api-key: $HOT_UPDATER_API_KEY, using a key registered or created during init.
Internally, the server runs the insights(), apiKeys(), and
remoteConfig() plugins; only
handlers.client is mounted. API keys do not authorize Insights query
routes, and bundle management endpoints are not mounted on the public
function URL.
Generated configuration and operations
Init generates hot-updater.config.ts with your AWS storage and database, and
plugins: the server plugins the managed Lambda@Edge function runs,
apiKeys(), insights(), and remoteConfig(), imported from hot-updater/plugins.
The CLI and the Console reach S3 and DynamoDB through these settings and run the same plugins
as the function. The managed function runs these official plugins only; to run
other server plugins, use a custom server.
On a rerun, init updates storage, database, and plugins in the existing
file and keeps your other settings, including a wrapped build such as
withSentry(bare()). When it cannot edit hot-updater.config.ts, such as a
config that a function returns, it leaves the file unchanged and prints the
storage, database, and plugins lines to add.
If you choose current AWS CLI/default session, the generated config uses the AWS SDK default provider chain instead of embedding access keys:
import { dynamoDB, s3Storage } from "@hot-updater/aws";
import { apiKeys, insights, remoteConfig } from "hot-updater/plugins";
import { bare } from "@hot-updater/bare";
import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
import { defineConfig } from "hot-updater";
import { existsSync } from "node:fs";
if (existsSync(".env.hotupdater")) {
process.loadEnvFile(".env.hotupdater");
}
const awsOptions = {
region: process.env.HOT_UPDATER_S3_REGION!,
credentials: fromNodeProviderChain(),
};
export default defineConfig({
build: bare({ enableHermes: true }),
storage: s3Storage({
...awsOptions,
bucketName: process.env.HOT_UPDATER_S3_BUCKET_NAME!,
}),
database: dynamoDB({
...awsOptions,
tableName: process.env.HOT_UPDATER_DYNAMODB_TABLE_NAME!,
cloudfrontDistributionId: process.env.HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID!,
}),
plugins: [apiKeys(), insights(), remoteConfig()],
updateStrategy: "appVersion", // or "fingerprint"
});If you choose shared AWS profile, fromNodeProviderChain() is replaced with
fromIni({ profile: process.env.HOT_UPDATER_AWS_PROFILE! }) from the same
package. SSO uses fromSSO({ profile: process.env.HOT_UPDATER_AWS_PROFILE! })
from @aws-sdk/credential-provider-sso. Init installs the package the config
imports as a dev dependency: @aws-sdk/credential-providers for the default
session and shared profile, @aws-sdk/credential-provider-sso for SSO. Only
account/access-key mode emits a literal access-key credential block.
Replace account access keys (optional)
By this point, .env.hotupdater already contains the settings selected during
hot-updater init.
This step applies only if you selected account/access-key mode during
init. Current AWS CLI/default session, shared-profile, and SSO modes use their
generated credential providers and do not read these two variables.
The account-mode credentials entered during infrastructure setup may have broader permissions than ongoing deployment requires.
Replace those credentials with a permanent least-privilege identity that can write bundle artifacts to S3, read and write the selected DynamoDB table, and invalidate the CloudFront distribution.
HOT_UPDATER_S3_ACCESS_KEY_ID=your-access-key-id
HOT_UPDATER_S3_SECRET_ACCESS_KEY=your-secret-access-keyStep 4: If you use Expo, add the config plugin
Follow the Expo path in Set up your app. It applies the config plugin and generates the native integration. For DOM components, continue with Expo DOM components.
Step 5: Add native code
For Bare or Rock, follow the Android and iOS instructions in Set up your app. Keep the integration appropriate to your React Native version and rebuild the native app after changing it.
Upgrade infrastructure
With the Hot Updater skill attached, ask your agent:
$hot-updater Upgrade this project's existing AWS server infrastructure.The agent discovers the existing deployment, uses hot-updater agent infra upgrade,
and reads the applicable version files before changing resources. It applies pending
changes and verifies the server with doctor. See
Upgrade an existing server
for the workflow or Doctor
for terminal instructions.
For server templates to apply with your own deployment tooling, use
hot-updater infra scaffold --provider aws. See
Infrastructure Templates.
Verifying the setup
-
Confirm the selected AWS resources and the deployed client base URL.
-
From the React Native project, check the server and native integration:
npx hot-updater doctor --server-base-url <client-base-url> --jsonDoctor checks the public
/versionendpoint. It does not prove an authenticated update download or application. -
Complete Test an OTA update on a release build. Verify that the app downloads and runs the changed code, then survives a restart.
An agent should report the selected resources, verified URL, configuration file paths and verification result. Report a missing access, billing or native-build prerequisite explicitly instead of marking an untested installation complete.
Host the Console
Host the console on Vercel, Netlify, or Docker/Node with AWS SDK credentials for the existing DynamoDB and S3 resources. ECS/Fargate is another option when you want an AWS task role. See the console hosting matrix.