@intentius/chant-lexicon-aws 0.124.30 → 0.124.32
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/actions/dynamodb.js +41 -0
- package/dist/actions/ecr.js +9 -0
- package/dist/actions/ecs.js +5 -0
- package/dist/actions/iam.js +3 -0
- package/dist/actions/index.js +9 -0
- package/dist/actions/lambda.js +11 -0
- package/dist/actions/logs.js +4 -0
- package/dist/actions/s3.js +40 -0
- package/dist/actions/sns.js +5 -0
- package/dist/actions/sqs.js +15 -0
- package/dist/agentcore/trace-fetch.d.ts.map +1 -1
- package/dist/agentcore/trace-fetch.js +472 -0
- package/dist/agentcore/trace-render.js +359 -0
- package/dist/ambient.js +148 -0
- package/dist/api/credential-chain.d.ts +30 -3
- package/dist/api/credential-chain.d.ts.map +1 -1
- package/dist/api/credential-chain.js +509 -0
- package/dist/api/read-client.d.ts +16 -43
- package/dist/api/read-client.d.ts.map +1 -1
- package/dist/api/read-client.js +458 -0
- package/dist/api/sigv4.d.ts +4 -4
- package/dist/api/sigv4.js +185 -0
- package/dist/behaviour-kinds.js +114 -0
- package/dist/caller-identity.d.ts +3 -5
- package/dist/caller-identity.d.ts.map +1 -1
- package/dist/caller-identity.js +146 -0
- package/dist/codegen/docs-cli.js +2 -0
- package/dist/codegen/docs.js +120 -0
- package/dist/codegen/enum-overlay.js +162 -0
- package/dist/codegen/extensions.js +139 -0
- package/dist/codegen/fallback.js +32 -0
- package/dist/codegen/generate-cli.js +15 -0
- package/dist/codegen/generate-lexicon.js +70 -0
- package/dist/codegen/generate-typescript.js +226 -0
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +234 -0
- package/dist/codegen/naming.js +135 -0
- package/dist/codegen/package.js +67 -0
- package/dist/codegen/patches.d.ts +26 -1
- package/dist/codegen/patches.d.ts.map +1 -1
- package/dist/codegen/patches.js +90 -0
- package/dist/codegen/property-overlay.js +85 -0
- package/dist/codegen/property-overlay.json +1 -16
- package/dist/codegen/sam.js +402 -0
- package/dist/codegen/typecheck.js +4 -0
- package/dist/codegen/versions.js +31 -0
- package/dist/components/__tests__/mock-cloud-executor.js +326 -0
- package/dist/components/apply.d.ts +44 -1
- package/dist/components/apply.d.ts.map +1 -1
- package/dist/components/apply.js +752 -0
- package/dist/components/builders.js +37 -0
- package/dist/components/capability-plugin.js +66 -0
- package/dist/components/cloud-executor.d.ts +35 -0
- package/dist/components/cloud-executor.d.ts.map +1 -1
- package/dist/components/cloud-executor.js +576 -0
- package/dist/components/config-bom.js +207 -0
- package/dist/components/host-delivery.js +117 -0
- package/dist/components/index.js +18 -0
- package/dist/components/job-submission.js +77 -0
- package/dist/components/publish.js +234 -0
- package/dist/components/safety.js +62 -0
- package/dist/components/wait-aws.js +68 -0
- package/dist/composites/agentcore-agent.js +187 -0
- package/dist/composites/agentcore-trust-policy.js +13 -0
- package/dist/composites/alb-shared.js +84 -0
- package/dist/composites/bucket-deployment.js +93 -0
- package/dist/composites/catalog.js +2714 -0
- package/dist/composites/dynamodb-table.js +66 -0
- package/dist/composites/ec2-instance-bundle.js +75 -0
- package/dist/composites/ec2-instance-role.js +26 -0
- package/dist/composites/ecr-repository.js +64 -0
- package/dist/composites/ecs-trust-policy.js +10 -0
- package/dist/composites/efs-with-access-point.js +44 -0
- package/dist/composites/eks-cluster.js +118 -0
- package/dist/composites/fargate-alb.js +216 -0
- package/dist/composites/fargate-service.js +222 -0
- package/dist/composites/index.js +28 -0
- package/dist/composites/lambda-api.js +15 -0
- package/dist/composites/lambda-dynamodb.js +77 -0
- package/dist/composites/lambda-eventbridge.js +27 -0
- package/dist/composites/lambda-function.js +54 -0
- package/dist/composites/lambda-s3.js +93 -0
- package/dist/composites/lambda-sns.js +23 -0
- package/dist/composites/lambda-sqs.js +34 -0
- package/dist/composites/landing-zone.js +82 -0
- package/dist/composites/microvm-app.js +293 -0
- package/dist/composites/minimal-vpc.js +40 -0
- package/dist/composites/monitoring-stack.js +105 -0
- package/dist/composites/nlb-service.js +61 -0
- package/dist/composites/rds-instance.js +98 -0
- package/dist/composites/scheduled-lambda.js +28 -0
- package/dist/composites/solr-fargate-service.js +33 -0
- package/dist/composites/step-functions-workflow.js +78 -0
- package/dist/composites/vpc-default.js +132 -0
- package/dist/condition.js +43 -0
- package/dist/coverage.js +4 -0
- package/dist/deep-observe.d.ts.map +1 -1
- package/dist/deep-observe.js +709 -0
- package/dist/deep-topology.js +226 -0
- package/dist/default-tags.js +50 -0
- package/dist/defaults.js +85 -0
- package/dist/dependencies.js +269 -0
- package/dist/detect.js +21 -0
- package/dist/disruption.d.ts.map +1 -1
- package/dist/disruption.js +129 -0
- package/dist/effect-receipt-row.js +107 -0
- package/dist/generated/index.d.ts +1297 -82
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +12382 -0
- package/dist/generated/runtime.js +4 -0
- package/dist/governance.js +131 -0
- package/dist/identity-observe.d.ts.map +1 -1
- package/dist/identity-observe.js +127 -0
- package/dist/import/generator.js +757 -0
- package/dist/import/live-export.js +34 -0
- package/dist/import/parser.js +394 -0
- package/dist/index.js +69 -0
- package/dist/integrity.json +6 -6
- package/dist/intrinsics.js +393 -0
- package/dist/lint/audit-catalog.js +87 -0
- package/dist/lint/audit-lineage.js +150 -0
- package/dist/lint/post-synth/cf-refs.js +247 -0
- package/dist/lint/post-synth/cor020.js +60 -0
- package/dist/lint/post-synth/ext001.d.ts.map +1 -1
- package/dist/lint/post-synth/ext001.js +197 -0
- package/dist/lint/post-synth/index.js +124 -0
- package/dist/lint/post-synth/waw010.js +41 -0
- package/dist/lint/post-synth/waw011.js +41 -0
- package/dist/lint/post-synth/waw013.js +38 -0
- package/dist/lint/post-synth/waw014.js +42 -0
- package/dist/lint/post-synth/waw015.js +88 -0
- package/dist/lint/post-synth/waw016.d.ts.map +1 -1
- package/dist/lint/post-synth/waw016.js +116 -0
- package/dist/lint/post-synth/waw017.js +43 -0
- package/dist/lint/post-synth/waw018.js +61 -0
- package/dist/lint/post-synth/waw019.js +64 -0
- package/dist/lint/post-synth/waw020.js +56 -0
- package/dist/lint/post-synth/waw021.js +44 -0
- package/dist/lint/post-synth/waw022.js +36 -0
- package/dist/lint/post-synth/waw023.js +40 -0
- package/dist/lint/post-synth/waw024.js +46 -0
- package/dist/lint/post-synth/waw025.js +36 -0
- package/dist/lint/post-synth/waw026.js +38 -0
- package/dist/lint/post-synth/waw027.js +41 -0
- package/dist/lint/post-synth/waw028.js +39 -0
- package/dist/lint/post-synth/waw029.js +54 -0
- package/dist/lint/post-synth/waw030.js +282 -0
- package/dist/lint/post-synth/waw031.js +58 -0
- package/dist/lint/post-synth/waw032.js +45 -0
- package/dist/lint/post-synth/waw033.js +75 -0
- package/dist/lint/post-synth/waw034.js +52 -0
- package/dist/lint/post-synth/waw035.js +56 -0
- package/dist/lint/post-synth/waw036.js +79 -0
- package/dist/lint/post-synth/waw037.js +67 -0
- package/dist/lint/post-synth/waw038.js +42 -0
- package/dist/lint/post-synth/waw039.js +42 -0
- package/dist/lint/post-synth/waw040.js +45 -0
- package/dist/lint/post-synth/waw041.js +40 -0
- package/dist/lint/post-synth/waw042.js +99 -0
- package/dist/lint/post-synth/waw043.js +51 -0
- package/dist/lint/post-synth/waw044.js +64 -0
- package/dist/lint/post-synth/waw045.js +49 -0
- package/dist/lint/post-synth/waw046.js +52 -0
- package/dist/lint/post-synth/waw047.js +43 -0
- package/dist/lint/post-synth/waw048.js +40 -0
- package/dist/lint/post-synth/waw049.js +78 -0
- package/dist/lint/post-synth/waw050.js +44 -0
- package/dist/lint/post-synth/waw051.js +41 -0
- package/dist/lint/post-synth/waw052.js +43 -0
- package/dist/lint/post-synth/waw053.js +43 -0
- package/dist/lint/post-synth/waw054.js +41 -0
- package/dist/lint/post-synth/waw055.js +41 -0
- package/dist/lint/post-synth/waw056.js +65 -0
- package/dist/lint/post-synth/waw057.js +43 -0
- package/dist/lint/post-synth/waw058.js +61 -0
- package/dist/lint/post-synth/waw059.js +338 -0
- package/dist/lint/post-synth/waw060.js +83 -0
- package/dist/lint/post-synth/waw061.js +60 -0
- package/dist/lint/post-synth/waw062.js +0 -0
- package/dist/lint/post-synth/waw063.js +0 -0
- package/dist/lint/post-synth/waw064.js +45 -0
- package/dist/lint/post-synth/waw065.js +104 -0
- package/dist/lint/post-synth/waw066.js +145 -0
- package/dist/lint/post-synth/waw067.js +115 -0
- package/dist/lint/post-synth/waw068.js +69 -0
- package/dist/lint/post-synth/waw069.js +0 -0
- package/dist/lint/rules/hardcoded-region.js +38 -0
- package/dist/lint/rules/iam-wildcard.js +60 -0
- package/dist/lint/rules/index.js +6 -0
- package/dist/lint/rules/s3-encryption.js +60 -0
- package/dist/live-attrs.js +42 -0
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +18 -0
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +66 -0
- package/dist/manifest.json +1 -1
- package/dist/mapping.js +33 -0
- package/dist/meta.json +17359 -784
- package/dist/nested-stack.js +95 -0
- package/dist/okf/index.md +203 -0
- package/dist/okf/rules/EXT001.md +1 -0
- package/dist/okf/rules/WAW016.md +2 -0
- package/dist/okf/rules/WAW019.md +1 -0
- package/dist/okf/rules/WAW028.md +1 -0
- package/dist/okf/rules/WAW030.md +2 -0
- package/dist/okf/rules/WAW039.md +1 -0
- package/dist/okf/rules/WAW049.md +1 -0
- package/dist/okf/rules/WAW056.md +1 -0
- package/dist/okf/rules/WAW058.md +1 -0
- package/dist/okf/rules/WAW062.md +1 -0
- package/dist/okf/rules/WAW064.md +1 -0
- package/dist/okf/rules/WAW065.md +1 -0
- package/dist/okf/rules/WAW066.md +1 -0
- package/dist/okf/rules/WAW067.md +1 -0
- package/dist/okf/rules/WAW068.md +1 -0
- package/dist/okf/rules/WAW069.md +4 -0
- package/dist/okf/types/AIWorkloadConfig.md +23 -0
- package/dist/okf/types/ARCRegionSwitchPlan.md +1 -0
- package/dist/okf/types/AccountAccessApplication.md +28 -0
- package/dist/okf/types/AccountAccessEntitlement.md +22 -0
- package/dist/okf/types/ActionTarget.md +20 -0
- package/dist/okf/types/AdConfiguration.md +21 -0
- package/dist/okf/types/Adapter.md +26 -0
- package/dist/okf/types/AgentContext.md +35 -0
- package/dist/okf/types/AgentGoal.md +31 -0
- package/dist/okf/types/AgentProfile.md +34 -0
- package/dist/okf/types/Alarm.md +3 -1
- package/dist/okf/types/AlarmModel.md +14 -9
- package/dist/okf/types/AmplifyWebhook.md +25 -0
- package/dist/okf/types/ApiCache.md +8 -8
- package/dist/okf/types/ApiGatewayManagedOverrides.md +5 -5
- package/dist/okf/types/AppAuthorization.md +35 -0
- package/dist/okf/types/AppBlockBuilder.md +1 -0
- package/dist/okf/types/AppInstance.md +2 -2
- package/dist/okf/types/AppInstanceBot.md +2 -2
- package/dist/okf/types/AppStreamFleet.md +3 -2
- package/dist/okf/types/AppSyncApiKey.md +6 -6
- package/dist/okf/types/AppSyncType.md +22 -0
- package/dist/okf/types/ApplicationStatusCheck.md +36 -0
- package/dist/okf/types/ApplicationVersion.md +4 -1
- package/dist/okf/types/ApplicationsList.md +26 -0
- package/dist/okf/types/ApprovalPolicy.md +28 -0
- package/dist/okf/types/ArchiveRule.md +24 -0
- package/dist/okf/types/Asset.md +30 -0
- package/dist/okf/types/Backup.md +31 -0
- package/dist/okf/types/BedrockAgentCoreDataset.md +1 -1
- package/dist/okf/types/BedrockAgentCoreGateway.md +3 -0
- package/dist/okf/types/BedrockSession.md +28 -0
- package/dist/okf/types/BillEstimate.md +35 -0
- package/dist/okf/types/Brand.md +32 -0
- package/dist/okf/types/CallAnalyticsCategory.md +25 -0
- package/dist/okf/types/Campaign.md +28 -0
- package/dist/okf/types/CapacityProvider.md +30 -0
- package/dist/okf/types/Case.md +24 -0
- package/dist/okf/types/CertificateAssociation.md +13 -0
- package/dist/okf/types/ChangeSet.md +36 -0
- package/dist/okf/types/ChannelFlow.md +29 -0
- package/dist/okf/types/ChimeChannel.md +39 -0
- package/dist/okf/types/Classifier.md +6 -6
- package/dist/okf/types/ClientVpnAuthorizationRule.md +6 -6
- package/dist/okf/types/ClientVpnEndpoint.md +2 -0
- package/dist/okf/types/ClientVpnRoute.md +5 -5
- package/dist/okf/types/CloudConnector.md +29 -0
- package/dist/okf/types/Cluster.md +39 -0
- package/dist/okf/types/ClusterSchedulerConfig.md +30 -0
- package/dist/okf/types/CodeCommitRepository.md +12 -12
- package/dist/okf/types/CodeConnectionsHost.md +26 -0
- package/dist/okf/types/CodeRepository.md +5 -5
- package/dist/okf/types/CompositeAlarm.md +1 -0
- package/dist/okf/types/ComputeEnvironment.md +2 -0
- package/dist/okf/types/ComputeNodeGroup.md +1 -1
- package/dist/okf/types/ComputeQuota.md +34 -0
- package/dist/okf/types/ConfigRule.md +1 -1
- package/dist/okf/types/ConfigurationRecorder.md +7 -6
- package/dist/okf/types/ConnectAttachment.md +2 -0
- package/dist/okf/types/ConnectQueue.md +5 -1
- package/dist/okf/types/ConnectVocabulary.md +28 -0
- package/dist/okf/types/ConnectionType.md +24 -0
- package/dist/okf/types/ConsentPortal.md +33 -0
- package/dist/okf/types/ContactMethod.md +29 -0
- package/dist/okf/types/ContainerAssociation.md +26 -0
- package/dist/okf/types/ContainerFleet.md +1 -1
- package/dist/okf/types/ContainerGroupDefinition.md +1 -1
- package/dist/okf/types/Content.md +40 -0
- package/dist/okf/types/ContentAssociation.md +28 -0
- package/dist/okf/types/CustomDetectionRuleAssociation.md +28 -0
- package/dist/okf/types/CustomEntityType.md +4 -9
- package/dist/okf/types/Customization.md +22 -0
- package/dist/okf/types/CwIntegration.md +31 -0
- package/dist/okf/types/DAXParameterGroup.md +3 -8
- package/dist/okf/types/DAXSubnetGroup.md +0 -5
- package/dist/okf/types/DBClusterEndpoint.md +31 -0
- package/dist/okf/types/DBProxyTargetGroup.md +1 -0
- package/dist/okf/types/DBSnapshot.md +62 -0
- package/dist/okf/types/DLMLifecyclePolicy.md +12 -12
- package/dist/okf/types/DLPSetting.md +31 -0
- package/dist/okf/types/DMSInstanceProfile.md +1 -1
- package/dist/okf/types/DRSLaunchConfigurationTemplate.md +28 -0
- package/dist/okf/types/Daemon.md +1 -0
- package/dist/okf/types/DataExchangeDataSet.md +29 -0
- package/dist/okf/types/DataIntegrationFlow.md +27 -0
- package/dist/okf/types/DataMigration.md +1 -1
- package/dist/okf/types/DataProvider.md +2 -1
- package/dist/okf/types/DataQualityRuleset.md +6 -11
- package/dist/okf/types/DataSource.md +23 -0
- package/dist/okf/types/Dataset.md +20 -0
- package/dist/okf/types/DatasetIntegration.md +23 -0
- package/dist/okf/types/DbCluster.md +1 -1
- package/dist/okf/types/DbInstance.md +8 -2
- package/dist/okf/types/DeadlineBudget.md +29 -0
- package/dist/okf/types/DelegationSet.md +23 -0
- package/dist/okf/types/DeliveryChannel.md +6 -11
- package/dist/okf/types/DevOpsAgentAgentSpace.md +4 -0
- package/dist/okf/types/DevOpsAgentService.md +1 -0
- package/dist/okf/types/DevOpsAgentTrigger.md +28 -0
- package/dist/okf/types/DirectConnectGatewayAttachment.md +2 -0
- package/dist/okf/types/Directory.md +60 -0
- package/dist/okf/types/DocDBDBClusterParameterGroup.md +5 -10
- package/dist/okf/types/DocDBDBSubnetGroup.md +4 -9
- package/dist/okf/types/DocDBElasticClusterSnapshot.md +36 -0
- package/dist/okf/types/DocumentClassifierEndpoint.md +27 -0
- package/dist/okf/types/Domain.md +27 -0
- package/dist/okf/types/EKSCertificateAuthority.md +42 -0
- package/dist/okf/types/EKSCluster.md +8 -0
- package/dist/okf/types/EcSnapshot.md +66 -0
- package/dist/okf/types/EmailIdentityCertificate.md +15 -0
- package/dist/okf/types/EndpointConfig.md +14 -13
- package/dist/okf/types/EntityRecognizer.md +27 -0
- package/dist/okf/types/EntityRecognizerEndpoint.md +31 -0
- package/dist/okf/types/EnvironmentEC2.md +13 -13
- package/dist/okf/types/EvaluationForm.md +1 -0
- package/dist/okf/types/Evaluator.md +6 -2
- package/dist/okf/types/EventAction.md +26 -0
- package/dist/okf/types/EventRule.md +2 -0
- package/dist/okf/types/EventSource.md +30 -0
- package/dist/okf/types/EventTracker.md +22 -0
- package/dist/okf/types/EventsV2EventBus.md +28 -0
- package/dist/okf/types/EventsV2ResourcePolicy.md +19 -0
- package/dist/okf/types/EventsV2Subscriber.md +39 -0
- package/dist/okf/types/ExperimentDefinition.md +39 -0
- package/dist/okf/types/ExperimentRun.md +33 -0
- package/dist/okf/types/ExperimentTrialComponent.md +13 -11
- package/dist/okf/types/FHIRDatastore.md +3 -0
- package/dist/okf/types/FSxSnapshot.md +5 -5
- package/dist/okf/types/FSxVolume.md +9 -9
- package/dist/okf/types/FeaturedResultsSet.md +26 -0
- package/dist/okf/types/Feed.md +1 -0
- package/dist/okf/types/FieldLevelEncryptionConfig.md +25 -0
- package/dist/okf/types/FieldLevelEncryptionProfile.md +22 -0
- package/dist/okf/types/FileCache.md +45 -0
- package/dist/okf/types/Filter.md +27 -0
- package/dist/okf/types/Firewall.md +6 -0
- package/dist/okf/types/FlowMediaStream.md +28 -0
- package/dist/okf/types/FlowOutput.md +1 -0
- package/dist/okf/types/FpgaImage.md +38 -0
- package/dist/okf/types/Function.md +2 -2
- package/dist/okf/types/Gateway.md +41 -0
- package/dist/okf/types/GatewayClusterAssociations.md +23 -0
- package/dist/okf/types/GatewayRateLimit.md +26 -0
- package/dist/okf/types/GatewayRule.md +32 -0
- package/dist/okf/types/GlobalReplicationGroup.md +3 -0
- package/dist/okf/types/GlobalResolver.md +1 -1
- package/dist/okf/types/GlobalTable.md +1 -0
- package/dist/okf/types/GlueConnection.md +5 -4
- package/dist/okf/types/GlueSecurityConfiguration.md +1 -6
- package/dist/okf/types/GlueSession.md +38 -0
- package/dist/okf/types/GlueTable.md +5 -10
- package/dist/okf/types/GlueWorkflow.md +5 -10
- package/dist/okf/types/Group.md +27 -0
- package/dist/okf/types/Harness.md +1 -0
- package/dist/okf/types/HostKey.md +33 -0
- package/dist/okf/types/HostedZone.md +1 -0
- package/dist/okf/types/HttpApi.md +2 -0
- package/dist/okf/types/HttpNamespace.md +5 -5
- package/dist/okf/types/HubV2.md +1 -0
- package/dist/okf/types/HumanTaskUi.md +22 -0
- package/dist/okf/types/IPv4Pool.md +28 -0
- package/dist/okf/types/ImageBuilder.md +1 -0
- package/dist/okf/types/ImageBuilderImage.md +1 -1
- package/dist/okf/types/ImagePipeline.md +1 -1
- package/dist/okf/types/InferenceComponent.md +5 -1
- package/dist/okf/types/InfluxDBBackup.md +65 -0
- package/dist/okf/types/InfluxDBCluster.md +3 -0
- package/dist/okf/types/InfrastructureConfiguration.md +2 -0
- package/dist/okf/types/IngestionDestination.md +28 -0
- package/dist/okf/types/InputSecurityGroup.md +6 -4
- package/dist/okf/types/InspectorV2Connector.md +38 -0
- package/dist/okf/types/InstanceEventWindow.md +25 -0
- package/dist/okf/types/InstanceFleetConfig.md +10 -10
- package/dist/okf/types/InstanceGroupConfig.md +3 -3
- package/dist/okf/types/InstrumentationConfig.md +31 -0
- package/dist/okf/types/IntegrationAssociation.md +3 -0
- package/dist/okf/types/IoTSiteWiseApplication.md +34 -0
- package/dist/okf/types/IoTSiteWiseDataset.md +5 -2
- package/dist/okf/types/IoTSiteWiseTask.md +24 -0
- package/dist/okf/types/IpamExternalResourceVerificationToken.md +35 -0
- package/dist/okf/types/IpamInternetRegistryAssociation.md +32 -0
- package/dist/okf/types/Job.md +35 -0
- package/dist/okf/types/JobTemplate.md +26 -0
- package/dist/okf/types/KinesisChannel.md +31 -0
- package/dist/okf/types/KinesisStream.md +1 -0
- package/dist/okf/types/LambdaResourcePolicy.md +14 -0
- package/dist/okf/types/Lexicon.md +34 -0
- package/dist/okf/types/LicenseAssetGroup.md +23 -0
- package/dist/okf/types/LicenseConfiguration.md +33 -0
- package/dist/okf/types/LicenseServerEndpoint.md +32 -0
- package/dist/okf/types/LightsailKeyPair.md +29 -0
- package/dist/okf/types/LimitsProfile.md +27 -0
- package/dist/okf/types/LocationAzureBlob.md +2 -1
- package/dist/okf/types/LocationObjectStorage.md +1 -0
- package/dist/okf/types/LogAlarm.md +2 -0
- package/dist/okf/types/MGNConnector.md +23 -0
- package/dist/okf/types/MGNLaunchConfigurationTemplate.md +37 -0
- package/dist/okf/types/MLTransform.md +15 -15
- package/dist/okf/types/MWAAServerlessWorkflow.md +3 -0
- package/dist/okf/types/ManagedNotificationAccountContactAssociation.md +1 -0
- package/dist/okf/types/ManagedNotificationAdditionalChannelAssociation.md +1 -0
- package/dist/okf/types/MediaConvertJobTemplate.md +11 -13
- package/dist/okf/types/MediaConvertQueue.md +8 -10
- package/dist/okf/types/MediaInsightsPipelineConfiguration.md +28 -0
- package/dist/okf/types/MediaLiveInput.md +41 -18
- package/dist/okf/types/MediaPackageV2Channel.md +3 -0
- package/dist/okf/types/MediaPackageV2OriginEndpoint.md +1 -0
- package/dist/okf/types/MediaPipelineKinesisVideoStreamPool.md +28 -0
- package/dist/okf/types/MediaTailorFunction.md +27 -0
- package/dist/okf/types/MedicalVocabulary.md +21 -0
- package/dist/okf/types/Member.md +26 -0
- package/dist/okf/types/Memory.md +6 -0
- package/dist/okf/types/MemoryDBSnapshot.md +29 -0
- package/dist/okf/types/Metric.md +59 -0
- package/dist/okf/types/MetricAttribution.md +23 -0
- package/dist/okf/types/MicrosoftAD.md +11 -11
- package/dist/okf/types/MigrationProject.md +8 -1
- package/dist/okf/types/Monitor.md +26 -0
- package/dist/okf/types/NFSFileShare.md +44 -0
- package/dist/okf/types/NeptuneGraphGraph.md +1 -0
- package/dist/okf/types/NetworkConnector.md +4 -0
- package/dist/okf/types/NetworkFlowMonitorScope.md +23 -0
- package/dist/okf/types/NetworkMigrationDefinition.md +31 -0
- package/dist/okf/types/NetworkSecurityManagerDeployment.md +31 -0
- package/dist/okf/types/NetworkSecurityManagerPolicy.md +32 -0
- package/dist/okf/types/NetworkSecurityManagerScope.md +29 -0
- package/dist/okf/types/NotebookInstance.md +18 -18
- package/dist/okf/types/NotebookInstanceLifecycleConfig.md +6 -5
- package/dist/okf/types/NotifyConfiguration.md +35 -0
- package/dist/okf/types/OTelEnrichment.md +2 -0
- package/dist/okf/types/OnlineEvaluationConfig.md +0 -1
- package/dist/okf/types/OrganizationConfigRule.md +7 -7
- package/dist/okf/types/Outpost.md +32 -0
- package/dist/okf/types/ParallelData.md +40 -0
- package/dist/okf/types/Partition.md +5 -5
- package/dist/okf/types/PaymentConnector.md +4 -1
- package/dist/okf/types/Pentest.md +1 -0
- package/dist/okf/types/PerfReports.md +28 -0
- package/dist/okf/types/PermissionAssociation.md +30 -0
- package/dist/okf/types/PersonalizeDataset.md +1 -0
- package/dist/okf/types/PersonalizeDatasetGroup.md +1 -0
- package/dist/okf/types/PersonalizeSchema.md +1 -0
- package/dist/okf/types/Pipeline.md +25 -0
- package/dist/okf/types/PlaybackConfiguration.md +1 -0
- package/dist/okf/types/PolicyAssociation.md +1 -1
- package/dist/okf/types/PolicyGrant.md +2 -2
- package/dist/okf/types/PolicyPrincipalAttachment.md +2 -7
- package/dist/okf/types/PortalProduct.md +24 -0
- package/dist/okf/types/PrefetchSchedule.md +25 -0
- package/dist/okf/types/PricingPlanManagerSubscription.md +31 -0
- package/dist/okf/types/PrincipalAssociation.md +27 -0
- package/dist/okf/types/PrivateDnsNamespace.md +8 -8
- package/dist/okf/types/PrivateVirtualInterface.md +1 -0
- package/dist/okf/types/ProcurementPortalPreference.md +45 -0
- package/dist/okf/types/Program.md +33 -0
- package/dist/okf/types/ProjectMembership.md +1 -1
- package/dist/okf/types/ProtocolsList.md +26 -0
- package/dist/okf/types/PublicDnsNamespace.md +7 -7
- package/dist/okf/types/PublicVirtualInterface.md +1 -0
- package/dist/okf/types/QEV2IdcApplication.md +25 -0
- package/dist/okf/types/QueryLoggingConfig.md +21 -0
- package/dist/okf/types/QuerySuggestionsBlockList.md +25 -0
- package/dist/okf/types/QuickSightAssignment.md +24 -0
- package/dist/okf/types/RAMResourceAssociation.md +27 -0
- package/dist/okf/types/RDSClusterSnapshot.md +54 -0
- package/dist/okf/types/RDSDBParameterGroup.md +5 -0
- package/dist/okf/types/RDSDeployment.md +41 -0
- package/dist/okf/types/RcsAgent.md +38 -0
- package/dist/okf/types/ReceiptRule.md +5 -5
- package/dist/okf/types/ReceiptRuleSet.md +1 -6
- package/dist/okf/types/RecommenderFilter.md +27 -0
- package/dist/okf/types/RecommenderSchema.md +25 -0
- package/dist/okf/types/RecordSet.md +16 -22
- package/dist/okf/types/RecoveryPlan.md +28 -0
- package/dist/okf/types/RedshiftIdcApplication.md +31 -0
- package/dist/okf/types/RedshiftSnapshot.md +59 -0
- package/dist/okf/types/RegistrationAttachment.md +28 -0
- package/dist/okf/types/Registry.md +41 -0
- package/dist/okf/types/RegistryRecord.md +38 -0
- package/dist/okf/types/RelatedItem.md +24 -0
- package/dist/okf/types/ReplicationConfigurationTemplate.md +35 -0
- package/dist/okf/types/ReplicationSubnetGroup.md +4 -9
- package/dist/okf/types/ReplicationTask.md +14 -14
- package/dist/okf/types/ReportGenerator.md +29 -0
- package/dist/okf/types/ReportGroup.md +1 -3
- package/dist/okf/types/ResilienceHubV2Policy.md +1 -0
- package/dist/okf/types/ResilienceHubV2Service.md +1 -0
- package/dist/okf/types/ResourceConfiguration.md +1 -1
- package/dist/okf/types/ResourceMetricsConfiguration.md +21 -0
- package/dist/okf/types/RestApi.md +1 -0
- package/dist/okf/types/RetrievalInstruction.md +32 -0
- package/dist/okf/types/RouterOutput.md +1 -0
- package/dist/okf/types/Rule.md +31 -0
- package/dist/okf/types/RunCache.md +29 -0
- package/dist/okf/types/Runtime.md +2 -1
- package/dist/okf/types/SCNInstance.md +33 -0
- package/dist/okf/types/SDBDomain.md +2 -2
- package/dist/okf/types/SMBFileShare.md +49 -0
- package/dist/okf/types/SageMakerArtifact.md +27 -0
- package/dist/okf/types/SageMakerEndpoint.md +0 -1
- package/dist/okf/types/ScalableTarget.md +1 -0
- package/dist/okf/types/ScalingPlan.md +6 -6
- package/dist/okf/types/ScheduledReport.md +31 -0
- package/dist/okf/types/SecondaryNetwork.md +26 -0
- package/dist/okf/types/SecurityAgentArtifact.md +25 -0
- package/dist/okf/types/SecurityAgentIntegration.md +31 -0
- package/dist/okf/types/Server.md +1 -0
- package/dist/okf/types/ServerlessCache.md +2 -0
- package/dist/okf/types/ServerlessCacheSnapshot.md +31 -0
- package/dist/okf/types/ServerlessRepoApplication.md +32 -0
- package/dist/okf/types/ServiceDiscoveryInstance.md +3 -7
- package/dist/okf/types/SipMediaApplication.md +27 -0
- package/dist/okf/types/SiteToSiteVpnAttachment.md +2 -0
- package/dist/okf/types/SnapshotCopyGrant.md +20 -0
- package/dist/okf/types/Solution.md +1 -0
- package/dist/okf/types/SourceAssociation.md +25 -0
- package/dist/okf/types/SourceCredential.md +6 -6
- package/dist/okf/types/SourceNetwork.md +23 -0
- package/dist/okf/types/StackFleetAssociation.md +2 -7
- package/dist/okf/types/StorageTierPolicy.md +20 -0
- package/dist/okf/types/StorageVirtualMachine.md +9 -9
- package/dist/okf/types/Stream.md +28 -0
- package/dist/okf/types/SubnetCidrReservation.md +26 -0
- package/dist/okf/types/SubscriptionProvider.md +26 -0
- package/dist/okf/types/SupportPermit.md +29 -0
- package/dist/okf/types/Table.md +2 -1
- package/dist/okf/types/TableOptimizer.md +5 -10
- package/dist/okf/types/Tape.md +31 -0
- package/dist/okf/types/Template.md +36 -0
- package/dist/okf/types/Tenant.md +2 -0
- package/dist/okf/types/Terminology.md +39 -0
- package/dist/okf/types/Thesaurus.md +25 -0
- package/dist/okf/types/ThingPrincipalAttachment.md +3 -8
- package/dist/okf/types/Topic.md +1 -0
- package/dist/okf/types/TopicRuleDestination.md +1 -0
- package/dist/okf/types/TrafficPolicy.md +26 -0
- package/dist/okf/types/TrafficPolicyInstance.md +28 -0
- package/dist/okf/types/TranscribeVocabulary.md +27 -0
- package/dist/okf/types/TransitGatewayRouteTableAttachment.md +2 -0
- package/dist/okf/types/TransitVirtualInterface.md +1 -0
- package/dist/okf/types/Tunnel.md +25 -0
- package/dist/okf/types/UsageLimit.md +26 -0
- package/dist/okf/types/UseCase.md +23 -0
- package/dist/okf/types/User.md +47 -0
- package/dist/okf/types/VPCEndpoint.md +1 -1
- package/dist/okf/types/VPCEndpointService.md +6 -0
- package/dist/okf/types/VPCPeeringConnection.md +2 -2
- package/dist/okf/types/VPNConcentrator.md +1 -1
- package/dist/okf/types/VPNConnection.md +1 -1
- package/dist/okf/types/VerifiedDestinationNumber.md +25 -0
- package/dist/okf/types/View.md +27 -0
- package/dist/okf/types/VoiceConnector.md +30 -0
- package/dist/okf/types/Volume.md +44 -0
- package/dist/okf/types/Vpc.md +1 -1
- package/dist/okf/types/VpcAttachment.md +2 -0
- package/dist/okf/types/WebFunction.md +27 -0
- package/dist/okf/types/WebFunctionEndpoint.md +44 -0
- package/dist/okf/types/WebFunctionRevision.md +32 -0
- package/dist/okf/types/WickrNetwork.md +27 -0
- package/dist/okf/types/Worker.md +29 -0
- package/dist/okf/types/Workforce.md +26 -0
- package/dist/okf/types/Workload.md +35 -0
- package/dist/okf/types/WorkloadEstimate.md +35 -0
- package/dist/okf/types/Workspace.md +28 -0
- package/dist/okf/types/Workteam.md +8 -8
- package/dist/op/activities/aws-apply.js +214 -0
- package/dist/op/activities/floci.js +97 -0
- package/dist/op/activities/index.js +32 -0
- package/dist/op/builders.js +50 -0
- package/dist/ownership.js +52 -0
- package/dist/package-cli.js +25 -0
- package/dist/parameter.js +19 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1006 -0
- package/dist/properties.js +166 -0
- package/dist/pseudo.js +25 -0
- package/dist/receipt-store.d.ts.map +1 -1
- package/dist/receipt-store.js +233 -0
- package/dist/reference-catalog.js +106 -0
- package/dist/rules/ext001.ts +3 -3
- package/dist/rules/waw016.ts +2 -2
- package/dist/serializer.js +529 -0
- package/dist/spec/fetch.js +193 -0
- package/dist/spec/parse.js +259 -0
- package/dist/spec/pin.js +185 -0
- package/dist/spec/pinned-types.json +203 -0
- package/dist/stack-errors.js +14 -0
- package/dist/taggable.d.ts.map +1 -1
- package/dist/taggable.js +33 -0
- package/dist/teardown.js +199 -0
- package/dist/template-sections.js +53 -0
- package/dist/template-transform.js +50 -0
- package/dist/types/index.d.ts +18847 -1124
- package/dist/validate-cli.js +16 -0
- package/dist/validate.js +33 -0
- package/package.json +9 -9
- package/src/agentcore/trace-fetch.ts +2 -1
- package/src/api/credential-chain.ts +119 -9
- package/src/api/credential-isolation.test.ts +72 -0
- package/src/api/read-client-chain.test.ts +159 -0
- package/src/api/read-client.ts +42 -6
- package/src/api/sigv4.ts +4 -4
- package/src/caller-identity.ts +3 -5
- package/src/codegen/any-budget.test.ts +12 -2
- package/src/codegen/generate.ts +9 -0
- package/src/codegen/package.ts +2 -2
- package/src/codegen/patches.test.ts +95 -0
- package/src/codegen/patches.ts +53 -9
- package/src/codegen/property-overlay.json +1 -16
- package/src/components/apply.ts +218 -6
- package/src/components/cfn-plan-floci.e2e.test.ts +76 -0
- package/src/components/cfn-plan.test.ts +225 -16
- package/src/components/cloud-executor.ts +73 -25
- package/src/deep-observe.ts +2 -1
- package/src/disruption.ts +2 -1
- package/src/generated/index.d.ts +18847 -1124
- package/src/generated/index.ts +1376 -161
- package/src/generated/lexicon-aws.json +17359 -784
- package/src/identity-observe.ts +2 -1
- package/src/lint/post-synth/ext001.ts +3 -3
- package/src/lint/post-synth/waw016.ts +2 -2
- package/src/lsp/completions.ts +2 -1
- package/src/lsp/hover.ts +2 -1
- package/src/plugin.ts +2 -1
- package/src/receipt-store.ts +2 -1
- package/src/spec/pin.ts +3 -3
- package/src/spec/pinned-types.json +203 -0
- package/src/taggable.ts +2 -2
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW032: EFS Transit Encryption Disabled
|
|
3
|
+
*
|
|
4
|
+
* Flags EFS volume configurations on Fargate task definitions where transit
|
|
5
|
+
* encryption has been explicitly disabled. FargateService defaults to ENABLED;
|
|
6
|
+
* this rule catches intentional opt-outs.
|
|
7
|
+
*/
|
|
8
|
+
import { parseCFTemplate } from "./cf-refs.js";
|
|
9
|
+
export function checkEfsTransitEncryption(ctx) {
|
|
10
|
+
const diagnostics = [];
|
|
11
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
12
|
+
const template = parseCFTemplate(output);
|
|
13
|
+
if (!template?.Resources)
|
|
14
|
+
continue;
|
|
15
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
16
|
+
if (resource.Type !== "AWS::ECS::TaskDefinition")
|
|
17
|
+
continue;
|
|
18
|
+
const volumes = resource.Properties?.Volumes;
|
|
19
|
+
if (!Array.isArray(volumes))
|
|
20
|
+
continue;
|
|
21
|
+
for (const volume of volumes) {
|
|
22
|
+
const efsConfig = volume?.EFSVolumeConfiguration;
|
|
23
|
+
if (!efsConfig)
|
|
24
|
+
continue;
|
|
25
|
+
if (efsConfig.TransitEncryption === "DISABLED") {
|
|
26
|
+
diagnostics.push({
|
|
27
|
+
checkId: "WAW032",
|
|
28
|
+
severity: "warning",
|
|
29
|
+
message: `EFS volume "${volume.Name ?? "unnamed"}" in task "${logicalId}" has transit encryption disabled — set TransitEncryption: ENABLED to protect data in transit`,
|
|
30
|
+
entity: logicalId,
|
|
31
|
+
lexicon: "aws",
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return diagnostics;
|
|
38
|
+
}
|
|
39
|
+
export const waw032 = {
|
|
40
|
+
id: "WAW032",
|
|
41
|
+
description: "EFS volume on Fargate task has transit encryption disabled",
|
|
42
|
+
check(ctx) {
|
|
43
|
+
return checkEfsTransitEncryption(ctx);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW033: Solr Heap Exceeds 50% of Container Memory
|
|
3
|
+
*
|
|
4
|
+
* When SOLR_HEAP is set on a Fargate task running a Solr image, validates that
|
|
5
|
+
* the heap does not exceed 50% of the task's allocated memory. Exceeding this
|
|
6
|
+
* leaves insufficient headroom for the OS file cache that Lucene MMap relies on,
|
|
7
|
+
* causing the OOM killer to terminate the container.
|
|
8
|
+
*/
|
|
9
|
+
import { parseCFTemplate } from "./cf-refs.js";
|
|
10
|
+
/** Parse heap strings like "4g", "2048m", "2048" → megabytes */
|
|
11
|
+
function parseHeapMb(value) {
|
|
12
|
+
const lower = value.trim().toLowerCase();
|
|
13
|
+
const gMatch = lower.match(/^(\d+(?:\.\d+)?)g$/);
|
|
14
|
+
if (gMatch)
|
|
15
|
+
return Math.round(parseFloat(gMatch[1]) * 1024);
|
|
16
|
+
const mMatch = lower.match(/^(\d+(?:\.\d+)?)m?$/);
|
|
17
|
+
if (mMatch)
|
|
18
|
+
return Math.round(parseFloat(mMatch[1]));
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function isSolrImage(image) {
|
|
22
|
+
return typeof image === "string" && image.toLowerCase().includes("solr");
|
|
23
|
+
}
|
|
24
|
+
export function checkSolrHeapRatio(ctx) {
|
|
25
|
+
const diagnostics = [];
|
|
26
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
27
|
+
const template = parseCFTemplate(output);
|
|
28
|
+
if (!template?.Resources)
|
|
29
|
+
continue;
|
|
30
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
31
|
+
if (resource.Type !== "AWS::ECS::TaskDefinition")
|
|
32
|
+
continue;
|
|
33
|
+
const props = resource.Properties ?? {};
|
|
34
|
+
if (typeof props.Memory !== "string")
|
|
35
|
+
continue;
|
|
36
|
+
const taskMemoryMb = parseInt(props.Memory);
|
|
37
|
+
if (!taskMemoryMb)
|
|
38
|
+
continue;
|
|
39
|
+
const containers = Array.isArray(props.ContainerDefinitions)
|
|
40
|
+
? props.ContainerDefinitions
|
|
41
|
+
: [];
|
|
42
|
+
for (const container of containers) {
|
|
43
|
+
if (typeof container !== "object" || container === null)
|
|
44
|
+
continue;
|
|
45
|
+
const c = container;
|
|
46
|
+
if (!isSolrImage(c.Image))
|
|
47
|
+
continue;
|
|
48
|
+
const envVars = Array.isArray(c.Environment) ? c.Environment : [];
|
|
49
|
+
const heapEntry = envVars.find((e) => typeof e === "object" && e !== null && e.Name === "SOLR_HEAP");
|
|
50
|
+
if (!heapEntry)
|
|
51
|
+
continue; // WAW034 covers missing heap
|
|
52
|
+
const heapMb = parseHeapMb(String(heapEntry.Value ?? ""));
|
|
53
|
+
if (heapMb === null)
|
|
54
|
+
continue;
|
|
55
|
+
if (heapMb > taskMemoryMb * 0.5) {
|
|
56
|
+
diagnostics.push({
|
|
57
|
+
checkId: "WAW033",
|
|
58
|
+
severity: "error",
|
|
59
|
+
message: `Solr container "${c.Name ?? "app"}" SOLR_HEAP (${heapMb}MB) exceeds 50% of task memory (${taskMemoryMb}MB) — risk of OOM kill; set SOLR_HEAP <= ${Math.floor(taskMemoryMb * 0.45)}m`,
|
|
60
|
+
entity: logicalId,
|
|
61
|
+
lexicon: "aws",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return diagnostics;
|
|
68
|
+
}
|
|
69
|
+
export const waw033 = {
|
|
70
|
+
id: "WAW033",
|
|
71
|
+
description: "Solr SOLR_HEAP exceeds 50% of Fargate task memory",
|
|
72
|
+
check(ctx) {
|
|
73
|
+
return checkSolrHeapRatio(ctx);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW034: Solr Container Undersized
|
|
3
|
+
*
|
|
4
|
+
* Fargate tasks running a Solr image with less than 2048MB of memory will
|
|
5
|
+
* fail under any real load — the JVM alone needs headroom for the heap plus
|
|
6
|
+
* OS file cache for Lucene MMap. 4096MB is the practical production minimum.
|
|
7
|
+
*/
|
|
8
|
+
import { parseCFTemplate } from "./cf-refs.js";
|
|
9
|
+
function isSolrImage(image) {
|
|
10
|
+
return typeof image === "string" && image.toLowerCase().includes("solr");
|
|
11
|
+
}
|
|
12
|
+
export function checkSolrMemoryMinimum(ctx) {
|
|
13
|
+
const diagnostics = [];
|
|
14
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
15
|
+
const template = parseCFTemplate(output);
|
|
16
|
+
if (!template?.Resources)
|
|
17
|
+
continue;
|
|
18
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
19
|
+
if (resource.Type !== "AWS::ECS::TaskDefinition")
|
|
20
|
+
continue;
|
|
21
|
+
const props = resource.Properties ?? {};
|
|
22
|
+
if (typeof props.Memory !== "string")
|
|
23
|
+
continue;
|
|
24
|
+
const taskMemoryMb = parseInt(props.Memory);
|
|
25
|
+
if (!taskMemoryMb)
|
|
26
|
+
continue;
|
|
27
|
+
const containers = Array.isArray(props.ContainerDefinitions)
|
|
28
|
+
? props.ContainerDefinitions
|
|
29
|
+
: [];
|
|
30
|
+
const hasSolr = containers.some((c) => typeof c === "object" && c !== null && isSolrImage(c.Image));
|
|
31
|
+
if (!hasSolr)
|
|
32
|
+
continue;
|
|
33
|
+
if (taskMemoryMb < 2048) {
|
|
34
|
+
diagnostics.push({
|
|
35
|
+
checkId: "WAW034",
|
|
36
|
+
severity: "warning",
|
|
37
|
+
message: `Solr task "${logicalId}" has only ${taskMemoryMb}MB memory — Solr requires at least 2048MB; 4096MB recommended for production`,
|
|
38
|
+
entity: logicalId,
|
|
39
|
+
lexicon: "aws",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return diagnostics;
|
|
45
|
+
}
|
|
46
|
+
export const waw034 = {
|
|
47
|
+
id: "WAW034",
|
|
48
|
+
description: "Fargate task running Solr has insufficient memory (< 2048MB)",
|
|
49
|
+
check(ctx) {
|
|
50
|
+
return checkSolrMemoryMinimum(ctx);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW035: Solr Container Missing nofile Ulimit
|
|
3
|
+
*
|
|
4
|
+
* Solr opens a file descriptor for every shard replica, index file, log, and
|
|
5
|
+
* connection. Without a raised nofile limit the process hits the default kernel
|
|
6
|
+
* limit (~1024) under moderate load, causing "Too many open files" errors that
|
|
7
|
+
* bring the node down. The production minimum is 65535.
|
|
8
|
+
*/
|
|
9
|
+
import { parseCFTemplate } from "./cf-refs.js";
|
|
10
|
+
const NOFILE_MIN = 65535;
|
|
11
|
+
function isSolrImage(image) {
|
|
12
|
+
return typeof image === "string" && image.toLowerCase().includes("solr");
|
|
13
|
+
}
|
|
14
|
+
export function checkSolrUlimits(ctx) {
|
|
15
|
+
const diagnostics = [];
|
|
16
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
17
|
+
const template = parseCFTemplate(output);
|
|
18
|
+
if (!template?.Resources)
|
|
19
|
+
continue;
|
|
20
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
21
|
+
if (resource.Type !== "AWS::ECS::TaskDefinition")
|
|
22
|
+
continue;
|
|
23
|
+
const containers = Array.isArray(resource.Properties?.ContainerDefinitions)
|
|
24
|
+
? resource.Properties.ContainerDefinitions
|
|
25
|
+
: [];
|
|
26
|
+
for (const container of containers) {
|
|
27
|
+
if (typeof container !== "object" || container === null)
|
|
28
|
+
continue;
|
|
29
|
+
const c = container;
|
|
30
|
+
if (!isSolrImage(c.Image))
|
|
31
|
+
continue;
|
|
32
|
+
const ulimits = Array.isArray(c.Ulimits) ? c.Ulimits : [];
|
|
33
|
+
const nofile = ulimits.find((u) => typeof u === "object" && u !== null && u.Name === "nofile");
|
|
34
|
+
const hardLimit = nofile ? Number(nofile.HardLimit ?? 0) : 0;
|
|
35
|
+
if (!nofile || hardLimit < NOFILE_MIN) {
|
|
36
|
+
const current = nofile ? ` (current HardLimit: ${hardLimit})` : " (not set)";
|
|
37
|
+
diagnostics.push({
|
|
38
|
+
checkId: "WAW035",
|
|
39
|
+
severity: "warning",
|
|
40
|
+
message: `Solr container "${c.Name ?? "app"}" in task "${logicalId}" nofile ulimit${current} — set HardLimit >= ${NOFILE_MIN} to prevent "Too many open files" under load`,
|
|
41
|
+
entity: logicalId,
|
|
42
|
+
lexicon: "aws",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return diagnostics;
|
|
49
|
+
}
|
|
50
|
+
export const waw035 = {
|
|
51
|
+
id: "WAW035",
|
|
52
|
+
description: "Solr container missing nofile ulimit >= 65535",
|
|
53
|
+
check(ctx) {
|
|
54
|
+
return checkSolrUlimits(ctx);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW036: Non-ASCII Characters in EC2/IAM String Properties
|
|
3
|
+
*
|
|
4
|
+
* EC2, IAM, CloudWatch, and other AWS services only accept ASCII 0x20–0x7E in
|
|
5
|
+
* description, name, and label fields. Non-ASCII characters (em-dashes, curly
|
|
6
|
+
* quotes, accented letters, etc.) cause the changeset to fail at EarlyValidation
|
|
7
|
+
* with an opaque "Invalid parameter" error that doesn't name the offending property.
|
|
8
|
+
*
|
|
9
|
+
* Properties checked (all must be plain ASCII strings):
|
|
10
|
+
* - AWS::EC2::SecurityGroup GroupDescription
|
|
11
|
+
* - AWS::EC2::LaunchTemplate LaunchTemplateName
|
|
12
|
+
* - AWS::IAM::Role RoleName
|
|
13
|
+
* - AWS::Lambda::Function FunctionName
|
|
14
|
+
* - AWS::RDS::DBSubnetGroup DBSubnetGroupDescription
|
|
15
|
+
* - AWS::CloudWatch::Alarm AlarmDescription, AlarmName
|
|
16
|
+
* - AWS::AutoScaling::AutoScalingGroup AutoScalingGroupName
|
|
17
|
+
*/
|
|
18
|
+
import { parseCFTemplate } from "./cf-refs.js";
|
|
19
|
+
/** Map of CFN resource type → list of property names that must be ASCII-only. */
|
|
20
|
+
const ASCII_REQUIRED = {
|
|
21
|
+
"AWS::EC2::SecurityGroup": ["GroupDescription"],
|
|
22
|
+
"AWS::EC2::LaunchTemplate": ["LaunchTemplateName"],
|
|
23
|
+
"AWS::IAM::Role": ["RoleName"],
|
|
24
|
+
"AWS::Lambda::Function": ["FunctionName"],
|
|
25
|
+
"AWS::RDS::DBSubnetGroup": ["DBSubnetGroupDescription"],
|
|
26
|
+
"AWS::CloudWatch::Alarm": ["AlarmDescription", "AlarmName"],
|
|
27
|
+
"AWS::AutoScaling::AutoScalingGroup": ["AutoScalingGroupName"],
|
|
28
|
+
};
|
|
29
|
+
/** Return true if the string contains any character outside ASCII printable range (0x20–0x7E). */
|
|
30
|
+
function hasNonAscii(s) {
|
|
31
|
+
for (let i = 0; i < s.length; i++) {
|
|
32
|
+
const code = s.charCodeAt(i);
|
|
33
|
+
if (code < 0x20 || code > 0x7e)
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
export function checkNonAsciiProps(ctx) {
|
|
39
|
+
const diagnostics = [];
|
|
40
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
41
|
+
const template = parseCFTemplate(output);
|
|
42
|
+
if (!template?.Resources)
|
|
43
|
+
continue;
|
|
44
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
45
|
+
const propsToCheck = ASCII_REQUIRED[resource.Type];
|
|
46
|
+
if (!propsToCheck)
|
|
47
|
+
continue;
|
|
48
|
+
const props = resource.Properties ?? {};
|
|
49
|
+
for (const propName of propsToCheck) {
|
|
50
|
+
const value = props[propName];
|
|
51
|
+
if (typeof value !== "string")
|
|
52
|
+
continue;
|
|
53
|
+
if (!hasNonAscii(value))
|
|
54
|
+
continue;
|
|
55
|
+
// Find the specific offending characters for the message.
|
|
56
|
+
const badChars = [...new Set([...value].filter((c) => {
|
|
57
|
+
const code = c.charCodeAt(0);
|
|
58
|
+
return code < 0x20 || code > 0x7e;
|
|
59
|
+
}))];
|
|
60
|
+
const charList = badChars.map((c) => `U+${c.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`).join(", ");
|
|
61
|
+
diagnostics.push({
|
|
62
|
+
checkId: "WAW036",
|
|
63
|
+
severity: "error",
|
|
64
|
+
message: `${resource.Type} "${logicalId}" property "${propName}" contains non-ASCII characters (${charList}) — AWS rejects these at changeset validation time`,
|
|
65
|
+
entity: logicalId,
|
|
66
|
+
lexicon: "aws",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return diagnostics;
|
|
72
|
+
}
|
|
73
|
+
export const waw036 = {
|
|
74
|
+
id: "WAW036",
|
|
75
|
+
description: "Non-ASCII characters in EC2/IAM/CW string properties — rejected at changeset time",
|
|
76
|
+
check(ctx) {
|
|
77
|
+
return checkNonAsciiProps(ctx);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW037: Null Values in CloudFormation Resource Properties
|
|
3
|
+
*
|
|
4
|
+
* `resource.PropName` where PropName is not a real GetAtt attribute returns null
|
|
5
|
+
* silently in chant's AttrRef system — the TypeScript types say `string` but the
|
|
6
|
+
* runtime value is null. This produces a template with literal null values that
|
|
7
|
+
* CloudFormation rejects at changeset time with an unhelpful "Invalid template"
|
|
8
|
+
* error.
|
|
9
|
+
*
|
|
10
|
+
* Common causes:
|
|
11
|
+
* - `resource.SomeId` instead of `Ref(resource)` (use Ref for the primary identifier)
|
|
12
|
+
* - `resource.SomeProp` where SomeProp is not listed in AWS CloudFormation GetAtt docs
|
|
13
|
+
* - Typo in an attribute name (e.g. `resource.GroupName` vs `resource.GroupId`)
|
|
14
|
+
*
|
|
15
|
+
* This check scans every resource's Properties for null values at any depth and
|
|
16
|
+
* reports the logical resource ID and dotted property path.
|
|
17
|
+
*/
|
|
18
|
+
import { parseCFTemplate } from "./cf-refs.js";
|
|
19
|
+
/** Recursively collect all paths where the value is null. */
|
|
20
|
+
function collectNullPaths(value, path, results, logicalId) {
|
|
21
|
+
if (value === null) {
|
|
22
|
+
results.push({ logicalId, path });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
for (let i = 0; i < value.length; i++) {
|
|
27
|
+
collectNullPaths(value[i], `${path}[${i}]`, results, logicalId);
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (typeof value === "object") {
|
|
32
|
+
for (const [k, v] of Object.entries(value)) {
|
|
33
|
+
collectNullPaths(v, path ? `${path}.${k}` : k, results, logicalId);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function checkNullProperties(ctx) {
|
|
38
|
+
const diagnostics = [];
|
|
39
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
40
|
+
const template = parseCFTemplate(output);
|
|
41
|
+
if (!template?.Resources)
|
|
42
|
+
continue;
|
|
43
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
44
|
+
if (!resource.Properties)
|
|
45
|
+
continue;
|
|
46
|
+
const nullLocations = [];
|
|
47
|
+
collectNullPaths(resource.Properties, "", nullLocations, logicalId);
|
|
48
|
+
for (const loc of nullLocations) {
|
|
49
|
+
diagnostics.push({
|
|
50
|
+
checkId: "WAW037",
|
|
51
|
+
severity: "error",
|
|
52
|
+
message: `${resource.Type} "${logicalId}" has a null value at Properties.${loc.path} — likely a .PropName AttrRef on a non-existent GetAtt attribute. Use Ref(resource) for the primary identifier, or check the attribute name.`,
|
|
53
|
+
entity: logicalId,
|
|
54
|
+
lexicon: "aws",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return diagnostics;
|
|
60
|
+
}
|
|
61
|
+
export const waw037 = {
|
|
62
|
+
id: "WAW037",
|
|
63
|
+
description: "Null values in CFN resource properties — caused by invalid AttrRef (.PropName) usage",
|
|
64
|
+
check(ctx) {
|
|
65
|
+
return checkNullProperties(ctx);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW038: RDS Publicly Accessible
|
|
3
|
+
*
|
|
4
|
+
* Flags RDS instances with PubliclyAccessible: true — the instance gets a
|
|
5
|
+
* public IP/DNS name reachable from the internet instead of staying inside
|
|
6
|
+
* the VPC. (DBCluster has no PubliclyAccessible property; that's set on the
|
|
7
|
+
* member DBInstance.)
|
|
8
|
+
*/
|
|
9
|
+
import { parseCFTemplate, isIntrinsic } from "./cf-refs.js";
|
|
10
|
+
export function checkRdsPubliclyAccessible(ctx) {
|
|
11
|
+
const diagnostics = [];
|
|
12
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
13
|
+
const template = parseCFTemplate(output);
|
|
14
|
+
if (!template?.Resources)
|
|
15
|
+
continue;
|
|
16
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
17
|
+
if (resource.Type !== "AWS::RDS::DBInstance")
|
|
18
|
+
continue;
|
|
19
|
+
const props = resource.Properties ?? {};
|
|
20
|
+
const publiclyAccessible = props.PubliclyAccessible;
|
|
21
|
+
if (isIntrinsic(publiclyAccessible))
|
|
22
|
+
continue;
|
|
23
|
+
if (publiclyAccessible === true) {
|
|
24
|
+
diagnostics.push({
|
|
25
|
+
checkId: "WAW038",
|
|
26
|
+
severity: "error",
|
|
27
|
+
message: `RDS instance "${logicalId}" has PubliclyAccessible: true — keep the database inside the VPC, unreachable from the internet`,
|
|
28
|
+
entity: logicalId,
|
|
29
|
+
lexicon: "aws",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return diagnostics;
|
|
35
|
+
}
|
|
36
|
+
export const waw038 = {
|
|
37
|
+
id: "WAW038",
|
|
38
|
+
description: "RDS instance is publicly accessible — keep databases inside the VPC",
|
|
39
|
+
check(ctx) {
|
|
40
|
+
return checkRdsPubliclyAccessible(ctx);
|
|
41
|
+
},
|
|
42
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW039: RDS Backup Retention Not Set
|
|
3
|
+
*
|
|
4
|
+
* Flags RDS instances and clusters without a positive BackupRetentionPeriod —
|
|
5
|
+
* a retention of 0 (or an unset property on a resource that otherwise pins
|
|
6
|
+
* every other property explicitly) disables automated backups entirely.
|
|
7
|
+
*/
|
|
8
|
+
import { parseCFTemplate, isIntrinsic } from "./cf-refs.js";
|
|
9
|
+
const RDS_TYPES = new Set(["AWS::RDS::DBInstance", "AWS::RDS::DBCluster"]);
|
|
10
|
+
export function checkRdsBackupRetention(ctx) {
|
|
11
|
+
const diagnostics = [];
|
|
12
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
13
|
+
const template = parseCFTemplate(output);
|
|
14
|
+
if (!template?.Resources)
|
|
15
|
+
continue;
|
|
16
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
17
|
+
if (!RDS_TYPES.has(resource.Type))
|
|
18
|
+
continue;
|
|
19
|
+
const props = resource.Properties ?? {};
|
|
20
|
+
const retention = props.BackupRetentionPeriod;
|
|
21
|
+
if (isIntrinsic(retention))
|
|
22
|
+
continue;
|
|
23
|
+
if (retention === undefined || retention === 0) {
|
|
24
|
+
diagnostics.push({
|
|
25
|
+
checkId: "WAW039",
|
|
26
|
+
severity: "error",
|
|
27
|
+
message: `RDS resource "${logicalId}" (${resource.Type}) does not have a positive BackupRetentionPeriod — automated backups are disabled`,
|
|
28
|
+
entity: logicalId,
|
|
29
|
+
lexicon: "aws",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return diagnostics;
|
|
35
|
+
}
|
|
36
|
+
export const waw039 = {
|
|
37
|
+
id: "WAW039",
|
|
38
|
+
description: "RDS instance or cluster has automated backups disabled — set a positive BackupRetentionPeriod",
|
|
39
|
+
check(ctx) {
|
|
40
|
+
return checkRdsBackupRetention(ctx);
|
|
41
|
+
},
|
|
42
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW040: RDS Deletion Protection Disabled (full tier)
|
|
3
|
+
*
|
|
4
|
+
* Flags RDS instances and clusters without DeletionProtection: true. Tier-aware
|
|
5
|
+
* (#894): a relaxed "light" stack (local/Floci, or no --env/ownership.env set)
|
|
6
|
+
* only warns, since local/dev databases are routinely torn down on purpose; the
|
|
7
|
+
* strict "full"/production tier (ctx.env === "prod"/"production"/"full", the
|
|
8
|
+
* existing #201 env seam — see isFullTierEnv) fails the build.
|
|
9
|
+
*/
|
|
10
|
+
import { parseCFTemplate, isIntrinsic, isFullTierEnv } from "./cf-refs.js";
|
|
11
|
+
const RDS_TYPES = new Set(["AWS::RDS::DBInstance", "AWS::RDS::DBCluster"]);
|
|
12
|
+
export function checkRdsDeletionProtection(ctx) {
|
|
13
|
+
const diagnostics = [];
|
|
14
|
+
const severity = isFullTierEnv(ctx.env) ? "error" : "warning";
|
|
15
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
16
|
+
const template = parseCFTemplate(output);
|
|
17
|
+
if (!template?.Resources)
|
|
18
|
+
continue;
|
|
19
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
20
|
+
if (!RDS_TYPES.has(resource.Type))
|
|
21
|
+
continue;
|
|
22
|
+
const props = resource.Properties ?? {};
|
|
23
|
+
const deletionProtection = props.DeletionProtection;
|
|
24
|
+
if (isIntrinsic(deletionProtection))
|
|
25
|
+
continue;
|
|
26
|
+
if (deletionProtection !== true) {
|
|
27
|
+
diagnostics.push({
|
|
28
|
+
checkId: "WAW040",
|
|
29
|
+
severity,
|
|
30
|
+
message: `RDS resource "${logicalId}" (${resource.Type}) does not have DeletionProtection: true — enable it on the full/production tier`,
|
|
31
|
+
entity: logicalId,
|
|
32
|
+
lexicon: "aws",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return diagnostics;
|
|
38
|
+
}
|
|
39
|
+
export const waw040 = {
|
|
40
|
+
id: "WAW040",
|
|
41
|
+
description: "RDS instance or cluster does not have DeletionProtection enabled (full tier)",
|
|
42
|
+
check(ctx) {
|
|
43
|
+
return checkRdsDeletionProtection(ctx);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW041: RDS Proxy TLS Not Required
|
|
3
|
+
*
|
|
4
|
+
* Flags RDS Proxy resources without RequireTLS: true — without it, a client
|
|
5
|
+
* can connect to the proxy over plaintext.
|
|
6
|
+
*/
|
|
7
|
+
import { parseCFTemplate, isIntrinsic } from "./cf-refs.js";
|
|
8
|
+
export function checkDbProxyTls(ctx) {
|
|
9
|
+
const diagnostics = [];
|
|
10
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
11
|
+
const template = parseCFTemplate(output);
|
|
12
|
+
if (!template?.Resources)
|
|
13
|
+
continue;
|
|
14
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
15
|
+
if (resource.Type !== "AWS::RDS::DBProxy")
|
|
16
|
+
continue;
|
|
17
|
+
const props = resource.Properties ?? {};
|
|
18
|
+
const requireTls = props.RequireTLS;
|
|
19
|
+
if (isIntrinsic(requireTls))
|
|
20
|
+
continue;
|
|
21
|
+
if (requireTls !== true) {
|
|
22
|
+
diagnostics.push({
|
|
23
|
+
checkId: "WAW041",
|
|
24
|
+
severity: "error",
|
|
25
|
+
message: `RDS Proxy "${logicalId}" does not have RequireTLS: true — clients can connect over plaintext`,
|
|
26
|
+
entity: logicalId,
|
|
27
|
+
lexicon: "aws",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return diagnostics;
|
|
33
|
+
}
|
|
34
|
+
export const waw041 = {
|
|
35
|
+
id: "WAW041",
|
|
36
|
+
description: "RDS Proxy does not require TLS for client connections",
|
|
37
|
+
check(ctx) {
|
|
38
|
+
return checkDbProxyTls(ctx);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WAW042: S3 Bucket Missing TLS-Only Policy
|
|
3
|
+
*
|
|
4
|
+
* Flags S3 buckets without a companion BucketPolicy that denies requests made
|
|
5
|
+
* over plaintext (a Deny statement keyed on `aws:SecureTransport` being
|
|
6
|
+
* false). Encryption at rest is WAW006; the public-access block is WAW018;
|
|
7
|
+
* this covers encryption in transit.
|
|
8
|
+
*/
|
|
9
|
+
import { parseCFTemplate, findResourceRefs } from "./cf-refs.js";
|
|
10
|
+
function statementDeniesInsecureTransport(stmt) {
|
|
11
|
+
if (stmt.Effect !== "Deny")
|
|
12
|
+
return false;
|
|
13
|
+
const condition = stmt.Condition;
|
|
14
|
+
if (typeof condition !== "object" || condition === null)
|
|
15
|
+
return false;
|
|
16
|
+
const cond = condition;
|
|
17
|
+
for (const operator of ["Bool", "NumericLessThan"]) {
|
|
18
|
+
const clause = cond[operator];
|
|
19
|
+
if (typeof clause !== "object" || clause === null)
|
|
20
|
+
continue;
|
|
21
|
+
const value = clause["aws:SecureTransport"];
|
|
22
|
+
if (value === "false" || value === false)
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
/** A value as JSON with its object keys sorted, for comparing two values. */
|
|
28
|
+
function canonical(value) {
|
|
29
|
+
return JSON.stringify(value, (_key, v) => v && typeof v === "object" && !Array.isArray(v)
|
|
30
|
+
? Object.fromEntries(Object.keys(v).sort().map((k) => [k, v[k]]))
|
|
31
|
+
: v);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Logical ids of every bucket a BucketPolicy's `Bucket` property resolves to:
|
|
35
|
+
* a bucket it references (`Ref`, `GetAtt`), or a bucket whose `BucketName`
|
|
36
|
+
* is the same value (`Fn::Sub: "${AppName}-${AWS::Region}"` on both).
|
|
37
|
+
*/
|
|
38
|
+
function bucketPolicyTargets(resource, resources) {
|
|
39
|
+
const props = resource.Properties ?? {};
|
|
40
|
+
const targets = findResourceRefs(props.Bucket);
|
|
41
|
+
if (props.Bucket === undefined)
|
|
42
|
+
return targets;
|
|
43
|
+
const policyBucket = canonical(props.Bucket);
|
|
44
|
+
for (const [logicalId, other] of Object.entries(resources)) {
|
|
45
|
+
if (other.Type !== "AWS::S3::Bucket")
|
|
46
|
+
continue;
|
|
47
|
+
const name = other.Properties?.BucketName;
|
|
48
|
+
if (name !== undefined && canonical(name) === policyBucket)
|
|
49
|
+
targets.add(logicalId);
|
|
50
|
+
}
|
|
51
|
+
return targets;
|
|
52
|
+
}
|
|
53
|
+
export function checkS3TlsOnlyPolicy(ctx) {
|
|
54
|
+
const diagnostics = [];
|
|
55
|
+
for (const [_lexicon, output] of ctx.outputs) {
|
|
56
|
+
const template = parseCFTemplate(output);
|
|
57
|
+
if (!template?.Resources)
|
|
58
|
+
continue;
|
|
59
|
+
const bucketsWithTlsPolicy = new Set();
|
|
60
|
+
for (const resource of Object.values(template.Resources)) {
|
|
61
|
+
if (resource.Type !== "AWS::S3::BucketPolicy")
|
|
62
|
+
continue;
|
|
63
|
+
const props = resource.Properties ?? {};
|
|
64
|
+
const policyDoc = props.PolicyDocument;
|
|
65
|
+
if (typeof policyDoc !== "object" || policyDoc === null)
|
|
66
|
+
continue;
|
|
67
|
+
const statements = policyDoc.Statement;
|
|
68
|
+
if (!Array.isArray(statements))
|
|
69
|
+
continue;
|
|
70
|
+
const hasTlsDeny = statements.some((stmt) => typeof stmt === "object" && stmt !== null && statementDeniesInsecureTransport(stmt));
|
|
71
|
+
if (!hasTlsDeny)
|
|
72
|
+
continue;
|
|
73
|
+
for (const bucketId of bucketPolicyTargets(resource, template.Resources)) {
|
|
74
|
+
bucketsWithTlsPolicy.add(bucketId);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
78
|
+
if (resource.Type !== "AWS::S3::Bucket")
|
|
79
|
+
continue;
|
|
80
|
+
if (bucketsWithTlsPolicy.has(logicalId))
|
|
81
|
+
continue;
|
|
82
|
+
diagnostics.push({
|
|
83
|
+
checkId: "WAW042",
|
|
84
|
+
severity: "error",
|
|
85
|
+
message: `S3 bucket "${logicalId}" has no bucket policy denying non-TLS requests — add a Deny statement on aws:SecureTransport = false`,
|
|
86
|
+
entity: logicalId,
|
|
87
|
+
lexicon: "aws",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return diagnostics;
|
|
92
|
+
}
|
|
93
|
+
export const waw042 = {
|
|
94
|
+
id: "WAW042",
|
|
95
|
+
description: "S3 bucket missing a TLS-only bucket policy — deny requests over plaintext",
|
|
96
|
+
check(ctx) {
|
|
97
|
+
return checkS3TlsOnlyPolicy(ctx);
|
|
98
|
+
},
|
|
99
|
+
};
|