Skip to content

build(deps-dev)!: migrate to cdk-nag 3.0.1 (policy-validation plugin engine)#99

Merged
timpugh merged 1 commit into
mainfrom
chore/cdk-nag-3-migration
Jul 3, 2026
Merged

build(deps-dev)!: migrate to cdk-nag 3.0.1 (policy-validation plugin engine)#99
timpugh merged 1 commit into
mainfrom
chore/cdk-nag-3-migration

Conversation

@timpugh

@timpugh timpugh commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Supersedes #94 — the bare Dependabot bump cannot compile: cdk-nag v3 rewrites the packs from per-stack IAspects onto CDK's policy validation framework, removes NagSuppressions, and changes granular-finding matching. This PR does the full migration.

What changed

  • Pack attachment: five packs are policy-validation plugins registered once at the App root (attach_nag_packs, called from app.py and every nag-gating test fixture). apply_compliance_aspects stays per stack with TemplateConventionChecks plus cdk-nag's WriteNagSuppressionsToCloudFormationAspect — per stack because Aspects don't cross cdk.Stage boundaries (verified live; App-level registration silently dropped the cdk_nag template metadata for every nested stack).
  • Suppressions → acknowledgments: acknowledge_rules in nag_utils.py adapts the repo's unchanged {id, reason, applies_to} data shape onto Validations.of().acknowledge(). All 23 call sites converted with their data intact; previously-blanket granular wildcards (singleton IAM4/IAM5, BucketDeployment s3 grants, RUM cleanup ARN, CodeDeploy/APIGW roles) are now enumerated with exact Rule[Finding] ids, since v3 matches granular findings individually.
  • Gate integrity (the important part): CDK signals validation failure via process.exitCode in the Node process — jsii's throwaway kernel for a Python app — so neither app.synth() nor cdk synth fails natively (live-verified with a non-compliant canary). The hard gate is now explicit on both paths:
    • scripts/check_validation_report.py after synth in make cdk-synth + CI cdk-check (fails on violations and on a missing report);
    • TestNagCompliance parses each deployment shape's validation-report.json in-process, with test_nag_gate_can_fail as the non-vacuousness canary.

Upstream sharp edges worked around (documented in place)

  1. CDK's acknowledge API rejects ids containing more than one ::, yet the packs emit exactly such ids for IAM4 managed-policy findings → acknowledge_rules routes those through the aws:cdk:acknowledged-rules metadata fallback the plugin demonstrably honors.
  2. Raw IAM5 resource finding ids reproduce whichever partition rendering the synth used (arn:aws: under cdk.json's enablePartitionLiterals, arn:<AWS::Partition>: in flag-less test synth) → both forms acknowledged where ARNs embed partitions. The new CLI checker caught this split during the migration itself.

Verification

  • make pr fully green: lockfile drift check, all pre-commit hooks, mypy both venvs, markdownlint, unit tests (100% lambda/ gate), 146 CDK assertions (all four deployment shapes nag-clean + canary), Docker CLI synth + cdk-nag validation clean from the report checker, OpenAPI drift.
  • Snapshots regenerated; the metadata diff is the v3 write-aspect recording acknowledgments subtree-wide (reviewed).
  • Docs updated: CLAUDE.md nag sections rewritten for v3; nine README passages.

🤖 Generated with Claude Code

…engine)

cdk-nag v3 rewrites the rule packs from per-stack IAspects onto CDK's
native policy validation framework, which changes how packs attach, how
suppressions work, and — critically — how failure is signaled. This
migration covers all of it; supersedes #94, whose bare version bump
cannot compile against the v3 API.

Engine: the five packs are now plugins registered once at the App root
(attach_nag_packs, called from app.py and every nag-gating test
fixture). apply_compliance_aspects stays per stack carrying the
project's TemplateConventionChecks Aspect plus cdk-nag's
WriteNagSuppressionsToCloudFormationAspect — per stack because Aspects
do not cross cdk.Stage boundaries (verified live: an App-level
registration silently skipped every Stage-nested stack), which is what
keeps the v2-style cdk_nag Metadata audit trail in the templates and
snapshots.

Suppressions: NagSuppressions is gone; acknowledge_rules in nag_utils
adapts this repo's unchanged {id, reason, applies_to} data shape onto
Validations.of().acknowledge(). v3 matches granular IAM4/IAM5 findings
individually — a bare rule id matches nothing — so every previously
blanket wildcard is now enumerated with its exact finding id (singleton
IAM4 managed policies, the BucketDeployment handler's seven s3 grants,
the RUM cleanup log-group ARN, CodeDeploy and API Gateway CloudWatch
roles). Two upstream sharp edges are worked around and documented in
place: CDK's acknowledge API rejects ids with more than one '::' while
the packs emit exactly such ids for IAM4 (metadata fallback in
acknowledge_rules), and raw IAM5 resource finding ids reproduce
whichever partition rendering the synth used (both arn:aws: and
arn:<AWS::Partition>: forms acknowledged where ARNs embed partitions).

Gate integrity: CDK signals validation failure by setting
process.exitCode in the NODE process — jsii's throwaway kernel for a
Python app — so neither app.synth() nor cdk synth fails natively
(verified live: a non-compliant canary synthesized 'successfully' via
the CLI). The hard gate is now explicit on both paths:
scripts/check_validation_report.py (fails on violations AND on a
missing report) runs after synth in make cdk-synth and the CI cdk-check
job, and TestNagCompliance parses each shape's validation-report.json
in-process, with test_nag_gate_can_fail as the non-vacuousness canary.
That CLI checker caught the partition-rendering split during this very
migration.

The RUM cleanup grant ARN switched from a token-embedding monitor-id
prefix to a monitor-name suffix wildcard: the delete call still targets
the exact log group, and the literal ARN is what makes the finding id
reproducible enough to acknowledge.

Docs updated (CLAUDE.md nag sections, nine README passages); snapshots
regenerated — the metadata diff is the v3 write-aspect recording
acknowledgments subtree-wide.
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

🏗️ CDK infra diff — PR vs main

ServerlessApp-us-east-1-stage/ServerlessAppAudit-us-east-1
Stack ServerlessApp-us-east-1-stage/ServerlessAppAudit-us-east-1 (ServerlessAppAudit-us-east-1)
Resources
[~] AWS::S3::Bucket ServerlessAppAudit-us-east-1/CloudTrailLogsBucket CloudTrailLogsBucketF4E95F70
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,67 +1,54 @@
                [ ] [
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "AwsSolutions-S1",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "NIST.800.53.R5-S3BucketLoggingEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "HIPAA.Security-S3BucketLoggingEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "PCI.DSS.321-S3BucketLoggingEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "NIST.800.53.R5-S3DefaultEncryptionKMS",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "HIPAA.Security-S3DefaultEncryptionKMS",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "PCI.DSS.321-S3DefaultEncryptionKMS",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "NIST.800.53.R5-S3BucketVersioningEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "HIPAA.Security-S3BucketVersioningEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "PCI.DSS.321-S3BucketVersioningEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "NIST.800.53.R5-S3BucketReplicationEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "HIPAA.Security-S3BucketReplicationEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q2xvdWRUcmFpbCBsb2cgYnVja2V0IOKAlCBTU0UtUzMgKENsb3VkVHJhaWwgZGVsaXZlcnkgZG9lc24ndCBzdXBwb3J0IEtNUy1DTUsgZGVzdGluYXRpb24gYnVja2V0czsgdHJhaWwgbG9nIGZpbGVzIGFyZSBwZXItb2JqZWN0IFNTRS1LTVMpLCBzZWxmLWxvZ2dpbmcgd291bGQgY3JlYXRlIGNpcmN1bGFyIGF1ZGl0IHRyYWlscywgbm8gdmVyc2lvbmluZy9yZXBsaWNhdGlvbiBmb3IgYW4gYXBwZW5kLW9ubHksIGludGVncml0eS12YWxpZGF0ZWQgbG9nIHNpbms=",
                [ ]     "id": "PCI.DSS.321-S3BucketReplicationEnabled",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CloudTrail log bucket — SSE-S3 (CloudTrail delivery doesn't support KMS-CMK destination buckets; trail log files are per-object SSE-KMS), self-logging would create circular audit trails, no versioning/replication for an append-only, integrity-validated log sink"
                [ ]   }
                [ ] ]
[~] AWS::S3::BucketPolicy ServerlessAppAudit-us-east-1/CloudTrailLogsBucket/Policy CloudTrailLogsBucketPolicyF40858DB
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] Custom::S3AutoDeleteObjects ServerlessAppAudit-us-east-1/CloudTrailLogsBucket/AutoDeleteObjectsCustomResource CloudTrailLogsBucketAutoDeleteObjectsCustomResource00A8BB98
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::IAM::Role ServerlessAppAudit-us-east-1/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,80 +1,66 @@
                [ ] [
                [ ]   {
                [-]     "reason": "CDK-managed singleton Lambda uses AWS managed execution role",
                [-]     "id": "AwsSolutions-IAM4"
                [+]     "id": "AwsSolutions-L1",
                [+]     "reason": "CDK-managed singleton Lambda runtime is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-managed singleton Lambda uses wildcard in auto-generated policy",
                [-]     "id": "AwsSolutions-IAM5"
                [-]   },
                [-]   {
                [-]     "reason": "CDK-managed singleton Lambda runtime is not configurable",
                [-]     "id": "AwsSolutions-L1"
                [-]   },
                [-]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgdHJhY2luZyBpcyBub3QgY29uZmlndXJhYmxl",
                [ ]     "id": "Serverless-LambdaTracing",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — tracing is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgRExRIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "Serverless-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — DLQ is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgbWVtb3J5IGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "Serverless-LambdaDefaultMemorySize",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — memory is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-managed singleton Lambda runtime is not configurable",
                [-]     "id": "Serverless-LambdaLatestVersion"
                [+]     "id": "Serverless-LambdaLatestVersion",
                [+]     "reason": "CDK-managed singleton Lambda runtime is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-generated inline policy on singleton service role",
                [-]     "id": "NIST.800.53.R5-IAMNoInlinePolicy"
                [+]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [+]     "reason": "CDK-generated inline policy on singleton service role"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgRExRIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "NIST.800.53.R5-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — DLQ is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgY29uY3VycmVuY3kgaXMgbm90IGNvbmZpZ3VyYWJsZQ==",
                [ ]     "id": "NIST.800.53.R5-LambdaConcurrency",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — concurrency is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgVlBDIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "NIST.800.53.R5-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — VPC is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-generated inline policy on singleton service role",
                [-]     "id": "HIPAA.Security-IAMNoInlinePolicy"
                [+]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [+]     "reason": "CDK-generated inline policy on singleton service role"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgRExRIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "HIPAA.Security-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — DLQ is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgY29uY3VycmVuY3kgaXMgbm90IGNvbmZpZ3VyYWJsZQ==",
                [ ]     "id": "HIPAA.Security-LambdaConcurrency",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — concurrency is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgVlBDIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "HIPAA.Security-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — VPC is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-generated inline policy on singleton service role",
                [-]     "id": "PCI.DSS.321-IAMNoInlinePolicy"
                [+]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [+]     "reason": "CDK-generated inline policy on singleton service role"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgVlBDIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "PCI.DSS.321-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — VPC is not configurable"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]",
                [+]     "reason": "CDK-managed singleton Lambda uses AWS managed execution role"
                [ ]   }
                [ ] ]
[~] AWS::Lambda::Function ServerlessAppAudit-us-east-1/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,80 +1,66 @@
                [ ] [
                [ ]   {
                [-]     "reason": "CDK-managed singleton Lambda uses AWS managed execution role",
                [-]     "id": "AwsSolutions-IAM4"
                [+]     "id": "AwsSolutions-L1",
                [+]     "reason": "CDK-managed singleton Lambda runtime is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-managed singleton Lambda uses wildcard in auto-generated policy",
                [-]     "id": "AwsSolutions-IAM5"
                [-]   },
                [-]   {
                [-]     "reason": "CDK-managed singleton Lambda runtime is not configurable",
                [-]     "id": "AwsSolutions-L1"
                [-]   },
                [-]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgdHJhY2luZyBpcyBub3QgY29uZmlndXJhYmxl",
                [ ]     "id": "Serverless-LambdaTracing",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — tracing is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgRExRIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "Serverless-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — DLQ is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgbWVtb3J5IGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "Serverless-LambdaDefaultMemorySize",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — memory is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-managed singleton Lambda runtime is not configurable",
                [-]     "id": "Serverless-LambdaLatestVersion"
                [+]     "id": "Serverless-LambdaLatestVersion",
                [+]     "reason": "CDK-managed singleton Lambda runtime is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-generated inline policy on singleton service role",
                [-]     "id": "NIST.800.53.R5-IAMNoInlinePolicy"
                [+]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [+]     "reason": "CDK-generated inline policy on singleton service role"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgRExRIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "NIST.800.53.R5-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — DLQ is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgY29uY3VycmVuY3kgaXMgbm90IGNvbmZpZ3VyYWJsZQ==",
                [ ]     "id": "NIST.800.53.R5-LambdaConcurrency",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — concurrency is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgVlBDIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "NIST.800.53.R5-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — VPC is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-generated inline policy on singleton service role",
                [-]     "id": "HIPAA.Security-IAMNoInlinePolicy"
                [+]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [+]     "reason": "CDK-generated inline policy on singleton service role"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgRExRIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "HIPAA.Security-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — DLQ is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgY29uY3VycmVuY3kgaXMgbm90IGNvbmZpZ3VyYWJsZQ==",
                [ ]     "id": "HIPAA.Security-LambdaConcurrency",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — concurrency is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgVlBDIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "HIPAA.Security-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — VPC is not configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "CDK-generated inline policy on singleton service role",
                [-]     "id": "PCI.DSS.321-IAMNoInlinePolicy"
                [+]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [+]     "reason": "CDK-generated inline policy on singleton service role"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLLW1hbmFnZWQgc2luZ2xldG9uIExhbWJkYSDigJQgVlBDIGlzIG5vdCBjb25maWd1cmFibGU=",
                [ ]     "id": "PCI.DSS.321-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK-managed singleton Lambda — VPC is not configurable"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]",
                [+]     "reason": "CDK-managed singleton Lambda uses AWS managed execution role"
                [ ]   }
                [ ] ]
[~] AWS::IAM::Role ServerlessAppAudit-us-east-1/S3DataEventsTrail/LogsRole S3DataEventsTrailLogsRole65E12A90
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,17 +1,14 @@
                [ ] [
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   }
                [ ] ]
[~] AWS::IAM::Policy ServerlessAppAudit-us-east-1/S3DataEventsTrail/LogsRole/DefaultPolicy S3DataEventsTrailLogsRoleDefaultPolicy6EF6DB84
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,17 +1,14 @@
                [ ] [
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   }
                [ ] ]
[~] AWS::CloudTrail::Trail ServerlessAppAudit-us-east-1/S3DataEventsTrail S3DataEventsTrail9A744E14
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,17 +1,14 @@
                [ ] [
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgdHJhaWwncyBMb2dzUm9sZSBkZWZhdWx0IHBvbGljeSBpbmxpbmUg4oCUIG5vdCBkaXJlY3RseSBjb25maWd1cmFibGU=",
                [ ]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the trail's LogsRole default policy inline — not directly configurable"
                [ ]   }
                [ ] ]



✨  Number of stacks with differences: 1
ServerlessApp-us-east-1-stage/ServerlessAppBackend-us-east-1
Stack ServerlessApp-us-east-1-stage/ServerlessAppBackend-us-east-1 (ServerlessAppBackend-us-east-1)
Metadata
[-] Metadata cdk_nag: {"rules_to_suppress":[{"reason":"Request validation not needed for sample app","id":"AwsSolutions-APIG2"},{"reason":"Authorization not needed for sample app","id":"AwsSolutions-APIG4"},{"reason":"Cognito authorizer not needed for sample app","id":"AwsSolutions-COG4"},{"reason":"U2VydmVybGVzcy1BUElHV1N0cnVjdHVyZWRMb2dnaW5nIHZhbGlkYXRpb24gZmFpbHMgZHVlIHRvIGludHJpbnNpYyBmdW5jdGlvbiByZWZlcmVuY2UgaW4gYWNjZXNzIGxvZyBkZXN0aW5hdGlvbiDigJQgc3RydWN0dXJlZCBKU09OIGxvZ2dpbmcgaXMgY29uZmlndXJlZCB2aWEgbG9nZ2luZ19mb3JtYXQ9SlNPTiBvbiB0aGUgTGFtYmRh","id":"CdkNagValidationFailure","is_reason_encoded":true},{"reason":"Client-side SSL certificates not required for sample app","id":"NIST.800.53.R5-APIGWSSLEnabled"},{"reason":"QVBJIEdhdGV3YXkgY2FjaGUgY2x1c3RlciBpbnRlbnRpb25hbGx5IGRpc2FibGVkIGZvciBjb3N0IHJlYXNvbnMg4oCUIHRoZSBzbWFsbGVzdCAwLjUgR0IgY2x1c3RlciBpcyB+JDE0L21vbnRoIGZvciBhIHNhbXBsZSBhcHAuIENhY2hpbmcgR0VUIC9ncmVldGluZyB3b3VsZCBhbHNvIHNlcnZlIHN0YWxlIHZhbHVlcyBhY3Jvc3MgU1NNIHBhcmFtZXRlciBhbmQgQXBwQ29uZmlnIGZlYXR1cmUtZmxhZyBjaGFuZ2VzLg==","id":"NIST.800.53.R5-APIGWCacheEnabledAndEncrypted","is_reason_encoded":true},{"reason":"Client-side SSL certificates not required for sample app","id":"HIPAA.Security-APIGWSSLEnabled"},{"reason":"QVBJIEdhdGV3YXkgY2FjaGUgY2x1c3RlciBpbnRlbnRpb25hbGx5IGRpc2FibGVkIGZvciBjb3N0IHJlYXNvbnMg4oCUIHNlZSBOSVNULjgwMC41My5SNS1BUElHV0NhY2hlRW5hYmxlZEFuZEVuY3J5cHRlZCByYXRpb25hbGUgYWJvdmUu","id":"HIPAA.Security-APIGWCacheEnabledAndEncrypted","is_reason_encoded":true},{"reason":"Client-side SSL certificates not required for sample app","id":"PCI.DSS.321-APIGWSSLEnabled"},{"reason":"QVBJIEdhdGV3YXkgY2FjaGUgY2x1c3RlciBpbnRlbnRpb25hbGx5IGRpc2FibGVkIGZvciBjb3N0IHJlYXNvbnMg4oCUIHNlZSBOSVNULjgwMC41My5SNS1BUElHV0NhY2hlRW5hYmxlZEFuZEVuY3J5cHRlZCByYXRpb25hbGUgYWJvdmUu","id":"PCI.DSS.321-APIGWCacheEnabledAndEncrypted","is_reason_encoded":true}]}

Resources
[-] AWS::ApiGateway::Deployment ServerlessAppBackend-us-east-1/App/RestApi/Deployment AppRestApiDeployment0A1A30D71abe2dd993069430c3e4f7123f070b73 destroy
[+] AWS::ApiGateway::Deployment ServerlessAppBackend-us-east-1/App/RestApi/Deployment AppRestApiDeployment0A1A30D7439934e415247bebb089e2d7c8552ba3
[~] AWS::KMS::Key ServerlessAppBackend-us-east-1/App/EncryptionKey AppEncryptionKey7F644894
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::SSM::Parameter ServerlessAppBackend-us-east-1/App/GreetingParameter AppGreetingParameterD5E6E64F
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::AppConfig::Application ServerlessAppBackend-us-east-1/App/FeatureFlagsApp AppFeatureFlagsAppD0EAAC11
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::AppConfig::Environment ServerlessAppBackend-us-east-1/App/FeatureFlagsEnv AppFeatureFlagsEnvBF21F0D3
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::AppConfig::ConfigurationProfile ServerlessAppBackend-us-east-1/App/FeatureFlagsProfile AppFeatureFlagsProfile324F0464
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::AppConfig::HostedConfigurationVersion ServerlessAppBackend-us-east-1/App/FeatureFlagsVersion AppFeatureFlagsVersion486FFE3A
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::AppConfig::DeploymentStrategy ServerlessAppBackend-us-east-1/App/FeatureFlagsDeployStrategy AppFeatureFlagsDeployStrategyF51A0361
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::AppConfig::Deployment ServerlessAppBackend-us-east-1/App/FeatureFlagsDeployment AppFeatureFlagsDeployment1CB9CC7C
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::Logs::LogGroup ServerlessAppBackend-us-east-1/App/FunctionLogGroup AppFunctionLogGroupB9961371
 └─ [~] Metadata
     └─ [+] Added: .cdk_nag
[~] AWS::IAM::Role ServerlessAppBackend-us-east-1/App/ApiFunction/ServiceRole AppApiFunctionServiceRole6AC45AEC
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,66 +1,98 @@
                [ ] [
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "Serverless-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgbm8gYXN5bmMgZXZlbnQgc291cmNlIGV4aXN0czsgdGhlIEV2ZW50SW52b2tlQ29uZmlnIGV4aXN0cyBvbmx5IHRvIHBpbiByZXRyeV9hdHRlbXB0cz0w",
                [ ]     "id": "Serverless-LambdaAsyncFailureDestination",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — no async event source exists; the EventInvokeConfig exists only to pin retry_attempts=0"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "NIST.800.53.R5-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "HIPAA.Security-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "NIST.800.53.R5-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "HIPAA.Security-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "PCI.DSS.321-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "AWSLambdaBasicExecutionRole is the minimal managed policy for Lambda execution",
                [-]     "id": "AwsSolutions-IAM4"
                [+]     "id": "AwsSolutions-IAM5[Action::kms:GenerateDataKey*]",
                [+]     "reason": "kms:GenerateDataKey* and kms:ReEncrypt* require wildcard action suffix — standard KMS usage pattern"
                [ ]   },
                [ ]   {
                [-]     "reason": "a21zOkdlbmVyYXRlRGF0YUtleSogYW5kIGttczpSZUVuY3J5cHQqIHJlcXVpcmUgd2lsZGNhcmQgYWN0aW9uIHN1ZmZpeCDigJQgc3RhbmRhcmQgS01TIHVzYWdlIHBhdHRlcm4=",
                [-]     "id": "AwsSolutions-IAM5",
                [-]     "is_reason_encoded": true
                [+]     "id": "AwsSolutions-IAM5[Action::kms:ReEncrypt*]",
                [+]     "reason": "kms:GenerateDataKey* and kms:ReEncrypt* require wildcard action suffix — standard KMS usage pattern"
                [ ]   },
                [ ]   {
                [-]     "reason": "WC1SYXkgc2VnbWVudHMgaGF2ZSBubyByZXNvdXJjZS1sZXZlbCBBUk4g4oCUIHdpbGRjYXJkIGlzIHJlcXVpcmVkIGZvciB0aGUgWC1SYXkgd3JpdGUgc3RhdGVtZW50IG9ubHk=",
                [-]     "id": "AwsSolutions-IAM5",
                [-]     "is_reason_encoded": true
                [+]     "id": "AwsSolutions-IAM5[Resource::*]",
                [+]     "reason": "X-Ray segments have no resource-level ARN — wildcard is required for the X-Ray write statement only"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]",
                [+]     "reason": "AWSLambdaBasicExecutionRole is the minimal managed policy for Lambda execution"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-APIG2",
                [+]     "reason": "Request validation not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-APIG4",
                [+]     "reason": "Authorization not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-COG4",
                [+]     "reason": "Cognito authorizer not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "CdkNagValidationFailure",
                [+]     "reason": "Serverless-APIGWStructuredLogging validation fails due to intrinsic function reference in access log destination — structured JSON logging is configured via logging_format=JSON on the Lambda"
                [+]   },
                [+]   {
                [+]     "id": "NIST.800.53.R5-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "NIST.800.53.R5-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — the smallest 0.5 GB cluster is ~$14/month for a sample app. Caching GET /greeting would also serve stale values across SSM parameter and AppConfig feature-flag changes."
                [+]   },
                [+]   {
                [+]     "id": "HIPAA.Security-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "HIPAA.Security-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — see NIST.800.53.R5-APIGWCacheEnabledAndEncrypted rationale above."
                [+]   },
                [+]   {
                [+]     "id": "PCI.DSS.321-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "PCI.DSS.321-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — see NIST.800.53.R5-APIGWCacheEnabledAndEncrypted rationale above."
                [ ]   }
                [ ] ]
[~] AWS::IAM::Policy ServerlessAppBackend-us-east-1/App/ApiFunction/ServiceRole/DefaultPolicy AppApiFunctionServiceRoleDefaultPolicy6A1593AC
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,66 +1,98 @@
                [ ] [
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "Serverless-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgbm8gYXN5bmMgZXZlbnQgc291cmNlIGV4aXN0czsgdGhlIEV2ZW50SW52b2tlQ29uZmlnIGV4aXN0cyBvbmx5IHRvIHBpbiByZXRyeV9hdHRlbXB0cz0w",
                [ ]     "id": "Serverless-LambdaAsyncFailureDestination",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — no async event source exists; the EventInvokeConfig exists only to pin retry_attempts=0"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "NIST.800.53.R5-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "HIPAA.Security-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "NIST.800.53.R5-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "HIPAA.Security-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "PCI.DSS.321-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "AWSLambdaBasicExecutionRole is the minimal managed policy for Lambda execution",
                [-]     "id": "AwsSolutions-IAM4"
                [+]     "id": "AwsSolutions-IAM5[Action::kms:GenerateDataKey*]",
                [+]     "reason": "kms:GenerateDataKey* and kms:ReEncrypt* require wildcard action suffix — standard KMS usage pattern"
                [ ]   },
                [ ]   {
                [-]     "reason": "a21zOkdlbmVyYXRlRGF0YUtleSogYW5kIGttczpSZUVuY3J5cHQqIHJlcXVpcmUgd2lsZGNhcmQgYWN0aW9uIHN1ZmZpeCDigJQgc3RhbmRhcmQgS01TIHVzYWdlIHBhdHRlcm4=",
                [-]     "id": "AwsSolutions-IAM5",
                [-]     "is_reason_encoded": true
                [+]     "id": "AwsSolutions-IAM5[Action::kms:ReEncrypt*]",
                [+]     "reason": "kms:GenerateDataKey* and kms:ReEncrypt* require wildcard action suffix — standard KMS usage pattern"
                [ ]   },
                [ ]   {
                [-]     "reason": "WC1SYXkgc2VnbWVudHMgaGF2ZSBubyByZXNvdXJjZS1sZXZlbCBBUk4g4oCUIHdpbGRjYXJkIGlzIHJlcXVpcmVkIGZvciB0aGUgWC1SYXkgd3JpdGUgc3RhdGVtZW50IG9ubHk=",
                [-]     "id": "AwsSolutions-IAM5",
                [-]     "is_reason_encoded": true
                [+]     "id": "AwsSolutions-IAM5[Resource::*]",
                [+]     "reason": "X-Ray segments have no resource-level ARN — wildcard is required for the X-Ray write statement only"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]",
                [+]     "reason": "AWSLambdaBasicExecutionRole is the minimal managed policy for Lambda execution"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-APIG2",
                [+]     "reason": "Request validation not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-APIG4",
                [+]     "reason": "Authorization not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-COG4",
                [+]     "reason": "Cognito authorizer not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "CdkNagValidationFailure",
                [+]     "reason": "Serverless-APIGWStructuredLogging validation fails due to intrinsic function reference in access log destination — structured JSON logging is configured via logging_format=JSON on the Lambda"
                [+]   },
                [+]   {
                [+]     "id": "NIST.800.53.R5-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "NIST.800.53.R5-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — the smallest 0.5 GB cluster is ~$14/month for a sample app. Caching GET /greeting would also serve stale values across SSM parameter and AppConfig feature-flag changes."
                [+]   },
                [+]   {
                [+]     "id": "HIPAA.Security-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "HIPAA.Security-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — see NIST.800.53.R5-APIGWCacheEnabledAndEncrypted rationale above."
                [+]   },
                [+]   {
                [+]     "id": "PCI.DSS.321-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "PCI.DSS.321-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — see NIST.800.53.R5-APIGWCacheEnabledAndEncrypted rationale above."
                [ ]   }
                [ ] ]
[~] AWS::Lambda::Function ServerlessAppBackend-us-east-1/App/ApiFunction AppApiFunctionDE515850
 └─ [~] Metadata
     └─ [~] .cdk_nag:
         └─ [~] .rules_to_suppress:
             └─ @@ -1,66 +1,98 @@
                [ ] [
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "Serverless-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgbm8gYXN5bmMgZXZlbnQgc291cmNlIGV4aXN0czsgdGhlIEV2ZW50SW52b2tlQ29uZmlnIGV4aXN0cyBvbmx5IHRvIHBpbiByZXRyeV9hdHRlbXB0cz0w",
                [ ]     "id": "Serverless-LambdaAsyncFailureDestination",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — no async event source exists; the EventInvokeConfig exists only to pin retry_attempts=0"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "NIST.800.53.R5-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "SW52b2tlZCBzeW5jaHJvbm91c2x5IHZpYSBBUEkgR2F0ZXdheSDigJQgYXN5bmMgRExRIHBhdHRlcm4gZG9lcyBub3QgYXBwbHk=",
                [ ]     "id": "HIPAA.Security-LambdaDLQ",
                [-]     "is_reason_encoded": true
                [+]     "reason": "Invoked synchronously via API Gateway — async DLQ pattern does not apply"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "NIST.800.53.R5-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "HIPAA.Security-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "Tm8gVlBDIOKAlCBhZGRzIHNpZ25pZmljYW50IG9wZXJhdGlvbmFsIGNvbXBsZXhpdHk=",
                [ ]     "id": "PCI.DSS.321-LambdaInsideVPC",
                [-]     "is_reason_encoded": true
                [+]     "reason": "No VPC — adds significant operational complexity"
                [ ]   },
                [ ]   {
                [-]     "reason": "AWSLambdaBasicExecutionRole is the minimal managed policy for Lambda execution",
                [-]     "id": "AwsSolutions-IAM4"
                [+]     "id": "AwsSolutions-IAM5[Action::kms:GenerateDataKey*]",
                [+]     "reason": "kms:GenerateDataKey* and kms:ReEncrypt* require wildcard action suffix — standard KMS usage pattern"
                [ ]   },
                [ ]   {
                [-]     "reason": "a21zOkdlbmVyYXRlRGF0YUtleSogYW5kIGttczpSZUVuY3J5cHQqIHJlcXVpcmUgd2lsZGNhcmQgYWN0aW9uIHN1ZmZpeCDigJQgc3RhbmRhcmQgS01TIHVzYWdlIHBhdHRlcm4=",
                [-]     "id": "AwsSolutions-IAM5",
                [-]     "is_reason_encoded": true
                [+]     "id": "AwsSolutions-IAM5[Action::kms:ReEncrypt*]",
                [+]     "reason": "kms:GenerateDataKey* and kms:ReEncrypt* require wildcard action suffix — standard KMS usage pattern"
                [ ]   },
                [ ]   {
                [-]     "reason": "WC1SYXkgc2VnbWVudHMgaGF2ZSBubyByZXNvdXJjZS1sZXZlbCBBUk4g4oCUIHdpbGRjYXJkIGlzIHJlcXVpcmVkIGZvciB0aGUgWC1SYXkgd3JpdGUgc3RhdGVtZW50IG9ubHk=",
                [-]     "id": "AwsSolutions-IAM5",
                [-]     "is_reason_encoded": true
                [+]     "id": "AwsSolutions-IAM5[Resource::*]",
                [+]     "reason": "X-Ray segments have no resource-level ARN — wildcard is required for the X-Ray write statement only"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "NIST.800.53.R5-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "HIPAA.Security-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [ ]   },
                [ ]   {
                [-]     "reason": "Q0RLIGdlbmVyYXRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgaW5saW5lIG9uIHRoZSBMYW1iZGEgc2VydmljZSByb2xlIOKAlCBub3QgZGlyZWN0bHkgY29uZmlndXJhYmxl",
                [ ]     "id": "PCI.DSS.321-IAMNoInlinePolicy",
                [-]     "is_reason_encoded": true
                [+]     "reason": "CDK generates the default policy inline on the Lambda service role — not directly configurable"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]",
                [+]     "reason": "AWSLambdaBasicExecutionRole is the minimal managed policy for Lambda execution"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-APIG2",
                [+]     "reason": "Request validation not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-APIG4",
                [+]     "reason": "Authorization not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "AwsSolutions-COG4",
                [+]     "reason": "Cognito authorizer not needed for sample app"
                [+]   },
                [+]   {
                [+]     "id": "CdkNagValidationFailure",
                [+]     "reason": "Serverless-APIGWStructuredLogging validation fails due to intrinsic function reference in access log destination — structured JSON logging is configured via logging_format=JSON on the Lambda"
                [+]   },
                [+]   {
                [+]     "id": "NIST.800.53.R5-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "NIST.800.53.R5-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — the smallest 0.5 GB cluster is ~$14/month for a sample app. Caching GET /greeting would also serve stale values across SSM parameter and AppConfig feature-flag changes."
                [+]   },
                [+]   {
                [+]     "id": "HIPAA.Security-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "HIPAA.Security-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — see NIST.800.53.R5-APIGWCacheEnabledAndEncrypted rationale above."
                [+]   },
                [+]   {
                [+]     "id": "PCI.DSS.321-APIGWSSLEnabled",
                [+]     "reason": "Client-side SSL certificates not required for sample app"
                [+]   },
                [+]   {
                [+]     "id": "PCI.DSS.321-APIGWCacheEnabledAndEncrypted",
                [+]     "reason": "API Gateway cache cluster intentionally disabled for cost reasons — see NIST.800.53.R5-APIGWCacheEnabledAndEncrypted rationale above."
                [ ]   }
                [ ] ]
[~] AWS::IAM::Policy ServerlessAppBackend-us-east-1/App/ApiFunction/inlinePolicyAddedToExecution

_…diff truncated; run `make cdk-diff` locally for the full output._

@timpugh timpugh merged commit eb2c714 into main Jul 3, 2026
8 checks passed
@timpugh timpugh deleted the chore/cdk-nag-3-migration branch July 3, 2026 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant