@jaypie/mcp 0.8.63 → 0.8.65
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.59.md +14 -0
- package/release-notes/constructs/1.2.60.md +24 -0
- package/release-notes/mcp/0.8.65.md +17 -0
- package/skills/agents.md +1 -1
- package/skills/cdk.md +8 -83
- package/skills/secrets.md +24 -1
- package/skills/skills.md +1 -1
- package/skills/waf.md +154 -0
|
@@ -9,7 +9,7 @@ import { gt } from 'semver';
|
|
|
9
9
|
/**
|
|
10
10
|
* Docs Suite - Documentation services (skill, version, release_notes)
|
|
11
11
|
*/
|
|
12
|
-
const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.
|
|
12
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.65#58028ec6"
|
|
13
13
|
;
|
|
14
14
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname$1 = path.dirname(__filename$1);
|
package/package.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.59
|
|
3
|
+
date: 2026-06-03
|
|
4
|
+
summary: Add JaypieSecret base construct and serviceTag on lambda constructs
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## @jaypie/constructs 1.2.59
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- **JaypieSecret**: New base construct — a plain AWS Secrets Manager secret without the environment-driven provider/consumer cross-stack pattern. Reads its value from `process.env[envKey]`, an explicit `value`, or `generateSecretString`, and throws `ConfigurationError` when an `envKey` resolves to nothing. Supports the same SCREAMING_SNAKE_CASE shorthand as `JaypieEnvSecret` (construct id `Secret_${envKey}`).
|
|
12
|
+
- **JaypieEnvSecret** now extends `JaypieSecret`, layering the env-aware provider/consumer behavior on top via a `buildSecret` override. Existing behavior — including issue #347 cross-stack export names — is preserved. `JaypieEnvSecret` is deprecated and will be removed in 2.0.
|
|
13
|
+
- **resolveSecrets / lambda `secrets`**: `SecretsArrayItem` widened to `JaypieSecret | string`, so any `JaypieSecret` (including `JaypieEnvSecret`) is accepted wherever secrets are passed. Strings still create env-aware `JaypieEnvSecret` instances.
|
|
14
|
+
- **serviceTag**: `JaypieLambda` (and `JaypieExpressLambda`, `JaypieWebSocketLambda` by inheritance) accepts a `serviceTag` prop that applies `CDK.TAG.SERVICE` alongside `roleTag` and `vendorTag`. `JaypieQueuedLambda` propagates it to the SQS queue and `JaypieBucketQueuedLambda` to the S3 bucket.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.60
|
|
3
|
+
date: 2026-06-04
|
|
4
|
+
summary: Validate WAF managedRuleOverrides/allow rule names at synth, throwing ConfigurationError on unknown names
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## @jaypie/constructs 1.2.60
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **WAF rule-name validation** (`JaypieDistribution`, `JaypieWebDeploymentBucket`).
|
|
12
|
+
`waf.allow` and `waf.managedRuleOverrides` rule names are now validated against
|
|
13
|
+
each AWS managed rule group at synth time. AWS WAF matches `RuleActionOverride`
|
|
14
|
+
on the exact rule **name** and silently ignores any name that matches no rule —
|
|
15
|
+
so a typo, or the label/name casing trap (label
|
|
16
|
+
`…:core-rule-set:NoUserAgent_Header` vs rule name `NoUserAgent_HEADER`), used to
|
|
17
|
+
produce a WebACL that looked correct but kept blocking. Jaypie now throws a
|
|
18
|
+
`ConfigurationError` listing the valid rule names for the group. Custom
|
|
19
|
+
(non-AWS) rule groups are not validated.
|
|
20
|
+
|
|
21
|
+
New helper `assertValidWafRuleNames` and the canonical `AWS_MANAGED_RULE_GROUPS`
|
|
22
|
+
map are exported from the package.
|
|
23
|
+
|
|
24
|
+
Issue: [#362](https://github.com/finlaysonstudio/jaypie/issues/362)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.8.65
|
|
3
|
+
date: 2026-06-04
|
|
4
|
+
summary: Extract WAF guidance into a dedicated skill("waf") with allow prop and rule-name casing trap coverage
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changed
|
|
8
|
+
|
|
9
|
+
- **New `waf` skill**. WAF guidance moved out of `skill("cdk")` into a dedicated
|
|
10
|
+
`skill("waf")`, mirroring how `dns`, `secrets`, and `streaming` are split out.
|
|
11
|
+
`skill("cdk")` keeps a one-line **See Also → `skill("waf")`** pointer.
|
|
12
|
+
- **`waf` skill** adds coverage of the `waf.allow` path-scoped relaxation prop
|
|
13
|
+
and the **rule name ≠ label casing trap** (label
|
|
14
|
+
`…:core-rule-set:NoUserAgent_Header` vs rule name `NoUserAgent_HEADER`), noting
|
|
15
|
+
that `@jaypie/constructs` now validates rule names at synth.
|
|
16
|
+
|
|
17
|
+
Issue: [#362](https://github.com/finlaysonstudio/jaypie/issues/362)
|
package/skills/agents.md
CHANGED
|
@@ -34,7 +34,7 @@ Complete stack styles, techniques, and traditions.
|
|
|
34
34
|
|
|
35
35
|
Contents: index, releasenotes
|
|
36
36
|
Development: apikey, documentation, errors, llm, logs, mocks, monorepo, repokit, style, subpackages, tests, tools
|
|
37
|
-
Infrastructure: apigateway, aws, cdk, cicd, datadog, dns, dynamodb, express, lambda, migrations, secrets, sqs, streaming, variables, web, websockets
|
|
37
|
+
Infrastructure: apigateway, aws, cdk, cicd, datadog, dns, dynamodb, express, lambda, migrations, secrets, sqs, streaming, variables, waf, web, websockets
|
|
38
38
|
Patterns: api, fabric, handlers, models, services, vocabulary
|
|
39
39
|
Recipes: recipe-api-server
|
|
40
40
|
Meta: issues, jaypie, mcp, skills
|
package/skills/cdk.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: CDK constructs and deployment patterns
|
|
3
|
-
related: apikey, aws, cicd, dynamodb, express, lambda, migrations, secrets, streaming, web, websockets
|
|
3
|
+
related: apikey, aws, cicd, dynamodb, express, lambda, migrations, secrets, streaming, waf, web, websockets
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# CDK Constructs
|
|
@@ -347,89 +347,13 @@ new JaypieDistribution(this, "Dist", {
|
|
|
347
347
|
|
|
348
348
|
## WAF (Web Application Firewall)
|
|
349
349
|
|
|
350
|
-
`JaypieDistribution`
|
|
350
|
+
`JaypieDistribution` and `JaypieWebDeploymentBucket` attach a WAFv2 WebACL by
|
|
351
|
+
default (CommonRuleSet, KnownBadInputsRuleSet, IP rate limiting, and WAF logging
|
|
352
|
+
to S3 with Datadog forwarding).
|
|
351
353
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
-
|
|
355
|
-
- **WAF logging** — S3 bucket with Datadog forwarder notifications
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
// Default: WAF enabled with logging
|
|
359
|
-
new JaypieDistribution(this, "Dist", { handler });
|
|
360
|
-
|
|
361
|
-
// Disable WAF entirely
|
|
362
|
-
new JaypieDistribution(this, "Dist", { handler, waf: false });
|
|
363
|
-
|
|
364
|
-
// Customize rate limit (name required on any waf config object)
|
|
365
|
-
new JaypieDistribution(this, "Dist", {
|
|
366
|
-
handler,
|
|
367
|
-
waf: { name: "api", rateLimitPerIp: 500 },
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
// Multiple distributions in one env — set a unique waf.name on each to
|
|
371
|
-
// avoid WebACL/S3 bucket name collisions between stacks.
|
|
372
|
-
new JaypieDistribution(this, "Api", { handler: api, waf: { name: "api" } });
|
|
373
|
-
new JaypieDistribution(this, "Mcp", { handler: mcp, waf: { name: "mcp" } });
|
|
374
|
-
|
|
375
|
-
// Use existing WebACL
|
|
376
|
-
new JaypieDistribution(this, "Dist", {
|
|
377
|
-
handler,
|
|
378
|
-
waf: { name: "api", webAclArn: "arn:aws:wafv2:..." },
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
// Disable WAF logging only
|
|
382
|
-
new JaypieDistribution(this, "Dist", {
|
|
383
|
-
handler,
|
|
384
|
-
waf: { name: "api", logBucket: false },
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// Bring your own WAF logging bucket
|
|
388
|
-
new JaypieDistribution(this, "Dist", {
|
|
389
|
-
handler,
|
|
390
|
-
waf: { name: "api", logBucket: myWafBucket },
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
// Override specific managed rule actions (e.g., allow large request bodies)
|
|
394
|
-
new JaypieDistribution(this, "Dist", {
|
|
395
|
-
handler,
|
|
396
|
-
waf: {
|
|
397
|
-
name: "api",
|
|
398
|
-
managedRuleOverrides: {
|
|
399
|
-
AWSManagedRulesCommonRuleSet: [
|
|
400
|
-
{ name: "SizeRestrictions_BODY", actionToUse: { count: {} } },
|
|
401
|
-
],
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
// Scope a managed rule group to (or away from) specific URL patterns
|
|
407
|
-
new JaypieDistribution(this, "Dist", {
|
|
408
|
-
handler,
|
|
409
|
-
waf: {
|
|
410
|
-
name: "api",
|
|
411
|
-
managedRuleScopeDowns: {
|
|
412
|
-
// Only run the CommonRuleSet for paths OTHER than /chat — lets /chat
|
|
413
|
-
// handle large AI-generated request bodies without weakening protection
|
|
414
|
-
// elsewhere.
|
|
415
|
-
AWSManagedRulesCommonRuleSet: {
|
|
416
|
-
notStatement: {
|
|
417
|
-
statement: {
|
|
418
|
-
byteMatchStatement: {
|
|
419
|
-
fieldToMatch: { uriPath: {} },
|
|
420
|
-
positionalConstraint: "STARTS_WITH",
|
|
421
|
-
searchString: "/chat",
|
|
422
|
-
textTransformations: [{ priority: 0, type: "NONE" }],
|
|
423
|
-
},
|
|
424
|
-
},
|
|
425
|
-
},
|
|
426
|
-
},
|
|
427
|
-
},
|
|
428
|
-
},
|
|
429
|
-
});
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
Cost: $5/month per WebACL + $1/month per rule + $0.60 per million requests. Use `waf: false` to opt out.
|
|
354
|
+
See **`skill("waf")`** for configuration: `rateLimitPerIp`, `webAclArn`,
|
|
355
|
+
`logBucket`, `managedRuleOverrides`, `managedRuleScopeDowns`, the `allow`
|
|
356
|
+
path-scoped relaxation prop, and the rule-name ↔ label casing trap.
|
|
433
357
|
|
|
434
358
|
## Organization Trail Security Baseline
|
|
435
359
|
|
|
@@ -465,5 +389,6 @@ new JaypieOrganizationTrail(this, "OrgTrail", {
|
|
|
465
389
|
- **`skill("secrets")`** - Secret management with JaypieEnvSecret
|
|
466
390
|
- **`skill("streaming")`** - JaypieDistribution and JaypieNextJs streaming configuration
|
|
467
391
|
- **`skill("variables")`** - Environment variables reference
|
|
392
|
+
- **`skill("waf")`** - WAF configuration, managed rule overrides, and the `allow` prop
|
|
468
393
|
- **`skill("web")`** - JaypieWebDeploymentBucket and JaypieStaticWebBucket for static sites
|
|
469
394
|
- **`skill("websockets")`** - JaypieWebSocket and JaypieWebSocketTable constructs
|
package/skills/secrets.md
CHANGED
|
@@ -5,7 +5,30 @@ related: apikey, aws, cdk, variables
|
|
|
5
5
|
|
|
6
6
|
# Secret Management
|
|
7
7
|
|
|
8
|
-
Jaypie uses AWS Secrets Manager for secure credential storage. The `JaypieEnvSecret`
|
|
8
|
+
Jaypie uses AWS Secrets Manager for secure credential storage. The `JaypieSecret` and `JaypieEnvSecret` constructs create secrets at deploy time from environment variables, and `getEnvSecret` retrieves them at runtime.
|
|
9
|
+
|
|
10
|
+
## JaypieSecret vs JaypieEnvSecret
|
|
11
|
+
|
|
12
|
+
- **`JaypieSecret`** — a plain secret. Always creates a secret in the current stack from `process.env[envKey]`, an explicit `value`, or `generateSecretString`. No cross-stack imports or exports. This is the construct to reach for.
|
|
13
|
+
- **`JaypieEnvSecret`** — extends `JaypieSecret` and adds the environment-driven provider/consumer cross-stack pattern (see [Provider/Consumer Pattern](#providerconsumer-pattern) below). **Deprecated; will be removed in 2.0.**
|
|
14
|
+
|
|
15
|
+
`JaypieEnvSecret` is a `JaypieSecret`, so it is accepted anywhere a `JaypieSecret` is — including the `secrets` array on `JaypieLambda`. Strings in that array still create env-aware `JaypieEnvSecret` instances.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { JaypieSecret } from "@jaypie/constructs";
|
|
19
|
+
|
|
20
|
+
// Reads process.env.MY_API_KEY at deploy time
|
|
21
|
+
// Throws ConfigurationError if unset and no value/generateSecretString given
|
|
22
|
+
new JaypieSecret(this, "MY_API_KEY");
|
|
23
|
+
|
|
24
|
+
// Generated secret, no env var needed
|
|
25
|
+
new JaypieSecret(this, "DbPassword", {
|
|
26
|
+
envKey: "DB_PASSWORD",
|
|
27
|
+
generateSecretString: { excludePunctuation: true, passwordLength: 32 },
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Everything below that uses `JaypieEnvSecret` works the same on `JaypieSecret`, except the provider/consumer cross-stack behavior, which is `JaypieEnvSecret`-only.
|
|
9
32
|
|
|
10
33
|
## The Pattern
|
|
11
34
|
|
package/skills/skills.md
CHANGED
|
@@ -17,7 +17,7 @@ Look up skills by alias: `mcp__jaypie__skill(alias)`
|
|
|
17
17
|
|----------|--------|
|
|
18
18
|
| contents | index, releasenotes |
|
|
19
19
|
| development | apikey, documentation, errors, llm, logs, mocks, monorepo, repokit, style, subpackages, tests, tools |
|
|
20
|
-
| infrastructure | apigateway, aws, cdk, cicd, datadog, dns, dynamodb, express, lambda, migrations, secrets, sqs, streaming, variables, web, websockets |
|
|
20
|
+
| infrastructure | apigateway, aws, cdk, cicd, datadog, dns, dynamodb, express, lambda, migrations, secrets, sqs, streaming, variables, waf, web, websockets |
|
|
21
21
|
| patterns | api, fabric, handlers, models, services, vocabulary |
|
|
22
22
|
| recipes | recipe-api-server |
|
|
23
23
|
| meta | issues, jaypie, mcp, skills |
|
package/skills/waf.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: WAF (Web Application Firewall) configuration for JaypieDistribution
|
|
3
|
+
related: aws, cdk, web
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WAF (Web Application Firewall)
|
|
7
|
+
|
|
8
|
+
`JaypieDistribution` (and `JaypieWebDeploymentBucket`) attach a WAFv2 WebACL by
|
|
9
|
+
default with:
|
|
10
|
+
|
|
11
|
+
- **AWSManagedRulesCommonRuleSet** — OWASP top 10 (SQLi, XSS, etc.)
|
|
12
|
+
- **AWSManagedRulesKnownBadInputsRuleSet** — known bad patterns (Log4j, etc.)
|
|
13
|
+
- **Rate limiting** — 2000 requests per 5 minutes per IP
|
|
14
|
+
- **WAF logging** — S3 bucket with Datadog forwarder notifications
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// Default: WAF enabled with logging
|
|
18
|
+
new JaypieDistribution(this, "Dist", { handler });
|
|
19
|
+
|
|
20
|
+
// Disable WAF entirely
|
|
21
|
+
new JaypieDistribution(this, "Dist", { handler, waf: false });
|
|
22
|
+
|
|
23
|
+
// Customize rate limit (name required on any waf config object)
|
|
24
|
+
new JaypieDistribution(this, "Dist", {
|
|
25
|
+
handler,
|
|
26
|
+
waf: { name: "api", rateLimitPerIp: 500 },
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Multiple distributions in one env — set a unique waf.name on each to
|
|
30
|
+
// avoid WebACL/S3 bucket name collisions between stacks.
|
|
31
|
+
new JaypieDistribution(this, "Api", { handler: api, waf: { name: "api" } });
|
|
32
|
+
new JaypieDistribution(this, "Mcp", { handler: mcp, waf: { name: "mcp" } });
|
|
33
|
+
|
|
34
|
+
// Use existing WebACL
|
|
35
|
+
new JaypieDistribution(this, "Dist", {
|
|
36
|
+
handler,
|
|
37
|
+
waf: { name: "api", webAclArn: "arn:aws:wafv2:..." },
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Disable WAF logging only
|
|
41
|
+
new JaypieDistribution(this, "Dist", {
|
|
42
|
+
handler,
|
|
43
|
+
waf: { name: "api", logBucket: false },
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Bring your own WAF logging bucket
|
|
47
|
+
new JaypieDistribution(this, "Dist", {
|
|
48
|
+
handler,
|
|
49
|
+
waf: { name: "api", logBucket: myWafBucket },
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Cost: $5/month per WebACL + $1/month per rule + $0.60 per million requests. Use
|
|
54
|
+
`waf: false` to opt out.
|
|
55
|
+
|
|
56
|
+
## Override specific managed rule actions
|
|
57
|
+
|
|
58
|
+
Flip a named sub-rule from `block` to `count` everywhere (e.g. allow large
|
|
59
|
+
request bodies):
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
new JaypieDistribution(this, "Dist", {
|
|
63
|
+
handler,
|
|
64
|
+
waf: {
|
|
65
|
+
name: "api",
|
|
66
|
+
managedRuleOverrides: {
|
|
67
|
+
AWSManagedRulesCommonRuleSet: [
|
|
68
|
+
{ name: "SizeRestrictions_BODY", actionToUse: { count: {} } },
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Scope a managed rule group to specific URL patterns
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
new JaypieDistribution(this, "Dist", {
|
|
79
|
+
handler,
|
|
80
|
+
waf: {
|
|
81
|
+
name: "api",
|
|
82
|
+
managedRuleScopeDowns: {
|
|
83
|
+
// Only run the CommonRuleSet for paths OTHER than /chat — lets /chat
|
|
84
|
+
// handle large AI-generated request bodies without weakening protection
|
|
85
|
+
// elsewhere.
|
|
86
|
+
AWSManagedRulesCommonRuleSet: {
|
|
87
|
+
notStatement: {
|
|
88
|
+
statement: {
|
|
89
|
+
byteMatchStatement: {
|
|
90
|
+
fieldToMatch: { uriPath: {} },
|
|
91
|
+
positionalConstraint: "STARTS_WITH",
|
|
92
|
+
searchString: "/chat",
|
|
93
|
+
textTransformations: [{ priority: 0, type: "NONE" }],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Relaxing a managed rule for specific paths — `waf.allow`
|
|
104
|
+
|
|
105
|
+
`allow` relaxes named rules to **count** mode for matching paths, leaving full
|
|
106
|
+
blocking everywhere else. Each entry names one or more paths and, per managed
|
|
107
|
+
rule group key, the sub-rule names to flip:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
new JaypieDistribution(this, "Dist", {
|
|
111
|
+
handler,
|
|
112
|
+
waf: {
|
|
113
|
+
name: "api",
|
|
114
|
+
allow: [
|
|
115
|
+
{
|
|
116
|
+
path: "/hooks/*", // trailing * → STARTS_WITH; otherwise EXACTLY
|
|
117
|
+
AWSManagedRulesCommonRuleSet: ["NoUserAgent_HEADER"],
|
|
118
|
+
AWSManagedRulesKnownBadInputsRuleSet: ["ExploitablePaths_URIPATH"],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- A `path` ending in `*` compiles to a `STARTS_WITH` byte-match; otherwise
|
|
126
|
+
`EXACTLY`. `/hooks/*` matches `/hooks/ping` but **not** bare `/hooks`.
|
|
127
|
+
- The key (e.g. `AWSManagedRulesCommonRuleSet`) must be one of the active
|
|
128
|
+
`managedRules`.
|
|
129
|
+
- `allow` composes with `managedRuleOverrides`: the baseline overrides apply to
|
|
130
|
+
both the relaxed and strict emissions of a group; entries in `allow` further
|
|
131
|
+
relax specific (path × sub-rule) intersections. Groups not named in `allow`
|
|
132
|
+
keep their single-rule emission.
|
|
133
|
+
|
|
134
|
+
## ⚠️ Rule name ≠ label (casing trap)
|
|
135
|
+
|
|
136
|
+
AWS uses different casing for a rule's **label** (seen in WAF logs) and its
|
|
137
|
+
**name**. `managedRuleOverrides` / `allow` match on the **rule name**:
|
|
138
|
+
|
|
139
|
+
| Label (seen in WAF logs) | Rule name (use this) |
|
|
140
|
+
| ----------------------------------------------------- | -------------------- |
|
|
141
|
+
| `awswaf:managed:aws:core-rule-set:NoUserAgent_Header` | `NoUserAgent_HEADER` |
|
|
142
|
+
|
|
143
|
+
Jaypie now validates rule names against each AWS managed rule group at synth and
|
|
144
|
+
throws a `ConfigurationError` listing the valid names on a mismatch (custom rule
|
|
145
|
+
groups are not validated). Historically a name that matched no rule was
|
|
146
|
+
**silently ignored** — the rule kept blocking. If a relaxation "isn't working,"
|
|
147
|
+
read the WAF log `terminatingRule.<NAME>` and copy that exact name (e.g.
|
|
148
|
+
`NoUserAgent_HEADER`, `SizeRestrictions_BODY`, `UserAgent_BadBots_HEADER`).
|
|
149
|
+
|
|
150
|
+
## See Also
|
|
151
|
+
|
|
152
|
+
- **`skill("cdk")`** - CDK constructs and deployment patterns
|
|
153
|
+
- **`skill("aws")`** - AWS SDK utilities
|
|
154
|
+
- **`skill("web")`** - JaypieWebDeploymentBucket and JaypieStaticWebBucket
|