cdk-preflight 0.0.16 → 0.0.18

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/.jsii CHANGED
@@ -9598,6 +9598,6 @@
9598
9598
  "symbolId": "src/index:PreflightOptions"
9599
9599
  }
9600
9600
  },
9601
- "version": "0.0.16",
9602
- "fingerprint": "GpWUeSfx9QvGH3XdrOYiw5m2PBOMf3kIUSSdPNH3qoM="
9601
+ "version": "0.0.18",
9602
+ "fingerprint": "0JnjNXhPvlXcXyELz7mDg8cnh/46ynlfy+aGg1HE44M="
9603
9603
  }
package/AGENTS.md CHANGED
@@ -81,6 +81,7 @@ bench/ # real-deploy verification (needs an AWS account; no
81
81
  - The standard OPA `walk` builtin is NOT available in this engine. Write explicit traversals.
82
82
  - **Proving a property absent** (measured 2026-09-02, 1.7.0-beta): `resolve()` is undefined for a missing key AND for an unresolvable value (e.g. `Ref` to a no-default parameter), so `not resolve(...)` misfires on present-but-unresolvable values. The only reliable absence proof is the preprocessed document: `props := input.resources[name].properties; is_object(props); object.get(props, "<Key>", "__pf_absent") == "__pf_absent"`. The `is_object` guard fails closed if the internal shape ever changes. This is the sanctioned exception to "don't depend on `input` internals". Reference implementations: `pf-ecs-container-memory-required`, `pf-ecs-fargate-task-cpu-memory`.
83
83
  - `flatten_list()` returns an **empty list for an absent path** — it cannot distinguish "absent" from "present and empty" (measured 2026-09-02). Use the `input.resources` idiom above when the distinction matters (`pf-ecs-container-definitions-empty`).
84
+ - **Intrinsics inside `input.resources` values are marker objects, never strings** (measured 2026-09-03, 1.7.0-beta): `Fn::GetAtt` appears as `{"__kind": "getatt:Arn", "__ref": "B"}` and `Fn::Sub` as `{"__dynamic": "Sub:..."}` at any nesting depth. A plain `is_string(v)` guard therefore safely mutes rules that judge string shapes (ARN format, prefixes) on values users wired via intrinsics — no logical-ID false positives. Reference implementations: `pf-iam-policy-resource-format`, `pf-iam-policy-action-format`.
84
85
  - **Deploy-region rules**: the enforce plugin injects a generated module defining `deploy_region` whenever the app-level region is concrete (`deployEnvironmentModule` in `src/private/enforce.ts`; the test harness injects `us-east-1` for fixtures). Rules must read it as `data.cdk_preflight.deploy_region` — the data reference is undefined when not injected, so the rule skips; a bare `deploy_region` variable would be a compile error. Consequences: region-dependent rules are silent in warn mode (`enforce: false` hands rules to the CDK built-in plugin, which we cannot inject into) and in region-agnostic apps; say so in `meta.yaml#repro.evidence`. Reference implementations: `pf-dynamodb-global-table-replica-region`, `pf-dynamodb-kinesis-stream-region`.
85
86
  - Helper rules must use a unique `_pf_<rule>_...` prefix (all rules share one package).
86
87
  3. `npx projen bundle-rules` then `npx jest test/rules.test.ts test/structure.test.ts` — the duplication guard and fixture checks run here.
package/docs/rules.md CHANGED
@@ -82,9 +82,27 @@
82
82
  | `pf-events-input-transformer-placeholders` | AWS::Events::Rule | InputTemplate placeholders must be declared in InputPathsMap | none |
83
83
  | `pf-events-pattern-empty` | AWS::Events::Rule | An empty EventPattern counts as no pattern at all | none |
84
84
  | `pf-events-pattern-scalar-value` | AWS::Events::Rule | Event pattern values must be arrays or objects, not scalars | none |
85
+ | `pf-firehose-dfcc-required-configs` | AWS::KinesisFirehose::DeliveryStream | Enabled format conversion needs input, output, and schema configs | none |
86
+ | `pf-firehose-dynamic-partitioning-buffer` | AWS::KinesisFirehose::DeliveryStream | Dynamic partitioning needs a 64 MB buffer floor | none |
87
+ | `pf-firehose-dynamic-partitioning-prefix` | AWS::KinesisFirehose::DeliveryStream | Dynamic partitioning needs partition namespaces in the prefix | none |
88
+ | `pf-firehose-kinesis-source-config` | AWS::KinesisFirehose::DeliveryStream | KinesisStreamAsSource streams need KinesisStreamSourceConfiguration | none |
89
+ | `pf-firehose-one-destination` | AWS::KinesisFirehose::DeliveryStream | A delivery stream takes exactly one destination configuration | none |
90
+ | `pf-firehose-s3-backup-config` | AWS::KinesisFirehose::DeliveryStream | Enabling S3 backup needs S3BackupConfiguration | none |
91
+ | `pf-iam-identity-policy-no-principal` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Identity policies cannot carry a Principal field | none |
85
92
  | `pf-iam-inline-policy-size` | AWS::IAM::Policy<br>AWS::IAM::RolePolicy<br>AWS::IAM::UserPolicy<br>AWS::IAM::GroupPolicy | Inline policy documents are limited per identity (role 10240 / group 5120 / user 2048 characters) | none |
93
+ | `pf-iam-instance-profile-single-role` | AWS::IAM::InstanceProfile | An instance profile holds exactly one role | none |
86
94
  | `pf-iam-managed-policy-count` | AWS::IAM::Role<br>AWS::IAM::User<br>AWS::IAM::Group | Managed policies per identity are capped (hard maximums role 25 / user 20 / group 10) | none |
87
95
  | `pf-iam-managed-policy-size` | AWS::IAM::ManagedPolicy | Managed policy documents are limited to 6144 characters (whitespace excluded) | none |
96
+ | `pf-iam-policy-action-format` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Actions must carry a service prefix | none |
97
+ | `pf-iam-policy-condition-operator` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Condition operators come from a closed grammar | none |
98
+ | `pf-iam-policy-duplicate-sid` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Statement IDs must be unique within a policy | none |
99
+ | `pf-iam-policy-effect-case` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Effect is case-sensitive Allow or Deny | none |
100
+ | `pf-iam-policy-exclusive-fields` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Action/NotAction and Resource/NotResource are exclusive pairs | none |
101
+ | `pf-iam-policy-resource-format` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Resources must be ARNs or * | none |
102
+ | `pf-iam-policy-statement-resource-required` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Identity policy statements need Resource or NotResource | none |
103
+ | `pf-iam-policy-version` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Policy Version must be 2012-10-17 or 2008-10-17 | none |
104
+ | `pf-iam-trust-policy-no-resource` | AWS::IAM::Role | Trust policies cannot carry a Resource field | none |
105
+ | `pf-iam-trust-policy-service-principal` | AWS::IAM::Role | Service principals live under amazonaws.com | none |
88
106
  | `pf-lambda-code-s3-pair` | AWS::Lambda::Function | S3-based Code needs both S3Bucket and S3Key | none |
89
107
  | `pf-lambda-code-zipfile-exclusive` | AWS::Lambda::Function | Inline ZipFile excludes every other Code parameter | none |
90
108
  | `pf-lambda-dlq-region` | AWS::Lambda::Function | The dead letter target must sit in the deploy region | none |
package/lib/index.js CHANGED
@@ -17,7 +17,7 @@ const rules_generated_1 = require("./rules.generated");
17
17
  * Preflight.apply(app);
18
18
  */
19
19
  class Preflight {
20
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "0.0.16" };
20
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "0.0.18" };
21
21
  /**
22
22
  * Register the cdk-preflight rules on an App or Stage.
23
23
  */