---
title: "AWS AppConfig"
description: "Use AWS AppConfig for MainSDK runtime settings - IAM access, main.yaml, typed config.get and watch, last good values, testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/aws-appconfig"
updated: "2026-10-28"
---

# AWS AppConfig

> Use AWS AppConfig for MainSDK runtime settings - IAM access, main.yaml, typed config.get and watch, last good values, testing and swapping.

Canonical: https://mainsdk.dev/docs/integrations/aws-appconfig · Updated: 2026-10-28

AWS AppConfig is one of the stores behind [`config`](https://mainsdk.dev/docs/interfaces/config). You keep runtime settings, such as a cart limit or a support banner, in AppConfig, and your app reads them with `config.get()`, typed against a JSON schema in your repo. Changes reach the app without a deploy, a bad value keeps the last good one, and every change the app sees is audited. Pick AppConfig when your app runs on AWS and you want AppConfig's staged deployments and rollback for settings.

## Interfaces it serves

### Runtime settings (`config`)

- Status: Building for 0.2 · ships as a stable API
- Driver: `aws-appconfig` (AWS AppConfig). planned
- Docs: https://mainsdk.dev/docs/interfaces/config.md

```yaml
config:
  driver: aws-appconfig
```

Swap to another provider: `files`, `local`, `redis`, `postgres`, `vercel-global-config`, `cloudflare-kv`.

## Before you start

You need an AWS account and permission to manage AppConfig and IAM.

1. **Create an application** in AppConfig for your app, in the AWS Region closest to where it runs.
2. **Create an environment for each stage** (for example dev, stage and prod), so a change rolls out to one before the next.
3. **Create a freeform configuration profile** holding your settings as JSON. AppConfig can also validate a configuration against a JSON Schema before it deploys; add the same `config.schema.json` you use in your repo so a bad value is caught on both sides.
4. **Choose a deployment strategy.** AppConfig deploys a new version gradually and can roll back on a CloudWatch alarm.
5. **Give your app an IAM role** that can read that configuration. Prefer a workload identity (an IAM role for your compute) over long-lived access keys.

## Configure

```yaml title="main.yaml"
config:
  driver: aws-appconfig
  schema: ./config.schema.json   # JSON schema that types every key
  # [TBD] application, environment, profile and region keys
```

The connection keys for AppConfig (application, environment, configuration profile, region) are not decided yet. Settings are not secrets: keep credentials in [Secrets](https://mainsdk.dev/docs/interfaces/secrets) and refer to them as `secret:NAME`.

Use files in development and AppConfig in production:

```yaml title="main.env.dev.yaml"
config:
  driver: files
```

```yaml title="main.env.prod.yaml"
config:
  driver: aws-appconfig
```

## Use it

```ts title="app/api/cart/route.ts"
import { auth, config } from "mainsdk";

export async function POST(req: Request) {
  await auth.require(req);
  const { items } = await req.json();
  const max = config.get("cart.maxItems");   // typed as number from the schema
  if (items.length > max) {
    return Response.json({ error: `Keep the cart to ${max} items` }, { status: 422 });
  }
  return Response.json({ ok: true });
}
```

React to a deployment without a redeploy of your app:

```ts title="server/worker.ts"
import { config, log } from "mainsdk";

const stop = config.watch("worker.batchSize", (value) => {
  log.info("batch size changed", { value });
});
```

## Local development and testing

- **No AWS account:** `mainsdk dev` runs `config` on the `files` driver, with no network calls.
- **Tests:** `createTestApp()` from `@mainsdk/testing` runs `config` on its in-memory fake, and the same tests pass on each config driver. `chaos.on("config", { outage: true })` simulates AppConfig being unreachable; `config.get()` keeps returning the last good value.

## What MainSDK adds on top

- Typed against your schema: an unknown key fails type checking, and a value that fails the schema is rejected with `MAIN-CONFIG-0020` while the last good value is kept.
- Changes without a deploy, through `config.watch()`.
- Every change the app sees written to the audit log with the key, hashes of the old and new values, and the source.
- When AppConfig is unreachable after a value was read, the last good value is served from memory and reported (fail static).

See [Runtime settings](https://mainsdk.dev/docs/interfaces/config) for the full contract.

## Limits and notes

- Comes with the `config-secrets` spec (phase 1, milestone 0.2).
- AppConfig is regional. Keep the configuration in a Region that matches where your app runs; MainSDK regions are US, EU and India. Settings should hold no personal data.
- What happens when AppConfig is down at startup, before any successful read, is not specified yet.
- `config.raw()` returns the provider's client for AppConfig-only features. Every use is logged and listed by `mainsdk check`.

## Swap to or from it

```yaml title="main.yaml"
config:
  driver: aws-appconfig   # was vercel-global-config
```

Your schema, `config.get()` and `config.watch()` calls stay the same. Copy the values into the new store before you switch.

## FAQ

**Do I still need AppConfig's own SDK or agent?** Your code calls `config`; the driver talks to AppConfig. Whether the driver uses the AppConfig Agent or the data plane API directly is not specified yet [TBD].

**Should feature flags go in AppConfig too?** Use [Feature flags](https://mainsdk.dev/docs/interfaces/flags) for per-user or per-market switches and `config` for typed values that apply to the whole app.

**Where do secrets go?** Not in AppConfig settings. Use [AWS Secrets Manager](https://mainsdk.dev/docs/integrations/aws-secrets-manager) behind `secrets`.

## Next

- [Runtime settings](https://mainsdk.dev/docs/interfaces/config) and [Feature flags](https://mainsdk.dev/docs/interfaces/flags)
- [AWS Secrets Manager](https://mainsdk.dev/docs/integrations/aws-secrets-manager), [Vercel](https://mainsdk.dev/docs/integrations/vercel) and [Cloudflare KV](https://mainsdk.dev/docs/integrations/cloudflare-kv)
- [Swap a driver](https://mainsdk.dev/docs/guides/swap-a-driver)
