@jaypie/mcp 0.8.156 → 0.8.158
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/dist/suites/docs/index.js +1 -1
- package/package.json +1 -1
- package/release-notes/constructs/1.2.85.md +22 -0
- package/release-notes/constructs/1.2.86.md +42 -0
- package/release-notes/mcp/0.8.157.md +13 -0
- package/release-notes/mcp/0.8.158.md +19 -0
- package/skills/cdk.md +2 -2
- package/skills/dynamodb.md +61 -3
- package/skills/migrations.md +21 -8
- package/skills/secrets.md +63 -1
|
@@ -13,7 +13,7 @@ import { RELEASE_NOTES_HELP } from './help.js';
|
|
|
13
13
|
/**
|
|
14
14
|
* Docs Suite - Documentation services (skill, version, release_notes)
|
|
15
15
|
*/
|
|
16
|
-
const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.
|
|
16
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.158#55ed6fbc"
|
|
17
17
|
;
|
|
18
18
|
// =============================================================================
|
|
19
19
|
// ASSET PATHS
|
package/package.json
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.85
|
|
3
|
+
date: 2026-09-13
|
|
4
|
+
summary: Per-build tags skip DynamoDB tables so migration-owned indexes survive redeploys
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- **`constructTagger`** adds `buildDate`, `buildHex`, `buildTime`, `commit`, and
|
|
10
|
+
`version` with `excludeResourceTypes` for `AWS::DynamoDB::GlobalTable` and
|
|
11
|
+
`AWS::DynamoDB::Table`. These tags changed every synth, forcing a table update
|
|
12
|
+
on every deploy. A table whose GSIs a migration created rejects that update
|
|
13
|
+
with `Invalid AttributeDefinitions`, so every deploy after the first rolled
|
|
14
|
+
back (#548).
|
|
15
|
+
- **`JaypieInfrastructureStack`** applies the same exclusion to `stackSha`.
|
|
16
|
+
|
|
17
|
+
## Upgrade
|
|
18
|
+
|
|
19
|
+
Tables deployed with earlier versions carry the build tags. The first deploy on
|
|
20
|
+
this version removes them, which is a table update. A table with no
|
|
21
|
+
migration-owned indexes updates normally. A table with migration-owned indexes
|
|
22
|
+
fails that update: recreate the table or declare its indexes in CDK.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.86
|
|
3
|
+
date: 2026-09-13
|
|
4
|
+
summary: CDK owns DynamoDB indexes; external secrets and SSOSync secret props keep credentials out of templates
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- **`JaypieMigration`** grants `DescribeTable`, `DescribeTimeToLive`, and
|
|
10
|
+
`DescribeContinuousBackups` only. `UpdateTable`, `UpdateTimeToLive`, and
|
|
11
|
+
`UpdateContinuousBackups` are removed: a GSI a migration creates blocks every
|
|
12
|
+
later CloudFormation update to the table (#552).
|
|
13
|
+
- **`JaypieMigration`** warns at synth when a `JaypieDynamoDb` in `tables`
|
|
14
|
+
declares no `indexes`. Acknowledge
|
|
15
|
+
`@jaypie/constructs:migrationTableWithoutIndexes` for tables that need none.
|
|
16
|
+
- **`JaypieDynamoDb`** sorts `indexes` by name, so
|
|
17
|
+
`indexes: getAllRegisteredIndexes()` synthesizes the same template regardless
|
|
18
|
+
of import order, and exposes the sorted list as `indexes`.
|
|
19
|
+
- **`constructTagger`** and **`JaypieInfrastructureStack`** apply per-build tags
|
|
20
|
+
to DynamoDB tables again, reverting 1.2.85.
|
|
21
|
+
- **`JaypieSecret`** and **`JaypieEnvSecret`** accept `external: true`, which
|
|
22
|
+
creates an empty secret whose value never enters the template, assets
|
|
23
|
+
bucket, `cdk.out`, or `cdk diff`. An `ExternalArn` output described by the
|
|
24
|
+
`envKey` locates the secret for CI `put-secret-value` (#551).
|
|
25
|
+
- **`JaypieSsoSyncApplication`** accepts `googleCredentialsSecret` and
|
|
26
|
+
`scimEndpointAccessTokenSecret` and deploys SSOSync as "App only" with six
|
|
27
|
+
secret ARNs in `CrossStackConfig`. Literal credentials still work and warn
|
|
28
|
+
at synth (`@jaypie/constructs:ssoSyncLiteralCredentials`).
|
|
29
|
+
|
|
30
|
+
## Upgrade
|
|
31
|
+
|
|
32
|
+
- Declare every registered index in `JaypieDynamoDb` `indexes`.
|
|
33
|
+
- A table with GSIs created outside CDK fails the first deploy on this version,
|
|
34
|
+
because build tags update the table. CloudFormation cannot adopt those
|
|
35
|
+
indexes: declare them and recreate the table. See `skill("dynamodb")`.
|
|
36
|
+
- Migrations that call `UpdateTable`, `UpdateTimeToLive`, or
|
|
37
|
+
`UpdateContinuousBackups` fail with `AccessDenied`. Move those settings into
|
|
38
|
+
`JaypieDynamoDb`.
|
|
39
|
+
- Add indexes to an existing table one per deploy.
|
|
40
|
+
- Moving `JaypieSsoSyncApplication` to secret props deletes the SAR-created
|
|
41
|
+
`SSOSync*` secrets. Sync fails until CI writes the new secret values. See
|
|
42
|
+
`skill("secrets")`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.8.157
|
|
3
|
+
date: 2026-09-13
|
|
4
|
+
summary: Document that tables with migration-owned indexes need stable CloudFormation properties
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- **`dynamodb`** adds "Keep Table Properties Stable": any CloudFormation update
|
|
10
|
+
to a table fails once a migration creates a GSI.
|
|
11
|
+
- **`migrations`** notes migration-owned index behavior and recovery for stacks
|
|
12
|
+
deployed before `@jaypie/constructs` 1.2.85.
|
|
13
|
+
- **`cdk`** notes that per-build tags skip DynamoDB tables (#548).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.8.158
|
|
3
|
+
date: 2026-09-13
|
|
4
|
+
summary: Indexes belong in CDK; external secrets keep credentials out of templates
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- **`dynamodb`** replaces "Keep Table Properties Stable" with "Share Indexes
|
|
10
|
+
Between CDK and Runtime" (`indexes: getAllRegisteredIndexes()`) and "Indexes
|
|
11
|
+
Created Outside CDK" (failure and recovery). Local Development creates the
|
|
12
|
+
table with `createTable()` from the registry and runs the migration seed,
|
|
13
|
+
replacing the AWS CLI script that created no GSIs (#552).
|
|
14
|
+
- **`migrations`** documents describe-only grants, the synth warning for tables
|
|
15
|
+
without indexes, and a seed module shared by the migration and local scripts.
|
|
16
|
+
- **`cdk`** removes the note that per-build tags skip DynamoDB tables.
|
|
17
|
+
- **`secrets`** adds External Secrets (`external: true` with a CI
|
|
18
|
+
`put-secret-value` step) and SSOSync Credentials, and notes that env-sourced
|
|
19
|
+
values are written into the template (#551).
|
package/skills/cdk.md
CHANGED
|
@@ -131,7 +131,7 @@ workspaces/
|
|
|
131
131
|
`cdk-{PROJECT_SPONSOR}-{PROJECT_KEY}-{PROJECT_ENV}-{PROJECT_NONCE}[-{key}]`,
|
|
132
132
|
so naming stays consistent across sandbox, personal, and production deploys.
|
|
133
133
|
2. **Account & region** resolved from `CDK_DEFAULT_ACCOUNT` / `CDK_DEFAULT_REGION` (overridable via `env`).
|
|
134
|
-
3. **Standard tags** applied to the stack and propagated to every taggable child resource: `env`, `project`, `sponsor`, `nonce`, `commit`, `buildHex`, `buildDate`, `buildTime`, `version`, `service`, `creation`, `role`, `stack`.
|
|
134
|
+
3. **Standard tags** applied to the stack and propagated to every taggable child resource: `env`, `project`, `sponsor`, `nonce`, `commit`, `buildHex`, `buildDate`, `buildTime`, `version`, `service`, `creation`, `role`, `stack`. Per-build tags update every table on every deploy, so a table must declare its indexes in CDK (see `skill("dynamodb")`).
|
|
135
135
|
|
|
136
136
|
```typescript
|
|
137
137
|
import { Construct } from "constructs";
|
|
@@ -235,7 +235,7 @@ const handler = new JaypieLambda(this, "ApiHandler", {
|
|
|
235
235
|
| 1 table | `grantReadWriteData()` plus `Query`/`Scan` on `index/*` | `DYNAMODB_TABLE_NAME` set automatically |
|
|
236
236
|
| 2+ tables | `grantReadWriteData()` plus `Query`/`Scan` on `index/*` for each | No auto env var — set `CDK_ENV_TABLE` manually |
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
The explicit `index/*` grant also covers indexes on imported tables, which CDK does not know about.
|
|
239
239
|
|
|
240
240
|
Single table example — at runtime, use `process.env.DYNAMODB_TABLE_NAME`:
|
|
241
241
|
|
package/skills/dynamodb.md
CHANGED
|
@@ -270,9 +270,9 @@ const { items: chats } = await queryByScope({ model: "chat", scope: APEX });
|
|
|
270
270
|
|
|
271
271
|
GSIs are defined using `fabricIndex()` from `@jaypie/fabric`. **Do not create all GSIs upfront** — start with zero and add only what your access patterns require. The most common first GSI is `indexModel` for listing entities by model.
|
|
272
272
|
|
|
273
|
-
**
|
|
273
|
+
**Indexes belong in CDK.** Declare every registered `fabricIndex()` in `JaypieDynamoDb` `indexes` (see [Share Indexes Between CDK and Runtime](#share-indexes-between-cdk-and-runtime)). A new table is created with all declared GSIs in one deploy. DynamoDB adds only **one GSI per update** to an existing table, so add indexes to a deployed table one per deploy.
|
|
274
274
|
|
|
275
|
-
**Grants:**
|
|
275
|
+
**Grants:** `JaypieLambda` and `JaypieMigration` grant `Query` and `Scan` on `${tableArn}/index/*` for every table in `tables`, which also covers indexes on imported tables. Hand-rolled roles must add it.
|
|
276
276
|
|
|
277
277
|
All GSIs use a composite sort key of `scope#updatedAt` (stored as `{indexName}Sk`). Queries use `begins_with` on the sk to filter by scope; omitting scope lists across all scopes.
|
|
278
278
|
|
|
@@ -474,17 +474,75 @@ const table = new JaypieDynamoDb(this, "myApp", {
|
|
|
474
474
|
|
|
475
475
|
Wire tables to Lambda using the `tables` prop — see `skill("cdk")` for details.
|
|
476
476
|
|
|
477
|
+
### Share Indexes Between CDK and Runtime
|
|
478
|
+
|
|
479
|
+
The model registry is the single source of indexes. Register models in a module that both the CDK workspace and the runtime import, then pass the registry to the construct:
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
// packages/models/src/index.ts
|
|
483
|
+
import { fabricIndex, registerModel } from "@jaypie/fabric";
|
|
484
|
+
|
|
485
|
+
registerModel({ model: "record", indexes: [fabricIndex(), fabricIndex("alias")] });
|
|
486
|
+
registerModel({ model: "session", indexes: [fabricIndex()], ttl: "30 days" });
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
// workspaces/cdk/lib/data-stack.ts
|
|
491
|
+
import "@project/models"; // registers models
|
|
492
|
+
import { JaypieDynamoDb } from "@jaypie/constructs";
|
|
493
|
+
import { getAllRegisteredIndexes } from "@jaypie/fabric";
|
|
494
|
+
|
|
495
|
+
const table = new JaypieDynamoDb(this, "myApp", {
|
|
496
|
+
indexes: getAllRegisteredIndexes(),
|
|
497
|
+
});
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
`JaypieDynamoDb` sorts indexes by name, so import order does not change the template. The registry is module state: the CDK workspace and the models module must resolve the same `@jaypie/fabric` copy, or `getAllRegisteredIndexes()` returns an empty list.
|
|
501
|
+
|
|
502
|
+
### Indexes Created Outside CDK
|
|
503
|
+
|
|
504
|
+
A GSI created through `UpdateTable` (a migration, the console, or the CLI) blocks every later CloudFormation update to the table:
|
|
505
|
+
|
|
506
|
+
```
|
|
507
|
+
Invalid AttributeDefinitions Expected the following attributes to be present: [indexModel, ...]
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
CloudFormation sends only the attributes the template declares, and DynamoDB rejects a request that omits attributes an existing index references. Tag, TTL, point-in-time recovery, and billing changes all fail. `JaypieMigration` grants no `UpdateTable` for this reason.
|
|
511
|
+
|
|
512
|
+
CloudFormation cannot adopt an existing GSI. Recover by declaring the indexes in `JaypieDynamoDb` and recreating the table. Outside production, delete and redeploy the stack. In production, deploy a new CDK-declared table beside the old one, copy items with `scanTable` and `updateEntity` (see [Migration: v0.4.x to v0.5.0](#migration-v04x-to-v050)), and switch `tables` to the new table.
|
|
513
|
+
|
|
477
514
|
## Local Development
|
|
478
515
|
|
|
479
516
|
Use docker-compose for local DynamoDB. The `@jaypie/dynamodb` MCP tool can generate a `docker-compose.yml` with custom ports.
|
|
480
517
|
|
|
518
|
+
`createTable()` builds the table with every registered GSI, the same indexes CDK declares. Import the models module, create the table, then run the seed the deployed migration runs (see `skill("migrations")`):
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
// scripts/dynamo-create-table.ts
|
|
522
|
+
import "@project/models"; // registers models
|
|
523
|
+
import { createTable, initClient } from "@jaypie/dynamodb";
|
|
524
|
+
|
|
525
|
+
import { seed } from "../packages/api/src/migrations/seed/seed.js";
|
|
526
|
+
|
|
527
|
+
initClient({
|
|
528
|
+
credentials: { accessKeyId: "local", secretAccessKey: "local" },
|
|
529
|
+
endpoint: "http://127.0.0.1:9060",
|
|
530
|
+
tableName: "jaypie-local",
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
await createTable();
|
|
534
|
+
await seed();
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
`createTable()` leaves an existing table unchanged and adds no indexes to it. After registering a new index, run `npm run dynamo:remove && npm run dynamo:init` to rebuild the local table.
|
|
538
|
+
|
|
481
539
|
### Suggested package.json Scripts
|
|
482
540
|
|
|
483
541
|
```json
|
|
484
542
|
{
|
|
485
543
|
"scripts": {
|
|
486
544
|
"dynamo:init": "docker compose up -d && npm run dynamo:create-table",
|
|
487
|
-
"dynamo:create-table": "
|
|
545
|
+
"dynamo:create-table": "tsx scripts/dynamo-create-table.ts",
|
|
488
546
|
"dynamo:remove": "docker compose down -v",
|
|
489
547
|
"dynamo:start": "docker compose up -d",
|
|
490
548
|
"dynamo:stop": "docker compose down"
|
package/skills/migrations.md
CHANGED
|
@@ -47,25 +47,38 @@ new JaypieMigration(this, "SeedData", {
|
|
|
47
47
|
- **Role**: Tagged as `CDK.ROLE.PROCESSING`
|
|
48
48
|
- **Execution**: Uses `cr.Provider` with both `onEventHandler` and `isCompleteHandler` pointing to the same Lambda. The `onEventHandler` returns `PhysicalResourceId` immediately; the migration code runs in `isCompleteHandler` invocations, which are polled by Step Functions until `IsComplete: true`. `Delete` requests skip the migration entirely.
|
|
49
49
|
- **Dependencies**: Use `dependencies` to ensure tables and other resources exist before the migration executes
|
|
50
|
-
- **Permissions**: Tables passed via `tables` get data-plane (`grantReadWriteData`), `Query` and `Scan` on `${tableArn}/index/*`, plus
|
|
50
|
+
- **Permissions**: Tables passed via `tables` get data-plane (`grantReadWriteData`), `Query` and `Scan` on `${tableArn}/index/*`, plus `DescribeTable`, `DescribeTimeToLive`, and `DescribeContinuousBackups` scoped to the table ARN and its indexes. Migrations read and write data. They do not change table shape
|
|
51
|
+
- **Indexes**: CDK owns indexes, TTL, and backups. Declare every registered `fabricIndex()` in `JaypieDynamoDb` `indexes` (see `skill("dynamodb")`). A GSI created outside CDK blocks every later CloudFormation update to the table, so `JaypieMigration` grants no `UpdateTable`. Synth warns (`@jaypie/constructs:migrationTableWithoutIndexes`) when a `JaypieDynamoDb` in `tables` declares no indexes; acknowledge it for tables that need none
|
|
51
52
|
|
|
52
53
|
## Migration Lambda Handler
|
|
53
54
|
|
|
54
55
|
Use `migrationHandler` from `jaypie` so errors propagate as CFN failures and the waiter protocol is handled automatically.
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
// src/migrations/seed/index.ts
|
|
58
|
-
import { initClient, seedEntities, APEX } from "@jaypie/dynamodb";
|
|
59
|
-
import { migrationHandler } from "jaypie";
|
|
57
|
+
Keep the seed in its own module so the local table script runs the same seed (see Local Development in `skill("dynamodb")`):
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
```typescript
|
|
60
|
+
// src/migrations/seed/seed.ts
|
|
61
|
+
import { APEX, seedEntities } from "@jaypie/dynamodb";
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
export async function seed() {
|
|
64
|
+
return seedEntities([
|
|
65
65
|
{ alias: "config-main", model: "config", name: "Main Config", scope: APEX },
|
|
66
66
|
{ alias: "vocab-en", model: "vocabulary", name: "English", scope: APEX },
|
|
67
67
|
]);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
68
70
|
|
|
71
|
+
```typescript
|
|
72
|
+
// src/migrations/seed/index.ts
|
|
73
|
+
import "@project/models"; // registers models; indexEntity requires them
|
|
74
|
+
import { initClient } from "@jaypie/dynamodb";
|
|
75
|
+
import { migrationHandler } from "jaypie";
|
|
76
|
+
|
|
77
|
+
import { seed } from "./seed.js";
|
|
78
|
+
|
|
79
|
+
export const handler = migrationHandler(async () => {
|
|
80
|
+
await initClient();
|
|
81
|
+
await seed();
|
|
69
82
|
return { status: "complete" };
|
|
70
83
|
});
|
|
71
84
|
```
|
package/skills/secrets.md
CHANGED
|
@@ -71,7 +71,7 @@ Synth fails fast whenever a declared secret source produces no secret string, so
|
|
|
71
71
|
```typescript
|
|
72
72
|
new JaypieSecret(this, "ApiKey", { value: process.env.MISSING }); // throws ConfigurationError
|
|
73
73
|
new JaypieSecret(this, "ApiKey", { envKey: "MISSING" }); // throws ConfigurationError
|
|
74
|
-
new JaypieSecret(this, "Placeholder"); // allowed:
|
|
74
|
+
new JaypieSecret(this, "Placeholder"); // allowed: CDK generates a random value
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
`JaypieEnvSecret` applies the same guard, except in consumer environments, where the secret is imported rather than created.
|
|
@@ -91,6 +91,8 @@ jobs:
|
|
|
91
91
|
- run: npx cdk deploy
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
An env-sourced value is written into the synthesized template. Copies persist in the deployed stack template, the CDK assets bucket, `cdk.out`, and `cdk diff` output. Use [External Secrets](#external-secrets) for credentials that must stay out of those places.
|
|
95
|
+
|
|
94
96
|
## Runtime: Retrieving Secrets
|
|
95
97
|
|
|
96
98
|
Use `getEnvSecret` to fetch secrets in Lambda:
|
|
@@ -202,6 +204,66 @@ new JaypieEnvSecret(this, "AdminSeed", {
|
|
|
202
204
|
|
|
203
205
|
With `excludePunctuation: true` and `includeSpace: false`, the generated value contains only base62 characters.
|
|
204
206
|
|
|
207
|
+
## External Secrets
|
|
208
|
+
|
|
209
|
+
`external: true` creates an empty secret (no `SecretString` or `GenerateSecretString`), so the value never enters the template, the assets bucket, `cdk.out`, or `cdk diff`. CI sets the value after deploy. `envKey` still names the runtime variable (`SECRET_ANTHROPIC_API_KEY`) but is never read at synth. Combining `external` with `value` or `generateSecretString` throws `ConfigurationError`.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
const anthropicSecret = new JaypieSecret(this, "ANTHROPIC_API_KEY", {
|
|
213
|
+
external: true,
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
new JaypieLambda(this, "Handler", {
|
|
217
|
+
code: "dist/lambda",
|
|
218
|
+
handler: "index.handler",
|
|
219
|
+
secrets: [anthropicSecret],
|
|
220
|
+
});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
The construct outputs the secret ARN with the `envKey` (or construct id) as the output description. Set the value in a step after `cdk deploy`, and keep the value out of the deploy step's environment:
|
|
224
|
+
|
|
225
|
+
```yaml
|
|
226
|
+
- name: Set external secrets
|
|
227
|
+
env:
|
|
228
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
229
|
+
STACK_NAME: my-stack
|
|
230
|
+
run: |
|
|
231
|
+
ARN=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" \
|
|
232
|
+
--query "Stacks[0].Outputs[?Description=='ANTHROPIC_API_KEY'].OutputValue" \
|
|
233
|
+
--output text)
|
|
234
|
+
printf '%s' "$ANTHROPIC_API_KEY" > "$RUNNER_TEMP/secret"
|
|
235
|
+
aws secretsmanager put-secret-value --secret-id "$ARN" \
|
|
236
|
+
--secret-string "file://$RUNNER_TEMP/secret" > /dev/null
|
|
237
|
+
rm -f "$RUNNER_TEMP/secret"
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
- A new external secret has no value until the step runs; `getEnvSecret` fails until then.
|
|
241
|
+
- CloudFormation never writes the value, so a hand-rotated secret is not overwritten by a later deploy.
|
|
242
|
+
- Switching an existing secret to `external` removes `SecretString` from the template. Run the value step in the same workflow.
|
|
243
|
+
- Each `put-secret-value` creates a secret version. Compare with `get-secret-value` first to skip unchanged writes.
|
|
244
|
+
- In `JaypieEnvSecret` consumer environments the secret is imported; set the value on the provider stack.
|
|
245
|
+
|
|
246
|
+
### SSOSync Credentials
|
|
247
|
+
|
|
248
|
+
`JaypieSsoSyncApplication` writes `googleCredentials` and `scimEndpointAccessToken` into the template and warns at synth (`@jaypie/constructs:ssoSyncLiteralCredentials`). Pass secrets instead:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
new JaypieSsoSyncApplication(this, "SsoSync", {
|
|
252
|
+
googleCredentialsSecret: new JaypieSecret(this, "SsoSyncGoogleCredentials", {
|
|
253
|
+
external: true,
|
|
254
|
+
}),
|
|
255
|
+
scimEndpointAccessTokenSecret: new JaypieSecret(this, "SsoSyncScimToken", {
|
|
256
|
+
external: true,
|
|
257
|
+
}),
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
- The application deploys SSOSync as "App only". The construct creates secrets for the admin email, SCIM endpoint URL, region, and identity store ID (still read from `CDK_ENV_SSOSYNC_*`), then passes all six ARNs in `CrossStackConfig`.
|
|
262
|
+
- Both secret props are required together, and neither combines with the literal props.
|
|
263
|
+
- Secrets need a complete ARN: created in the stack or imported with `Secret.fromSecretCompleteArn`. SSOSync reads them with the AWS managed key.
|
|
264
|
+
- Switching an existing application from "App + secrets" deletes the SAR-created `SSOSync*` secrets. Sync fails until CI writes the new secret values. Do not name new secrets `SSOSync*`.
|
|
265
|
+
- SSOSync accepts secret ARNs in `us`, `us-gov`, `ap`, `ca`, `cn`, `eu`, and `sa` regions only.
|
|
266
|
+
|
|
205
267
|
## Seeds and API Keys in Workflows
|
|
206
268
|
|
|
207
269
|
Seeds are secrets used to derive deterministic values (like API keys) at runtime. The generated-secret pattern is ideal for seeds because:
|