@auth-craft/aws-cf-stack 1.8.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +15 -0
- package/README.md +82 -4
- package/assets/admin/cli.mjs +90 -90
- package/assets/gateway/worker.js +1 -1
- package/assets/lambda/index.mjs +52 -50
- package/bin/deploy.sh +12 -0
- package/cdk/bin/app.ts +13 -2
- package/cdk/lib/dynamodb-stack.ts +59 -90
- package/cdk/lib/lambda-stack.ts +101 -4
- package/cdk/lib/table-schema.json +192 -0
- package/lib/common.sh +10 -0
- package/lib/deploy-lambda.sh +4 -0
- package/lib/sync-table-gsis.sh +257 -0
- package/package.json +17 -9
- package/cdk/cdk.out/asset.530567cf1e6fd5236cd0e483ba02427949a4a68b619db930921f8d3ba9f03689/index.mjs +0 -135
- package/cdk/cdk.out/cdk.out +0 -1
- package/cdk/cdk.out/manifest.json +0 -565
- package/cdk/cdk.out/snapshot-commerce-prod-auth-api.assets.json +0 -36
- package/cdk/cdk.out/snapshot-commerce-prod-auth-api.metadata.json +0 -277
- package/cdk/cdk.out/snapshot-commerce-prod-auth-api.template.json +0 -412
- package/cdk/cdk.out/snapshot-commerce-prod-auth-data.assets.json +0 -21
- package/cdk/cdk.out/snapshot-commerce-prod-auth-data.metadata.json +0 -151
- package/cdk/cdk.out/snapshot-commerce-prod-auth-data.template.json +0 -371
- package/cdk/cdk.out/tree.json +0 -1
package/.env.example
CHANGED
|
@@ -155,6 +155,21 @@ LAMBDA_REFRESH_COOKIE_TENANT=refresh_token_tenant
|
|
|
155
155
|
LAMBDA_REFRESH_COOKIE_SYSTEM=refresh_token_system
|
|
156
156
|
LAMBDA_AUDIT_ENABLED=false
|
|
157
157
|
LAMBDA_DEVICE_TRACKING=true
|
|
158
|
+
|
|
159
|
+
# ─── Observability cost controls (optional) ──────────────────────────────────
|
|
160
|
+
# CloudWatch Logs are billed for ingestion AND stored volume; retention only affects
|
|
161
|
+
# storage. Short retention in dev is the cheap default.
|
|
162
|
+
# Unset → 3 days in dev, 30 days in staging/prod.
|
|
163
|
+
# Valid → 1,3,5,7,14,30,60,90,120,150,180,365,400,545,731,1096,1827,2192,2557,
|
|
164
|
+
# 2922,3288,3653 (CloudWatch's fixed set — anything else fails at synth),
|
|
165
|
+
# or 'infinite' to never expire.
|
|
166
|
+
LAMBDA_LOG_RETENTION_DAYS=
|
|
167
|
+
# X-Ray tracing is billed per recorded trace. Unset → disabled in dev, active otherwise.
|
|
168
|
+
# active | disabled | pass_through
|
|
169
|
+
LAMBDA_TRACING=
|
|
170
|
+
# Adding missing GSIs to an existing table (one per CloudFormation update): max minutes to
|
|
171
|
+
# wait for each to backfill before giving up (re-running resumes). Unset → 60.
|
|
172
|
+
AUTH_CRAFT_GSI_WAIT_MINUTES=
|
|
158
173
|
LAMBDA_APP_URL=
|
|
159
174
|
LAMBDA_SUPPORT_EMAIL=
|
|
160
175
|
LAMBDA_CORS_ORIGINS=
|
package/README.md
CHANGED
|
@@ -87,7 +87,9 @@ all point at the single worker.
|
|
|
87
87
|
|
|
88
88
|
- `aws` CLI authenticated (or `AWS_*` creds in env), `cdk` (or `npx cdk`), `wrangler`,
|
|
89
89
|
`node` ≥ 20, `jq`, `curl`.
|
|
90
|
-
- AWS + Cloudflare credentials.
|
|
90
|
+
- AWS + Cloudflare credentials. Besides the CDK deploy roles, the identity running the CLI
|
|
91
|
+
needs `dynamodb:DescribeTable` on the `<app>-<stage>-<layer>-data` table and
|
|
92
|
+
`cloudformation:GetTemplate` on the data stack (see [Table schema & GSI rollout](#table-schema--gsi-rollout)).
|
|
91
93
|
|
|
92
94
|
## Usage
|
|
93
95
|
|
|
@@ -163,6 +165,75 @@ CF_EDGE_GATE_SECRET="$SNAP_EDGE" CLOUDFLARE_ACCOUNT_ID="$SNAP_CF_ACCT" \
|
|
|
163
165
|
npx auth-craft-stack all --stage "$STAGE"
|
|
164
166
|
```
|
|
165
167
|
|
|
168
|
+
## Table schema & GSI rollout
|
|
169
|
+
|
|
170
|
+
The table's keys and GSIs come from one source: `TABLE_SCHEMA` in
|
|
171
|
+
`@auth-craft/database-plugin-dynamodb`, snapshotted into `cdk/lib/table-schema.json` at build
|
|
172
|
+
time. The CDK stack, the integration tests and the create-table script all read it, so a deployed
|
|
173
|
+
table can no longer miss an index the repositories query.
|
|
174
|
+
|
|
175
|
+
CloudFormation creates or deletes **at most one GSI per table update**. A new table gets every GSI
|
|
176
|
+
at once, but an existing table deployed by an older version may lack several. Before the normal
|
|
177
|
+
deploy, `lambda` therefore:
|
|
178
|
+
|
|
179
|
+
1. `DescribeTable`s the existing table (nothing to do if it doesn't exist yet).
|
|
180
|
+
2. Deploys the data stack with the table's current GSIs **plus the next missing one**.
|
|
181
|
+
3. Waits for that GSI to finish backfilling (`ACTIVE`), then repeats until the schema is complete.
|
|
182
|
+
|
|
183
|
+
Each GSI takes a few minutes on a populated table; the wait is capped by
|
|
184
|
+
`AUTH_CRAFT_GSI_WAIT_MINUTES` (default 60) and an interrupted run resumes where it stopped.
|
|
185
|
+
|
|
186
|
+
GSIs are compared by their full definition (keys, key attribute types, projection), not by name.
|
|
187
|
+
The CLI stops before deploying, and prints how to fix it, when:
|
|
188
|
+
|
|
189
|
+
- the table has a GSI that CloudFormation doesn't know about (created by hand);
|
|
190
|
+
- the stack declares a GSI the table lacks (deleted by hand). The CLI prints the
|
|
191
|
+
`aws dynamodb update-table` command that recreates it as the stack declares it;
|
|
192
|
+
- the table has a GSI the schema no longer declares;
|
|
193
|
+
- a GSI's definition differs from the schema. CloudFormation would have to replace it, which is
|
|
194
|
+
two GSI operations in one update. A changed index needs a new name in `TABLE_SCHEMA`;
|
|
195
|
+
- a rollout step finished without adding its GSI.
|
|
196
|
+
|
|
197
|
+
The GSI subset for each rollout step goes to the CDK app as context (`-c dataGsis=...`), never as
|
|
198
|
+
an environment variable, so nothing in your shell or `--env-file` can shrink the full deploy.
|
|
199
|
+
|
|
200
|
+
## Observability cost controls (log retention, tracing)
|
|
201
|
+
|
|
202
|
+
CloudWatch Logs and X-Ray are usually the two line items that make a low-traffic **dev**
|
|
203
|
+
stage cost more than the Lambda itself. Both are configurable, with stage-aware defaults
|
|
204
|
+
that keep dev cheap without touching staging/prod behaviour:
|
|
205
|
+
|
|
206
|
+
| Setting | Env var / flag | Default (dev) | Default (staging/prod) |
|
|
207
|
+
|---------|----------------|---------------|------------------------|
|
|
208
|
+
| Log retention | `LAMBDA_LOG_RETENTION_DAYS` / `--log-retention-days` | `3` days | `30` days |
|
|
209
|
+
| X-Ray tracing | `LAMBDA_TRACING` / `--tracing` | `disabled` | `active` |
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Cheapest dev: keep 1 day of logs, no tracing (tracing is already off by default in dev)
|
|
213
|
+
npx auth-craft-stack lambda --stage dev --log-retention-days 1
|
|
214
|
+
|
|
215
|
+
# Turn tracing back on in dev while debugging
|
|
216
|
+
npx auth-craft-stack lambda --stage dev --tracing active
|
|
217
|
+
|
|
218
|
+
# Long retention for an audited prod
|
|
219
|
+
npx auth-craft-stack lambda --stage prod --log-retention-days 365
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Notes:
|
|
223
|
+
- Retention accepts only **CloudWatch's fixed set** — `1, 3, 5, 7, 14, 30, 60, 90, 120, 150,
|
|
224
|
+
180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653` — or `infinite` to never
|
|
225
|
+
expire. Any other value fails at **synth** time with the valid list, so a typo can't
|
|
226
|
+
silently deploy the wrong retention.
|
|
227
|
+
- Retention caps **storage** cost only; you are still billed for log **ingestion**. To cut
|
|
228
|
+
ingestion, reduce what the app logs.
|
|
229
|
+
- Changing retention applies to the existing log group too (it's the same CloudFormation
|
|
230
|
+
resource), so old logs beyond the new window age out — it is not just for new logs.
|
|
231
|
+
- In `prod` the log group has `RemovalPolicy.RETAIN`, so destroying the stack keeps the logs
|
|
232
|
+
(and the group must be deleted manually before a same-name redeploy). In dev/staging it is
|
|
233
|
+
destroyed with the stack.
|
|
234
|
+
- `LogRetentionDays` and `TracingMode` are emitted as CDK outputs, so
|
|
235
|
+
`npx auth-craft-stack outputs` shows what is actually deployed.
|
|
236
|
+
|
|
166
237
|
## CORS (per scope + dynamic allowlist)
|
|
167
238
|
|
|
168
239
|
CORS is resolved **per scope** (system / tenant / customer) — the 3 workers no longer
|
|
@@ -326,6 +397,11 @@ time). Bump the version to deploy newer auth-craft.
|
|
|
326
397
|
already-deployed queue. The stack grants the Lambda `sqs:SendMessage` on that ARN, but it
|
|
327
398
|
can't create a cross-stack queue — deploy your email/queue stack first, then this one.
|
|
328
399
|
|
|
400
|
+
- **`DATABASE_QUERY_ERROR` from invite flows on a table deployed by ≤ 1.9.0** — the table lacks
|
|
401
|
+
`GSI_InviteToken` / `GSI_InviteeEmail` / `GSI_InviteePhone`. Deploy `lambda` with ≥ 1.10.0; it
|
|
402
|
+
adds them one at a time. The Lambda log names the cause:
|
|
403
|
+
`ValidationException: The table does not have the specified index: …`.
|
|
404
|
+
|
|
329
405
|
## Email delivery modes
|
|
330
406
|
|
|
331
407
|
`LAMBDA_EMAIL_MODE` = `console` (default) | `smtp` | `queue`.
|
|
@@ -345,6 +421,9 @@ time). Bump the version to deploy newer auth-craft.
|
|
|
345
421
|
(ESM, `node:*` external — provided by the Workers runtime), the same way wrangler bundles
|
|
346
422
|
internally. Uses the esbuild binary in the app's `node_modules` (the root `.bin/esbuild`
|
|
347
423
|
symlink can be stale because esbuild is in pnpm `ignoredBuiltDependencies`).
|
|
424
|
+
- **Table schema**: `scripts/sync-table-schema.mjs` writes `cdk/lib/table-schema.json` from
|
|
425
|
+
`TABLE_SCHEMA` (database-plugin-dynamodb is unpublished, so the CDK app can't import it at the
|
|
426
|
+
consumer). The JSON is committed; `pnpm test` fails if it's stale (`pnpm sync:table-schema`).
|
|
348
427
|
- **Admin CLI**: esbuilds `packages/auth-admin-cli/src/index.ts` → `assets/admin/cli.mjs`,
|
|
349
428
|
fully inlined (auth-core + plugins + `pg` + aws-sdk). It is **bundled, not a dependency**,
|
|
350
429
|
because `@auth-craft/auth-admin-cli` is `private` and pulls in ~7 workspace packages —
|
|
@@ -352,6 +431,5 @@ time). Bump the version to deploy newer auth-craft.
|
|
|
352
431
|
|
|
353
432
|
The bundled `cdk/lib/lambda-stack.ts` deploys the Lambda via
|
|
354
433
|
`lambda.Code.fromAsset('../../assets/lambda')` + handler `index.handler` (not `NodejsFunction`),
|
|
355
|
-
so no source build happens at the consumer's deploy time.
|
|
356
|
-
|
|
357
|
-
unifies them.
|
|
434
|
+
so no source build happens at the consumer's deploy time. These `cdk/lib/*.ts` stacks are the
|
|
435
|
+
only CDK definition of the auth deploy — the app's old `infrastructure/` copy was removed.
|