@auth-craft/aws-cf-stack 1.7.1 → 1.8.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 CHANGED
@@ -11,12 +11,20 @@
11
11
  # Required vs optional is marked per line.
12
12
 
13
13
  # ─── Stage / project / naming ────────────────────────────────────────────────
14
+ # Resources are named {app}-{env}-{layer}-{component}, e.g. snapshot-commerce-prod-auth-data.
15
+ # app = AUTH_CRAFT_APP_NAME, else auth-craft[-<project>]
16
+ # env = STAGE
17
+ # layer = LAYER (default "auth")
18
+ # component = per-resource: data (table), api (Lambda), system/tenant/customer (workers)
19
+ # The {app}-{env}-{layer} base (no component) is also AUTH_SYSTEM_NAME / the JWT issuer.
14
20
  STAGE=dev # optional (flag --stage), default dev | staging | prod
15
21
  # also accepts production -> prod, development -> dev
16
- PROJECT=default # optional (flag --project), default "default" (multi-tenant naming)
17
- AUTH_CRAFT_APP_NAME= # optional (flag --app-name) — override the app/resource name
18
- # (e.g. snapshot-auth). Unset = auth-craft[-<project>]. Drives
19
- # stack names, table, Lambda fn, worker names.
22
+ PROJECT=default # optional (flag --project), default "default". app = auth-craft-<project>
23
+ AUTH_CRAFT_APP_NAME= # optional (flag --app-name) — full rebrand of the app name
24
+ # (e.g. snapshot-commerce, drops the auth-craft prefix).
25
+ # Unset = auth-craft[-<project>].
26
+ LAYER=auth # optional (flag --layer), default "auth" — layer namespace within
27
+ # the app; use a larger app's other layers (e.g. billing) per deploy.
20
28
 
21
29
  # ─── Tool command overrides (optional — pin your own binaries) ───────────────
22
30
  AUTH_CRAFT_WRANGLER_CMD= # optional — e.g. "pnpm wrangler"; default "npx --yes wrangler"
package/README.md CHANGED
@@ -28,17 +28,30 @@ process env.
28
28
 
29
29
  ### Naming convention
30
30
 
31
- Everything is named from `--stage` (`dev|staging|prod`) and `--project` (default
32
- `default`). With the default project, `app = auth-craft`; otherwise `app = auth-craft-<project>`.
31
+ Pattern: **`{app}-{env}-{layer}-{component}`**.
32
+
33
+ - **`app`** — `auth-craft` by default; `auth-craft-<project>` with `--project`; or a full
34
+ rebrand with `--app-name` / `AUTH_CRAFT_APP_NAME` (e.g. `snapshot-commerce`).
35
+ - **`env`** — `--stage` (`dev|staging|prod`).
36
+ - **`layer`** — `--layer` / `LAYER`, default `auth`. Namespaces this deploy within a larger
37
+ app that has other layers (e.g. `--layer billing`), so the CLI is reused per layer.
38
+ - **`component`** — per-resource: `data` (table), `api` (Lambda), `system`/`tenant`/`customer`
39
+ (gateway workers).
33
40
 
34
41
  | Resource | Name |
35
42
  |----------|------|
36
- | CDK stacks | `<app>-<stage>-data`, `<app>-<stage>-api` |
37
- | Lambda fn + DynamoDB table | `<app>-<stage>` |
38
- | Gateway workers (`multi`) | `<app>-<stage>-system` / `-tenant` / `-customer` |
39
- | Gateway worker (`shared`) | `<app>-<stage>` |
40
-
41
- So `outputs`/`gateway` look up the api stack `<app>-<stage>-api`. The CDK output keys are
43
+ | CDK stacks | `<app>-<env>-<layer>-data`, `<app>-<env>-<layer>-api` |
44
+ | DynamoDB table | `<app>-<env>-<layer>-data` |
45
+ | Lambda fn (+ log group) | `<app>-<env>-<layer>-api` |
46
+ | Gateway workers (`multi`) | `<app>-<env>-<layer>-system` / `-tenant` / `-customer` |
47
+ | Gateway worker (`shared`) | `<app>-<env>-<layer>` |
48
+ | `AUTH_SYSTEM_NAME` / JWT issuer | `<app>-<env>-<layer>` (no component — keeps the `iss` claim stable) |
49
+
50
+ Example (`--app-name snapshot-commerce --stage prod`, default layer):
51
+ `snapshot-commerce-prod-auth-data` (table), `snapshot-commerce-prod-auth-api` (Lambda),
52
+ `snapshot-commerce-prod-auth-system` (worker), issuer `snapshot-commerce-prod-auth`.
53
+
54
+ So `outputs`/`gateway` look up the api stack `<app>-<env>-<layer>-api`. The CDK output keys are
42
55
  `LambdaFunctionUrl`, `ApiBasePath`, `AuthSystemName`, `DynamoDBTableName`.
43
56
 
44
57
  ### Deploy model (multi vs shared)
@@ -214,8 +227,8 @@ worker names + a ready-to-paste snippet are in `auth-craft-stack outputs`:
214
227
  ```jsonc
215
228
  // auth-craft-stack outputs →
216
229
  {
217
- "workerNames": { "system": "auth-craft-prod-system", "tenant": "...", "customer": "auth-craft-prod-customer" },
218
- "pagesProxy": { "serviceBindingExample": "[[services]]\nbinding = \"AUTH_GATEWAY\"\nservice = \"auth-craft-prod-customer\"\n" }
230
+ "workerNames": { "system": "auth-craft-prod-auth-system", "tenant": "...", "customer": "auth-craft-prod-auth-customer" },
231
+ "pagesProxy": { "serviceBindingExample": "[[services]]\nbinding = \"AUTH_GATEWAY\"\nservice = \"auth-craft-prod-auth-customer\"\n" }
219
232
  }
220
233
  ```
221
234
 
@@ -225,7 +238,7 @@ In the Pages app:
225
238
  # wrangler.toml (your Pages project) — bind the gateway worker for the scope this app serves
226
239
  [[services]]
227
240
  binding = "AUTH_GATEWAY"
228
- service = "auth-craft-prod-customer" # from outputs.workerNames.<scope>
241
+ service = "auth-craft-prod-auth-customer" # from outputs.workerNames.<scope>
229
242
  ```
230
243
 
231
244
  ```ts
package/bin/deploy.sh CHANGED
@@ -44,6 +44,9 @@ Options (each also reads an env var; the flag wins):
44
44
  --stage <dev|staging|prod> Stage (env STAGE, default dev; accepts production/development)
45
45
  --project <name> CDK project (env PROJECT, default "default")
46
46
  --app-name <name> Override app name (env AUTH_CRAFT_APP_NAME; default auth-craft[-project])
47
+ --layer <name> Layer namespace within the app (env LAYER, default "auth").
48
+ Resource names are {app}-{env}-{layer}-{component}, so a larger
49
+ app with other layers (e.g. billing) reuses this CLI per layer.
47
50
  --region <region> AWS region (env LAMBDA_AWS_REGION, default us-east-1)
48
51
  --gateway-secret <v> env LAMBDA_GATEWAY_SECRET
49
52
  --jwt-public-key <v> env LAMBDA_JWT_PUBLIC_KEY
@@ -78,6 +81,7 @@ while [[ $# -gt 0 ]]; do
78
81
  --stage) FLAG[STAGE]="${2:?}"; shift 2 ;;
79
82
  --project) FLAG[PROJECT]="${2:?}"; shift 2 ;;
80
83
  --app-name) FLAG[AUTH_CRAFT_APP_NAME]="${2:?}"; shift 2 ;;
84
+ --layer) FLAG[LAYER]="${2:?}"; shift 2 ;;
81
85
  --region) FLAG[LAMBDA_AWS_REGION]="${2:?}"; shift 2 ;;
82
86
  --gateway-secret) FLAG[LAMBDA_GATEWAY_SECRET]="${2:?}"; shift 2 ;;
83
87
  --jwt-public-key) FLAG[LAMBDA_JWT_PUBLIC_KEY]="${2:?}"; shift 2 ;;
@@ -142,7 +146,7 @@ case "$COMMAND" in
142
146
  # if not already exported in this process (e.g. snapshot drove `lambda` separately).
143
147
  if [[ -z "${LAMBDA_FUNCTION_URL:-}" || -z "${API_BASE_PATH:-}" ]]; then
144
148
  require_aws_identity
145
- api_stack="${APP_NAME}-${STAGE}-api"
149
+ api_stack="${RESOURCE_NAME}-api"
146
150
  LAMBDA_FUNCTION_URL="$(cfn_output "$api_stack" LambdaFunctionUrl)"
147
151
  API_BASE_PATH="$(cfn_output "$api_stack" ApiBasePath)"
148
152
  AUTH_SYSTEM_NAME="$(cfn_output "$api_stack" AuthSystemName)"
package/cdk/bin/app.ts CHANGED
@@ -10,6 +10,7 @@ const app = new cdk.App();
10
10
  const rawStage = process.env.STAGE || 'dev';
11
11
  const stage = rawStage === 'production' ? 'prod' : rawStage === 'development' ? 'dev' : rawStage;
12
12
  const project = process.env.PROJECT || 'default'; // Client project name
13
+ const layer = process.env.LAYER || 'auth'; // Layer namespace within the app (default "auth")
13
14
 
14
15
  const env = {
15
16
  account: process.env.CDK_DEFAULT_ACCOUNT,
@@ -17,18 +18,25 @@ const env = {
17
18
  };
18
19
 
19
20
  // ==================== Naming Convention ====================
20
- // Stack naming: {app}-{env}-{layer}
21
- // - app: AUTH_CRAFT_APP_NAME if set, else "auth-craft" (base) / "auth-craft-{project}"
22
- // - env: "dev", "staging", "prod"
23
- // - layer: "data", "api"
24
- // Examples: auth-craft-dev-data, auth-craft-staging-api, snapshot-auth-prod-api
21
+ // Pattern: {app}-{env}-{layer}-{component}
22
+ // - app: AUTH_CRAFT_APP_NAME if set, else "auth-craft" (base) / "auth-craft-{project}"
23
+ // - env: "dev", "staging", "prod"
24
+ // - layer: LAYER (default "auth") — namespaces this deploy within a larger app
25
+ // - component: per-resource suffix ("data" for the table, "api" for the Lambda)
26
+ // The {app}-{env}-{layer} base is the resourceName (AUTH_SYSTEM_NAME / JWT issuer);
27
+ // it carries no component so the iss claim stays stable across resources.
28
+ // Examples: snapshot-commerce-prod-auth-data, snapshot-commerce-prod-auth-api
25
29
 
26
30
  const appName =
27
31
  process.env.AUTH_CRAFT_APP_NAME || (project === 'default' ? 'auth-craft' : `auth-craft-${project}`);
28
32
 
33
+ // Base name shared by every resource (also AUTH_SYSTEM_NAME / JWT issuer).
34
+ const resourceBase = `${appName}-${stage}-${layer}`;
35
+
29
36
  console.log(`🚀 Deploying Auth Craft to AWS`);
30
37
  console.log(` App: ${appName}`);
31
38
  console.log(` Stage: ${stage}`);
39
+ console.log(` Layer: ${layer}`);
32
40
  console.log(` Region: ${env.region}`);
33
41
 
34
42
  // Common tags for cost allocation
@@ -39,30 +47,29 @@ const costTags = {
39
47
  ManagedBy: 'CDK',
40
48
  };
41
49
 
42
- // Stack naming helper: {app}-{env}-{layer}
43
- const getStackName = (layer: string) => `${appName}-${stage}-${layer}`;
44
-
45
- // Resource naming helper: {app}-{env}
46
- const getResourceName = () => `${appName}-${stage}`;
50
+ // Stack / resource naming helper: {app}-{env}-{layer}-{component}
51
+ const nameFor = (component: string) => `${resourceBase}-${component}`;
47
52
 
48
- // DynamoDB Stack (data layer)
49
- const dynamodbStack = new DynamoDBStack(app, `${appName}-${stage}-data`, {
53
+ // DynamoDB Stack (data component)
54
+ const dynamodbStack = new DynamoDBStack(app, nameFor('data'), {
50
55
  env,
51
- stackName: getStackName('data'),
52
- description: `Auth Craft DynamoDB (${appName}-${stage})`,
56
+ stackName: nameFor('data'),
57
+ description: `Auth Craft DynamoDB (${resourceBase})`,
53
58
  tags: costTags,
54
- resourceName: getResourceName(),
59
+ tableName: nameFor('data'),
55
60
  stage,
56
61
  });
57
62
 
58
- // Lambda Stack (api layer)
59
- const lambdaStack = new LambdaStack(app, `${appName}-${stage}-api`, {
63
+ // Lambda Stack (api component)
64
+ const lambdaStack = new LambdaStack(app, nameFor('api'), {
60
65
  env,
61
- stackName: getStackName('api'),
62
- description: `Auth Craft Lambda API (${appName}-${stage})`,
66
+ stackName: nameFor('api'),
67
+ description: `Auth Craft Lambda API (${resourceBase})`,
63
68
  table: dynamodbStack.table,
64
69
  tags: costTags,
65
- resourceName: getResourceName(),
70
+ functionName: nameFor('api'),
71
+ // Base {app}-{env}-{layer} — AUTH_SYSTEM_NAME / JWT issuer (no component).
72
+ resourceName: resourceBase,
66
73
  stage,
67
74
  });
68
75