From e0b66f8be12d625fa8958903b9026df4db774852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=87=E6=BD=AD?= Date: Tue, 9 Jun 2026 14:04:04 +0800 Subject: [PATCH 1/5] feat: add InfraGuard policy catalog --- .gitignore | 2 + MANIFEST.in | 2 +- pyproject.toml | 1 + .../skills/bundled/iac_aliyun/SKILL.md | 12 +- .../skills/bundled/iac_aliyun/__init__.py | 8 +- .../skills/bundled/iac_aliyun/auto_trigger.py | 22 + .../references/infraguard-policies/README.md | 36 + .../alb-loadbalancer-name-required.rego | 65 + .../best-practice-usage-guidelines.md | 22 + .../ecs-instance-name-required.rego | 65 + .../ecs-instance-tags-required.rego | 65 + ...s-security-group-description-required.rego | 65 + .../kms-key-description-required.rego | 65 + .../oss-bucket-tags-required.rego | 65 + .../polardb-cluster-tags-required.rego | 65 + .../rds-instance-tags-required.rego | 65 + .../redis-instance-name-required.rego | 65 + .../slb-loadbalancer-name-required.rego | 65 + .../sls-project-description-required.rego | 65 + .../best-practice/vpc-name-required.rego | 65 + .../best-practice/vswitch-name-required.rego | 65 + .../actiontrail-trail-intact-enabled.rego | 91 ++ .../compliance/compliance-usage-guidelines.md | 22 + ...-instance-deletion-protection-enabled.rego | 66 + .../compliance/kms-key-rotation-enabled.rego | 66 + ...maxcompute-project-encryption-enabled.rego | 67 + .../nas-filesystem-encrypt-type-check.rego | 72 + .../oss-bucket-logging-enabled.rego | 68 + ...bucket-server-side-encryption-enabled.rego | 68 + .../polardb-cluster-enabled-tde.rego | 61 + .../compliance/ram-password-policy-check.rego | 68 + .../compliance/ram-user-mfa-check.rego | 72 + .../rds-instance-enabled-log-backup.rego | 61 + ...s-white-list-internet-ip-access-check.rego | 68 + .../compliance/sls-project-multi-zone.rego | 70 + .../cost-optimization-usage-guidelines.md | 22 + .../ecs-disk-category-required.rego | 65 + .../ecs-disk-size-required.rego | 65 + .../ecs-instance-bandwidth-configured.rego | 65 + .../ecs-instance-charge-type-required.rego | 65 + .../ecs-instance-type-required.rego | 65 + .../eip-bandwidth-required.rego | 65 + .../logstore-ttl-required.rego | 65 + .../nat-gateway-spec-required.rego | 65 + .../oss-storage-class-required.rego | 65 + .../rds-pay-type-required.rego | 65 + .../rds-storage-type-required.rego | 65 + .../redis-instance-class-required.rego | 65 + .../slb-internet-charge-type-required.rego | 65 + ...cluster-node-pool-autoscaling-enabled.rego | 65 + ...ter-node-pool-scaling-limits-required.rego | 65 + ...alb-all-listener-health-check-enabled.rego | 21 + .../alb-all-listenter-has-server.rego | 65 + .../elasticity/elasticity-usage-guidelines.md | 22 + .../elasticity/ess-group-health-check.rego | 21 + ...ess-scaling-configuration-image-check.rego | 65 + ...ion-instance-type-candidates-required.rego | 65 + ...ess-scaling-group-attach-multi-switch.rego | 65 + ...caling-group-capacity-bounds-required.rego | 65 + ...ess-scaling-group-cooldown-configured.rego | 65 + .../ess-scaling-rule-action-configured.rego | 65 + ...ction-instance-concurrency-configured.rego | 65 + .../fc-function-timeout-configured.rego | 65 + ...-cluster-high-availability-configured.rego | 65 + ...slb-all-listener-health-check-enabled.rego | 65 + .../alb-instance-multi-zone.rego | 72 + ...cs-instance-group-max-amount-required.rego | 66 + ...cs-instance-group-min-amount-required.rego | 66 + ...ling-group-multi-vswitch-distribution.rego | 67 + .../high-availability-usage-guidelines.md | 22 + .../mongodb-instance-multi-zone.rego | 70 + .../nlb-loadbalancer-multi-zone.rego | 67 + .../high-availability/oss-zrs-enabled.rego | 67 + .../polardb-cluster-multi-zone.rego | 66 + .../rds-instance-secondary-zone-required.rego | 66 + .../rds-instance-zone-required.rego | 66 + .../redis-instance-multi-zone.rego | 66 + .../slb-instance-master-zone-required.rego | 66 + .../slb-instance-multi-zone.rego | 66 + .../infraguard-policies/lib/helpers.rego | 327 +++++ .../alb-address-type-intranet.rego | 65 + .../cen-instance-name-required.rego | 65 + .../eip-explicit-bandwidth-required.rego | 65 + .../nat-gateway-vpc-required.rego | 65 + .../network-architecture-usage-guidelines.md | 22 + .../nlb-address-type-intranet.rego | 65 + .../security-group-enterprise-type.rego | 65 + .../security-group-vpc-required.rego | 65 + .../slb-address-type-intranet.rego | 65 + ...nsit-router-vpc-attachment-multi-zone.rego | 65 + .../vpc-cidr-required.rego | 65 + .../vpn-gateway-vpc-required.rego | 65 + .../vswitch-cidr-required.rego | 65 + .../vswitch-zone-required.rego | 65 + .../actiontrail-trail-name-required.rego | 65 + .../operations/cms-alarm-name-required.rego | 65 + .../ecs-disk-auto-snapshot-policy.rego | 65 + ...tance-operational-deletion-protection.rego | 65 + .../operations/fc-service-log-enable.rego | 65 + .../operations/fc-service-tracing-enable.rego | 65 + .../operations/operations-usage-guidelines.md | 22 + ...oss-bucket-operational-access-logging.rego | 65 + ...rdb-cluster-delete-protection-enabled.rego | 65 + .../rds-backup-policy-required.rego | 65 + ...-instance-deletion-protection-enabled.rego | 65 + .../redis-backup-policy-required.rego | 65 + .../sls-logstore-shard-count-configured.rego | 65 + .../sls-logstore-ttl-configured.rego | 65 + ...loud-infrastructure-security-baseline.rego | 52 + .../packs/iac-code-best-practice-pack.rego | 40 + .../packs/iac-code-compliance-pack.rego | 40 + .../iac-code-cost-optimization-pack.rego | 40 + .../packs/iac-code-elasticity-pack.rego | 42 + .../iac-code-high-availability-pack.rego | 40 + .../iac-code-network-architecture-pack.rego | 40 + .../packs/iac-code-operations-pack.rego | 40 + .../packs/iac-code-security-pack.rego | 30 + .../ros/actiontrail-trail-intact-enabled.rego | 99 ++ .../ros/api-gateway-api-auth-required.rego | 60 + ...pi-gateway-api-internet-request-https.rego | 66 + .../cr-repository-image-scanning-enabled.rego | 63 + .../rules/ros/cr-repository-type-private.rego | 66 + .../ecs-running-instance-no-public-ip.rego | 67 + ...curity-group-not-internet-cidr-access.rego | 118 ++ ...group-risky-ports-check-with-protocol.rego | 150 +++ .../fc-service-internet-access-disable.rego | 63 + .../rules/ros/kms-key-rotation-enabled.rego | 66 + .../ros/kms-secret-rotation-enabled.rego | 66 + .../rules/ros/oss-bucket-logging-enabled.rego | 68 + .../ros/oss-bucket-only-https-enabled.rego | 98 ++ .../oss-bucket-public-read-prohibited.rego | 66 + .../oss-bucket-public-write-prohibited.rego | 66 + ...bucket-server-side-encryption-enabled.rego | 68 + .../rules/ros/ram-password-policy-check.rego | 68 + ...no-statements-with-admin-access-check.rego | 78 ++ .../rules/ros/ram-user-mfa-check.rego | 72 + .../rules/ros/rds-instance-enabled-ssl.rego | 62 + ...-instance-enabled-tde-disk-encryption.rego | 76 ++ ...ic-connection-and-any-ip-access-check.rego | 80 ++ .../rules/ros/redis-instance-enabled-ssl.rego | 62 + .../ros/redis-instance-no-public-ip.rego | 63 + .../rules/ros/vpc-flow-logs-enabled.rego | 63 + ...ecurity-api-gateway-api-auth-required.rego | 45 + .../security/security-ecs-disk-encrypted.rego | 45 + .../security-ecs-instance-no-public-ip.rego | 100 ++ ...-ecs-instance-security-group-required.rego | 45 + .../security-ecs-instance-vpc-required.rego | 45 + ...rity-oss-bucket-encryption-configured.rego | 45 + ...ecurity-oss-bucket-logging-configured.rego | 45 + .../security-oss-bucket-private-acl.rego | 45 + .../security-ram-user-mfa-required.rego | 45 + .../security-rds-instance-ssl-required.rego | 45 + .../security-rds-instance-tde-enabled.rego | 45 + .../security-rds-instance-vpc-required.rego | 45 + .../security-redis-instance-vpc-required.rego | 45 + .../infraguard-policy-generation.md | 190 +++ .../scripts/generate_infraguard_policies.py | 1153 +++++++++++++++++ tests/skills/bundled/test_iac_skill.py | 134 ++ tests/skills/test_auto_trigger.py | 20 + 159 files changed, 10969 insertions(+), 6 deletions(-) create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/README.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/alb-loadbalancer-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/best-practice-usage-guidelines.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-tags-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-security-group-description-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/kms-key-description-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/oss-bucket-tags-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/polardb-cluster-tags-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/rds-instance-tags-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/redis-instance-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/slb-loadbalancer-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/sls-project-description-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vpc-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vswitch-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/actiontrail-trail-intact-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/compliance-usage-guidelines.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ecs-instance-deletion-protection-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/kms-key-rotation-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/maxcompute-project-encryption-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/nas-filesystem-encrypt-type-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-logging-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-server-side-encryption-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/polardb-cluster-enabled-tde.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-password-policy-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-user-mfa-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-instance-enabled-log-backup.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-white-list-internet-ip-access-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/sls-project-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/cost-optimization-usage-guidelines.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-category-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-size-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-bandwidth-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-charge-type-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-type-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/eip-bandwidth-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/logstore-ttl-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/nat-gateway-spec-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/oss-storage-class-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-pay-type-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-storage-type-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/redis-instance-class-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/slb-internet-charge-type-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-autoscaling-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-scaling-limits-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listener-health-check-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listenter-has-server.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/elasticity-usage-guidelines.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-group-health-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-image-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-instance-type-candidates-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-attach-multi-switch.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-capacity-bounds-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-cooldown-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-rule-action-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-instance-concurrency-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-timeout-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/mse-cluster-high-availability-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/slb-all-listener-health-check-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/alb-instance-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-max-amount-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-min-amount-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ess-scaling-group-multi-vswitch-distribution.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/high-availability-usage-guidelines.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/mongodb-instance-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/nlb-loadbalancer-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/oss-zrs-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/polardb-cluster-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-secondary-zone-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-zone-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/redis-instance-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-master-zone-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/lib/helpers.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/alb-address-type-intranet.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/cen-instance-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/eip-explicit-bandwidth-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nat-gateway-vpc-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/network-architecture-usage-guidelines.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nlb-address-type-intranet.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-enterprise-type.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-vpc-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/slb-address-type-intranet.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/transit-router-vpc-attachment-multi-zone.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpc-cidr-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpn-gateway-vpc-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-cidr-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-zone-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/actiontrail-trail-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/cms-alarm-name-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-disk-auto-snapshot-policy.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-instance-operational-deletion-protection.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-log-enable.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-tracing-enable.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/operations-usage-guidelines.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/oss-bucket-operational-access-logging.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/polardb-cluster-delete-protection-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-backup-policy-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-instance-deletion-protection-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/redis-backup-policy-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-shard-count-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-ttl-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/cloud-infrastructure-security-baseline.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-best-practice-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-compliance-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-cost-optimization-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-elasticity-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-high-availability-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-network-architecture-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-operations-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-security-pack.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/actiontrail-trail-intact-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-auth-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-internet-request-https.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-image-scanning-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-type-private.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-running-instance-no-public-ip.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-not-internet-cidr-access.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-risky-ports-check-with-protocol.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/fc-service-internet-access-disable.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-key-rotation-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-secret-rotation-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-logging-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-only-https-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-read-prohibited.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-write-prohibited.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-server-side-encryption-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-password-policy-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-policy-no-statements-with-admin-access-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-user-mfa-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-ssl.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-tde-disk-encryption.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-public-connection-and-any-ip-access-check.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-enabled-ssl.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-no-public-ip.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/vpc-flow-logs-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-api-gateway-api-auth-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-disk-encrypted.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-no-public-ip.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-security-group-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-vpc-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-encryption-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-logging-configured.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-private-acl.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ram-user-mfa-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-ssl-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-tde-enabled.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-vpc-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-redis-instance-vpc-required.rego create mode 100644 src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policy-generation.md create mode 100644 src/iac_code/skills/bundled/iac_aliyun/scripts/generate_infraguard_policies.py diff --git a/.gitignore b/.gitignore index 0b7b890..106e62e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ downloads/ eggs/ .eggs/ lib/ +!src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/lib/ +!src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/lib/*.rego lib64/ parts/ sdist/ diff --git a/MANIFEST.in b/MANIFEST.in index fc35676..5624db9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,7 @@ include LICENSE include README.md include pyproject.toml -recursive-include src/iac_code *.yml *.yaml *.json *.md *.mo *.po +recursive-include src/iac_code *.yml *.yaml *.json *.md *.rego *.mo *.po prune tests prune htmlcov diff --git a/pyproject.toml b/pyproject.toml index 1173f8b..9ec4e8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,6 +91,7 @@ version = {attr = "iac_code.__version__"} "**/*.yaml", "**/*.json", "**/*.md", + "**/*.rego", "**/*.mo", "**/*.po", ] diff --git a/src/iac_code/skills/bundled/iac_aliyun/SKILL.md b/src/iac_code/skills/bundled/iac_aliyun/SKILL.md index 0d217dd..0a86505 100644 --- a/src/iac_code/skills/bundled/iac_aliyun/SKILL.md +++ b/src/iac_code/skills/bundled/iac_aliyun/SKILL.md @@ -1,7 +1,7 @@ --- name: iac-aliyun -description: 阿里云 Alibaba Cloud ROS/Terraform IaC 模板生成、解释、完善、校验、询价与部署 -when_to_use: 当用户请求阿里云/Alibaba Cloud/Alicloud 的 ROS 模板、资源栈、Terraform alicloud provider 模板生成、解释、完善、校验、询价、部署、更新或删除时,必须先调用 skill 工具加载 iac-aliyun。 +description: 阿里云 Alibaba Cloud ROS/Terraform IaC 模板生成、解释、完善、校验、询价、部署与 InfraGuard 合规策略生成 +when_to_use: 当用户请求阿里云/Alibaba Cloud/Alicloud 的 ROS 模板、资源栈、Terraform alicloud provider 模板生成、解释、完善、校验、询价、部署、更新、删除,或 InfraGuard 合规策略生成时,必须先调用 skill 工具加载 iac-aliyun。 user_invocable: false auto_trigger: script: auto_trigger.py @@ -9,7 +9,7 @@ auto_trigger: # 阿里云 IaC 技能 -阿里云 IaC 模板生成、解释、完善与部署。帮助用户通过 ROS/Terraform 模板管理云资源。 +阿里云 IaC 模板生成、解释、完善与部署,以及 InfraGuard 合规策略生成。帮助用户通过 ROS/Terraform 模板管理云资源,并通过 InfraGuard 在部署前检查安全与合规要求。 ## 地域 @@ -52,6 +52,12 @@ auto_trigger: ### 询价 - 查询部署的预估价格 +### InfraGuard 合规策略生成 +- 用户要求“生成合规策略”“写 InfraGuard 规则”“用 Rego 检查模板”“策略校验”等时,按 [references/infraguard-policy-generation.md](references/infraguard-policy-generation.md) 执行。 +- 已生成的 InfraGuard 策略资产位于 [references/infraguard-policies/](references/infraguard-policies/),按场景目录组织。 +- 云基础设施安全基线策略优先使用 [references/infraguard-policies/packs/cloud-infrastructure-security-baseline.rego](references/infraguard-policies/packs/cloud-infrastructure-security-baseline.rego) 及 [references/infraguard-policies/rules/ros/](references/infraguard-policies/rules/ros/) 下的官方风格规则,规则依赖 [references/infraguard-policies/lib/helpers.rego](references/infraguard-policies/lib/helpers.rego)。 +- 需要自定义或组合策略时,先阅读 InfraGuard 策略生成参考,再读取相关场景下的策略资产。 + ## 参数化规则 生成模板时,以下属性**必须**定义为 Parameters(部署前通过 API 查询确定实际值): diff --git a/src/iac_code/skills/bundled/iac_aliyun/__init__.py b/src/iac_code/skills/bundled/iac_aliyun/__init__.py index 69752f4..bbfe963 100644 --- a/src/iac_code/skills/bundled/iac_aliyun/__init__.py +++ b/src/iac_code/skills/bundled/iac_aliyun/__init__.py @@ -8,11 +8,15 @@ def register_iac_aliyun_skill() -> None: register_bundled_skill( name="iac-aliyun", - description="阿里云 Alibaba Cloud ROS/Terraform IaC 模板生成、解释、完善、校验、询价与部署", + description=( + "阿里云 Alibaba Cloud ROS/Terraform IaC 模板生成、解释、完善、校验、询价、部署," + "以及 InfraGuard 合规策略生成" + ), prompt=(SKILL_DIR / "SKILL.md").read_text(encoding="utf-8"), when_to_use=( "当用户请求阿里云/Alibaba Cloud/Alicloud 的 ROS 模板、资源栈、Terraform alicloud provider " - "模板生成、解释、完善、校验、询价、部署、更新或删除时,必须先调用 skill 工具加载 iac-aliyun。" + "模板生成、解释、完善、校验、询价、部署、更新、删除,或 InfraGuard 合规策略生成时," + "必须先调用 skill 工具加载 iac-aliyun。" ), user_invocable=False, skill_root=str(SKILL_DIR), diff --git a/src/iac_code/skills/bundled/iac_aliyun/auto_trigger.py b/src/iac_code/skills/bundled/iac_aliyun/auto_trigger.py index a5cffba..2135693 100644 --- a/src/iac_code/skills/bundled/iac_aliyun/auto_trigger.py +++ b/src/iac_code/skills/bundled/iac_aliyun/auto_trigger.py @@ -19,6 +19,17 @@ r"alicloud\s+provider", r'provider\s+"alicloud"', r'resource\s+"alicloud_', + r"\binfraguard\b", + r"\becs\b", + r"\brds\b", + r"\boss\b", + r"\bvpc\b", + r"\bslb\b", + r"\balb\b", + r"\bnlb\b", + r"安全组", + r"负载均衡", + r"云资源", ] _ES_TEMPLATE_ACTIONS = r"genera|generar|crea|crear|despliega|desplegar|explica|explicar|valida|validar|mejora|mejorar" @@ -38,6 +49,10 @@ r"\bros[-\s]+template\b", r"\b(create|generate|write|deploy|explain|validate|improve|update|delete)\b.*\b(template|stack)\b", r"\b(template|stack)\b.*\b(create|generate|write|deploy|explain|validate|improve|update|delete)\b", + r"\b(generate|write|create|validate)\b.*\b(compliance\s+)?polic(y|ies)\b", + r"\b(compliance\s+)?polic(y|ies)\b.*\b(generate|write|create|validate)\b", + r"\brego\b", + r"\bpolicy\s+validate\b", r"ros\s*模[板版]", r"模板生成", r"模版生成", @@ -50,6 +65,13 @@ r"验证.*模[板版]", r"更新.*模[板版]", r"删除.*模[板版]", + r"合规策略", + r"策略生成", + r"生成.*策略", + r"编写.*策略", + r"写.*策略", + r"校验.*策略", + r"验证.*策略", r"资源栈", rf"部署.*({_ZH_IAC_NOUNS})", rf"({_ZH_IAC_NOUNS}).*部署", diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/README.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/README.md new file mode 100644 index 0000000..812e40c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/README.md @@ -0,0 +1,36 @@ +# InfraGuard Policy Catalog + +This directory contains generated InfraGuard Rego policies for the `iac-aliyun` skill. + +- Total Rego files: 141 +- Total rule policies: 131 +- Scenarios: 8 +- Scenario policy files: 106 +- Cloud infrastructure security baseline rules: 25 +- Packs: 9 (8 scenario packs + 1 cloud infrastructure security baseline pack) + +Scenario directories: + +- `security` - security controls (13 rules) +- `high-availability` - high availability controls (13 rules) +- `cost-optimization` - cost optimization controls (13 rules) +- `compliance` - compliance controls (13 rules) +- `best-practice` - best practice controls (13 rules) +- `operations` - operability controls (13 rules) +- `network-architecture` - network architecture controls (13 rules) +- `elasticity` - elasticity controls (15 rules) +- `packs` - one InfraGuard pack per scenario plus the cloud infrastructure security baseline pack +- `rules/ros` - cloud infrastructure security baseline rules +- `lib` - shared Rego helpers + +Regenerate with: + +```bash +python3 src/iac_code/skills/bundled/iac_aliyun/scripts/generate_infraguard_policies.py +``` + +Validate a policy when InfraGuard is installed: + +```bash +infraguard policy validate src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-no-public-ip.rego +``` diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/alb-loadbalancer-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/alb-loadbalancer-name-required.rego new file mode 100644 index 0000000..c01f7bf --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/alb-loadbalancer-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.alb_loadbalancer_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "alb-loadbalancer-name-required", + "severity": "medium", + "name": { + "en": "ALB must configure name", + "zh": "ALB 必须配置名称", + "ja": "ALB 必须配置名称", + "de": "ALB 必须配置名称", + "es": "ALB 必须配置名称", + "fr": "ALB 必须配置名称", + "pt": "ALB 必须配置名称" + }, + "description": { + "en": "Checks ALB must configure name", + "zh": "检查ALB 必须配置名称", + "ja": "检查ALB 必须配置名称", + "de": "检查ALB 必须配置名称", + "es": "检查ALB 必须配置名称", + "fr": "检查ALB 必须配置名称", + "pt": "检查ALB 必须配置名称" + }, + "reason": { + "en": "ALB must configure name is not satisfied.", + "zh": "ALB 必须配置名称未满足。", + "ja": "ALB 必须配置名称未满足。", + "de": "ALB 必须配置名称未满足。", + "es": "ALB 必须配置名称未满足。", + "fr": "ALB 必须配置名称未满足。", + "pt": "ALB 必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure LoadBalancerName on ALIYUN::ALB::LoadBalancer to satisfy the policy.", + "zh": "请在 ALIYUN::ALB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "ja": "请在 ALIYUN::ALB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "de": "请在 ALIYUN::ALB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "es": "请在 ALIYUN::ALB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "fr": "请在 ALIYUN::ALB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "pt": "请在 ALIYUN::ALB::LoadBalancer 上配置 LoadBalancerName 以满足策略。" + }, + "resource_types": ["ALIYUN::ALB::LoadBalancer"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ALB::LoadBalancer") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoadBalancerName"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "LoadBalancerName") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/best-practice-usage-guidelines.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/best-practice-usage-guidelines.md new file mode 100644 index 0000000..8e3cb86 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/best-practice-usage-guidelines.md @@ -0,0 +1,22 @@ +# Best Practice InfraGuard Usage Guidelines + +## Sources read + +- Local official InfraGuard repository: `/private/tmp/infraguard-official`. +- Alibaba Cloud ROS and Well-Architected official references for the scenario. +- Cross-cloud Well-Architected references were used as control-point background when available. + +## Write to Learn notes + +The scenario was reduced to static IaC checks only. Runtime metrics, billing history, incident evidence, and approval workflow evidence are kept out of Rego because they cannot be proven from a ROS template alone. + +## Engineer-facing guidelines + +- Prefer explicit resource intent over provider defaults. +- Make the policy failure point actionable through `violation_path`. +- Keep rule ids short and stable, without scenario prefixes. +- Keep exceptions outside Rego unless the exception is represented in the template itself. + +## Rego mapping + +The scenario pack in `../packs/iac-code-best-practice-pack.rego` lists the rule ids enforced for this scenario. Rules use `package infraguard.rules.aliyun.`, `rule_meta`, and `deny contains result if` in the official InfraGuard style. diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-name-required.rego new file mode 100644 index 0000000..d6a7078 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_instance_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-name-required", + "severity": "medium", + "name": { + "en": "ECS instance must configure name", + "zh": "ECS 实例必须配置名称", + "ja": "ECS 实例必须配置名称", + "de": "ECS 实例必须配置名称", + "es": "ECS 实例必须配置名称", + "fr": "ECS 实例必须配置名称", + "pt": "ECS 实例必须配置名称" + }, + "description": { + "en": "Checks ECS instance must configure name", + "zh": "检查ECS 实例必须配置名称", + "ja": "检查ECS 实例必须配置名称", + "de": "检查ECS 实例必须配置名称", + "es": "检查ECS 实例必须配置名称", + "fr": "检查ECS 实例必须配置名称", + "pt": "检查ECS 实例必须配置名称" + }, + "reason": { + "en": "ECS instance must configure name is not satisfied.", + "zh": "ECS 实例必须配置名称未满足。", + "ja": "ECS 实例必须配置名称未满足。", + "de": "ECS 实例必须配置名称未满足。", + "es": "ECS 实例必须配置名称未满足。", + "fr": "ECS 实例必须配置名称未满足。", + "pt": "ECS 实例必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure InstanceName on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 InstanceName 以满足策略。", + "ja": "请在 ALIYUN::ECS::Instance 上配置 InstanceName 以满足策略。", + "de": "请在 ALIYUN::ECS::Instance 上配置 InstanceName 以满足策略。", + "es": "请在 ALIYUN::ECS::Instance 上配置 InstanceName 以满足策略。", + "fr": "请在 ALIYUN::ECS::Instance 上配置 InstanceName 以满足策略。", + "pt": "请在 ALIYUN::ECS::Instance 上配置 InstanceName 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InstanceName"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InstanceName") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-tags-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-tags-required.rego new file mode 100644 index 0000000..469d988 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-instance-tags-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_instance_tags_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-tags-required", + "severity": "medium", + "name": { + "en": "ECS instance must configure tags", + "zh": "ECS 实例必须配置标签", + "ja": "ECS 实例必须配置标签", + "de": "ECS 实例必须配置标签", + "es": "ECS 实例必须配置标签", + "fr": "ECS 实例必须配置标签", + "pt": "ECS 实例必须配置标签" + }, + "description": { + "en": "Checks ECS instance must configure tags", + "zh": "检查ECS 实例必须配置标签", + "ja": "检查ECS 实例必须配置标签", + "de": "检查ECS 实例必须配置标签", + "es": "检查ECS 实例必须配置标签", + "fr": "检查ECS 实例必须配置标签", + "pt": "检查ECS 实例必须配置标签" + }, + "reason": { + "en": "ECS instance must configure tags is not satisfied.", + "zh": "ECS 实例必须配置标签未满足。", + "ja": "ECS 实例必须配置标签未满足。", + "de": "ECS 实例必须配置标签未满足。", + "es": "ECS 实例必须配置标签未满足。", + "fr": "ECS 实例必须配置标签未满足。", + "pt": "ECS 实例必须配置标签未满足。" + }, + "recommendation": { + "en": "Configure Tags on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 Tags 以满足策略。", + "ja": "请在 ALIYUN::ECS::Instance 上配置 Tags 以满足策略。", + "de": "请在 ALIYUN::ECS::Instance 上配置 Tags 以满足策略。", + "es": "请在 ALIYUN::ECS::Instance 上配置 Tags 以满足策略。", + "fr": "请在 ALIYUN::ECS::Instance 上配置 Tags 以满足策略。", + "pt": "请在 ALIYUN::ECS::Instance 上配置 Tags 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Tags"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Tags") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-security-group-description-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-security-group-description-required.rego new file mode 100644 index 0000000..deeb962 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/ecs-security-group-description-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_security_group_description_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-security-group-description-required", + "severity": "medium", + "name": { + "en": "Security group must configure description", + "zh": "安全组必须配置描述", + "ja": "安全组必须配置描述", + "de": "安全组必须配置描述", + "es": "安全组必须配置描述", + "fr": "安全组必须配置描述", + "pt": "安全组必须配置描述" + }, + "description": { + "en": "Checks Security group must configure description", + "zh": "检查安全组必须配置描述", + "ja": "检查安全组必须配置描述", + "de": "检查安全组必须配置描述", + "es": "检查安全组必须配置描述", + "fr": "检查安全组必须配置描述", + "pt": "检查安全组必须配置描述" + }, + "reason": { + "en": "Security group must configure description is not satisfied.", + "zh": "安全组必须配置描述未满足。", + "ja": "安全组必须配置描述未满足。", + "de": "安全组必须配置描述未满足。", + "es": "安全组必须配置描述未满足。", + "fr": "安全组必须配置描述未满足。", + "pt": "安全组必须配置描述未满足。" + }, + "recommendation": { + "en": "Configure Description on ALIYUN::ECS::SecurityGroup to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::SecurityGroup 上配置 Description 以满足策略。", + "ja": "请在 ALIYUN::ECS::SecurityGroup 上配置 Description 以满足策略。", + "de": "请在 ALIYUN::ECS::SecurityGroup 上配置 Description 以满足策略。", + "es": "请在 ALIYUN::ECS::SecurityGroup 上配置 Description 以满足策略。", + "fr": "请在 ALIYUN::ECS::SecurityGroup 上配置 Description 以满足策略。", + "pt": "请在 ALIYUN::ECS::SecurityGroup 上配置 Description 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::SecurityGroup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Description"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Description") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/kms-key-description-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/kms-key-description-required.rego new file mode 100644 index 0000000..90200b1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/kms-key-description-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.kms_key_description_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "kms-key-description-required", + "severity": "medium", + "name": { + "en": "KMS key must configure description", + "zh": "KMS 密钥必须配置描述", + "ja": "KMS 密钥必须配置描述", + "de": "KMS 密钥必须配置描述", + "es": "KMS 密钥必须配置描述", + "fr": "KMS 密钥必须配置描述", + "pt": "KMS 密钥必须配置描述" + }, + "description": { + "en": "Checks KMS key must configure description", + "zh": "检查KMS 密钥必须配置描述", + "ja": "检查KMS 密钥必须配置描述", + "de": "检查KMS 密钥必须配置描述", + "es": "检查KMS 密钥必须配置描述", + "fr": "检查KMS 密钥必须配置描述", + "pt": "检查KMS 密钥必须配置描述" + }, + "reason": { + "en": "KMS key must configure description is not satisfied.", + "zh": "KMS 密钥必须配置描述未满足。", + "ja": "KMS 密钥必须配置描述未满足。", + "de": "KMS 密钥必须配置描述未满足。", + "es": "KMS 密钥必须配置描述未满足。", + "fr": "KMS 密钥必须配置描述未满足。", + "pt": "KMS 密钥必须配置描述未满足。" + }, + "recommendation": { + "en": "Configure Description on ALIYUN::KMS::Key to satisfy the policy.", + "zh": "请在 ALIYUN::KMS::Key 上配置 Description 以满足策略。", + "ja": "请在 ALIYUN::KMS::Key 上配置 Description 以满足策略。", + "de": "请在 ALIYUN::KMS::Key 上配置 Description 以满足策略。", + "es": "请在 ALIYUN::KMS::Key 上配置 Description 以满足策略。", + "fr": "请在 ALIYUN::KMS::Key 上配置 Description 以满足策略。", + "pt": "请在 ALIYUN::KMS::Key 上配置 Description 以满足策略。" + }, + "resource_types": ["ALIYUN::KMS::Key"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::KMS::Key") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Description"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Description") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/oss-bucket-tags-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/oss-bucket-tags-required.rego new file mode 100644 index 0000000..c34ebbd --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/oss-bucket-tags-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.oss_bucket_tags_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-tags-required", + "severity": "medium", + "name": { + "en": "OSS bucket must configure tags", + "zh": "OSS Bucket 必须配置标签", + "ja": "OSS Bucket 必须配置标签", + "de": "OSS Bucket 必须配置标签", + "es": "OSS Bucket 必须配置标签", + "fr": "OSS Bucket 必须配置标签", + "pt": "OSS Bucket 必须配置标签" + }, + "description": { + "en": "Checks OSS bucket must configure tags", + "zh": "检查OSS Bucket 必须配置标签", + "ja": "检查OSS Bucket 必须配置标签", + "de": "检查OSS Bucket 必须配置标签", + "es": "检查OSS Bucket 必须配置标签", + "fr": "检查OSS Bucket 必须配置标签", + "pt": "检查OSS Bucket 必须配置标签" + }, + "reason": { + "en": "OSS bucket must configure tags is not satisfied.", + "zh": "OSS Bucket 必须配置标签未满足。", + "ja": "OSS Bucket 必须配置标签未满足。", + "de": "OSS Bucket 必须配置标签未满足。", + "es": "OSS Bucket 必须配置标签未满足。", + "fr": "OSS Bucket 必须配置标签未满足。", + "pt": "OSS Bucket 必须配置标签未满足。" + }, + "recommendation": { + "en": "Configure Tags on ALIYUN::OSS::Bucket to satisfy the policy.", + "zh": "请在 ALIYUN::OSS::Bucket 上配置 Tags 以满足策略。", + "ja": "请在 ALIYUN::OSS::Bucket 上配置 Tags 以满足策略。", + "de": "请在 ALIYUN::OSS::Bucket 上配置 Tags 以满足策略。", + "es": "请在 ALIYUN::OSS::Bucket 上配置 Tags 以满足策略。", + "fr": "请在 ALIYUN::OSS::Bucket 上配置 Tags 以满足策略。", + "pt": "请在 ALIYUN::OSS::Bucket 上配置 Tags 以满足策略。" + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Tags"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Tags") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/polardb-cluster-tags-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/polardb-cluster-tags-required.rego new file mode 100644 index 0000000..9e1ab49 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/polardb-cluster-tags-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.polardb_cluster_tags_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "polardb-cluster-tags-required", + "severity": "medium", + "name": { + "en": "PolarDB cluster must configure tags", + "zh": "PolarDB 集群必须配置标签", + "ja": "PolarDB 集群必须配置标签", + "de": "PolarDB 集群必须配置标签", + "es": "PolarDB 集群必须配置标签", + "fr": "PolarDB 集群必须配置标签", + "pt": "PolarDB 集群必须配置标签" + }, + "description": { + "en": "Checks PolarDB cluster must configure tags", + "zh": "检查PolarDB 集群必须配置标签", + "ja": "检查PolarDB 集群必须配置标签", + "de": "检查PolarDB 集群必须配置标签", + "es": "检查PolarDB 集群必须配置标签", + "fr": "检查PolarDB 集群必须配置标签", + "pt": "检查PolarDB 集群必须配置标签" + }, + "reason": { + "en": "PolarDB cluster must configure tags is not satisfied.", + "zh": "PolarDB 集群必须配置标签未满足。", + "ja": "PolarDB 集群必须配置标签未满足。", + "de": "PolarDB 集群必须配置标签未满足。", + "es": "PolarDB 集群必须配置标签未满足。", + "fr": "PolarDB 集群必须配置标签未满足。", + "pt": "PolarDB 集群必须配置标签未满足。" + }, + "recommendation": { + "en": "Configure Tags on ALIYUN::POLARDB::DBCluster to satisfy the policy.", + "zh": "请在 ALIYUN::POLARDB::DBCluster 上配置 Tags 以满足策略。", + "ja": "请在 ALIYUN::POLARDB::DBCluster 上配置 Tags 以满足策略。", + "de": "请在 ALIYUN::POLARDB::DBCluster 上配置 Tags 以满足策略。", + "es": "请在 ALIYUN::POLARDB::DBCluster 上配置 Tags 以满足策略。", + "fr": "请在 ALIYUN::POLARDB::DBCluster 上配置 Tags 以满足策略。", + "pt": "请在 ALIYUN::POLARDB::DBCluster 上配置 Tags 以满足策略。" + }, + "resource_types": ["ALIYUN::POLARDB::DBCluster"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::POLARDB::DBCluster") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Tags"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Tags") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/rds-instance-tags-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/rds-instance-tags-required.rego new file mode 100644 index 0000000..5e218df --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/rds-instance-tags-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.rds_instance_tags_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "rds-instance-tags-required", + "severity": "medium", + "name": { + "en": "RDS instance must configure tags", + "zh": "RDS 实例必须配置标签", + "ja": "RDS 实例必须配置标签", + "de": "RDS 实例必须配置标签", + "es": "RDS 实例必须配置标签", + "fr": "RDS 实例必须配置标签", + "pt": "RDS 实例必须配置标签" + }, + "description": { + "en": "Checks RDS instance must configure tags", + "zh": "检查RDS 实例必须配置标签", + "ja": "检查RDS 实例必须配置标签", + "de": "检查RDS 实例必须配置标签", + "es": "检查RDS 实例必须配置标签", + "fr": "检查RDS 实例必须配置标签", + "pt": "检查RDS 实例必须配置标签" + }, + "reason": { + "en": "RDS instance must configure tags is not satisfied.", + "zh": "RDS 实例必须配置标签未满足。", + "ja": "RDS 实例必须配置标签未满足。", + "de": "RDS 实例必须配置标签未满足。", + "es": "RDS 实例必须配置标签未满足。", + "fr": "RDS 实例必须配置标签未满足。", + "pt": "RDS 实例必须配置标签未满足。" + }, + "recommendation": { + "en": "Configure Tags on ALIYUN::RDS::DBInstance to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::DBInstance 上配置 Tags 以满足策略。", + "ja": "请在 ALIYUN::RDS::DBInstance 上配置 Tags 以满足策略。", + "de": "请在 ALIYUN::RDS::DBInstance 上配置 Tags 以满足策略。", + "es": "请在 ALIYUN::RDS::DBInstance 上配置 Tags 以满足策略。", + "fr": "请在 ALIYUN::RDS::DBInstance 上配置 Tags 以满足策略。", + "pt": "请在 ALIYUN::RDS::DBInstance 上配置 Tags 以满足策略。" + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Tags"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Tags") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/redis-instance-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/redis-instance-name-required.rego new file mode 100644 index 0000000..2c75fdc --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/redis-instance-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.redis_instance_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "redis-instance-name-required", + "severity": "medium", + "name": { + "en": "Redis instance must configure name", + "zh": "Redis 实例必须配置名称", + "ja": "Redis 实例必须配置名称", + "de": "Redis 实例必须配置名称", + "es": "Redis 实例必须配置名称", + "fr": "Redis 实例必须配置名称", + "pt": "Redis 实例必须配置名称" + }, + "description": { + "en": "Checks Redis instance must configure name", + "zh": "检查Redis 实例必须配置名称", + "ja": "检查Redis 实例必须配置名称", + "de": "检查Redis 实例必须配置名称", + "es": "检查Redis 实例必须配置名称", + "fr": "检查Redis 实例必须配置名称", + "pt": "检查Redis 实例必须配置名称" + }, + "reason": { + "en": "Redis instance must configure name is not satisfied.", + "zh": "Redis 实例必须配置名称未满足。", + "ja": "Redis 实例必须配置名称未满足。", + "de": "Redis 实例必须配置名称未满足。", + "es": "Redis 实例必须配置名称未满足。", + "fr": "Redis 实例必须配置名称未满足。", + "pt": "Redis 实例必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure InstanceName on ALIYUN::REDIS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::REDIS::Instance 上配置 InstanceName 以满足策略。", + "ja": "请在 ALIYUN::REDIS::Instance 上配置 InstanceName 以满足策略。", + "de": "请在 ALIYUN::REDIS::Instance 上配置 InstanceName 以满足策略。", + "es": "请在 ALIYUN::REDIS::Instance 上配置 InstanceName 以满足策略。", + "fr": "请在 ALIYUN::REDIS::Instance 上配置 InstanceName 以满足策略。", + "pt": "请在 ALIYUN::REDIS::Instance 上配置 InstanceName 以满足策略。" + }, + "resource_types": ["ALIYUN::REDIS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::REDIS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InstanceName"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InstanceName") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/slb-loadbalancer-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/slb-loadbalancer-name-required.rego new file mode 100644 index 0000000..33a4045 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/slb-loadbalancer-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.slb_loadbalancer_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "slb-loadbalancer-name-required", + "severity": "medium", + "name": { + "en": "SLB must configure name", + "zh": "SLB 必须配置名称", + "ja": "SLB 必须配置名称", + "de": "SLB 必须配置名称", + "es": "SLB 必须配置名称", + "fr": "SLB 必须配置名称", + "pt": "SLB 必须配置名称" + }, + "description": { + "en": "Checks SLB must configure name", + "zh": "检查SLB 必须配置名称", + "ja": "检查SLB 必须配置名称", + "de": "检查SLB 必须配置名称", + "es": "检查SLB 必须配置名称", + "fr": "检查SLB 必须配置名称", + "pt": "检查SLB 必须配置名称" + }, + "reason": { + "en": "SLB must configure name is not satisfied.", + "zh": "SLB 必须配置名称未满足。", + "ja": "SLB 必须配置名称未满足。", + "de": "SLB 必须配置名称未满足。", + "es": "SLB 必须配置名称未满足。", + "fr": "SLB 必须配置名称未满足。", + "pt": "SLB 必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure LoadBalancerName on ALIYUN::SLB::LoadBalancer to satisfy the policy.", + "zh": "请在 ALIYUN::SLB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "ja": "请在 ALIYUN::SLB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "de": "请在 ALIYUN::SLB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "es": "请在 ALIYUN::SLB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "fr": "请在 ALIYUN::SLB::LoadBalancer 上配置 LoadBalancerName 以满足策略。", + "pt": "请在 ALIYUN::SLB::LoadBalancer 上配置 LoadBalancerName 以满足策略。" + }, + "resource_types": ["ALIYUN::SLB::LoadBalancer"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLB::LoadBalancer") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoadBalancerName"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "LoadBalancerName") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/sls-project-description-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/sls-project-description-required.rego new file mode 100644 index 0000000..fc10b5f --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/sls-project-description-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.sls_project_description_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "sls-project-description-required", + "severity": "medium", + "name": { + "en": "SLS project must configure description", + "zh": "SLS Project 必须配置描述", + "ja": "SLS Project 必须配置描述", + "de": "SLS Project 必须配置描述", + "es": "SLS Project 必须配置描述", + "fr": "SLS Project 必须配置描述", + "pt": "SLS Project 必须配置描述" + }, + "description": { + "en": "Checks SLS project must configure description", + "zh": "检查SLS Project 必须配置描述", + "ja": "检查SLS Project 必须配置描述", + "de": "检查SLS Project 必须配置描述", + "es": "检查SLS Project 必须配置描述", + "fr": "检查SLS Project 必须配置描述", + "pt": "检查SLS Project 必须配置描述" + }, + "reason": { + "en": "SLS project must configure description is not satisfied.", + "zh": "SLS Project 必须配置描述未满足。", + "ja": "SLS Project 必须配置描述未满足。", + "de": "SLS Project 必须配置描述未满足。", + "es": "SLS Project 必须配置描述未满足。", + "fr": "SLS Project 必须配置描述未满足。", + "pt": "SLS Project 必须配置描述未满足。" + }, + "recommendation": { + "en": "Configure Description on ALIYUN::SLS::Project to satisfy the policy.", + "zh": "请在 ALIYUN::SLS::Project 上配置 Description 以满足策略。", + "ja": "请在 ALIYUN::SLS::Project 上配置 Description 以满足策略。", + "de": "请在 ALIYUN::SLS::Project 上配置 Description 以满足策略。", + "es": "请在 ALIYUN::SLS::Project 上配置 Description 以满足策略。", + "fr": "请在 ALIYUN::SLS::Project 上配置 Description 以满足策略。", + "pt": "请在 ALIYUN::SLS::Project 上配置 Description 以满足策略。" + }, + "resource_types": ["ALIYUN::SLS::Project"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLS::Project") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Description"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Description") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vpc-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vpc-name-required.rego new file mode 100644 index 0000000..6339142 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vpc-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.vpc_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "vpc-name-required", + "severity": "medium", + "name": { + "en": "VPC must configure name", + "zh": "VPC 必须配置名称", + "ja": "VPC 必须配置名称", + "de": "VPC 必须配置名称", + "es": "VPC 必须配置名称", + "fr": "VPC 必须配置名称", + "pt": "VPC 必须配置名称" + }, + "description": { + "en": "Checks VPC must configure name", + "zh": "检查VPC 必须配置名称", + "ja": "检查VPC 必须配置名称", + "de": "检查VPC 必须配置名称", + "es": "检查VPC 必须配置名称", + "fr": "检查VPC 必须配置名称", + "pt": "检查VPC 必须配置名称" + }, + "reason": { + "en": "VPC must configure name is not satisfied.", + "zh": "VPC 必须配置名称未满足。", + "ja": "VPC 必须配置名称未满足。", + "de": "VPC 必须配置名称未满足。", + "es": "VPC 必须配置名称未满足。", + "fr": "VPC 必须配置名称未满足。", + "pt": "VPC 必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure VpcName on ALIYUN::ECS::VPC to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::VPC 上配置 VpcName 以满足策略。", + "ja": "请在 ALIYUN::ECS::VPC 上配置 VpcName 以满足策略。", + "de": "请在 ALIYUN::ECS::VPC 上配置 VpcName 以满足策略。", + "es": "请在 ALIYUN::ECS::VPC 上配置 VpcName 以满足策略。", + "fr": "请在 ALIYUN::ECS::VPC 上配置 VpcName 以满足策略。", + "pt": "请在 ALIYUN::ECS::VPC 上配置 VpcName 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::VPC"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::VPC") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VpcName"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VpcName") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vswitch-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vswitch-name-required.rego new file mode 100644 index 0000000..77e6e28 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/best-practice/vswitch-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.vswitch_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "vswitch-name-required", + "severity": "medium", + "name": { + "en": "VSwitch must configure name", + "zh": "交换机必须配置名称", + "ja": "交换机必须配置名称", + "de": "交换机必须配置名称", + "es": "交换机必须配置名称", + "fr": "交换机必须配置名称", + "pt": "交换机必须配置名称" + }, + "description": { + "en": "Checks VSwitch must configure name", + "zh": "检查交换机必须配置名称", + "ja": "检查交换机必须配置名称", + "de": "检查交换机必须配置名称", + "es": "检查交换机必须配置名称", + "fr": "检查交换机必须配置名称", + "pt": "检查交换机必须配置名称" + }, + "reason": { + "en": "VSwitch must configure name is not satisfied.", + "zh": "交换机必须配置名称未满足。", + "ja": "交换机必须配置名称未满足。", + "de": "交换机必须配置名称未满足。", + "es": "交换机必须配置名称未满足。", + "fr": "交换机必须配置名称未满足。", + "pt": "交换机必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure VSwitchName on ALIYUN::ECS::VSwitch to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::VSwitch 上配置 VSwitchName 以满足策略。", + "ja": "请在 ALIYUN::ECS::VSwitch 上配置 VSwitchName 以满足策略。", + "de": "请在 ALIYUN::ECS::VSwitch 上配置 VSwitchName 以满足策略。", + "es": "请在 ALIYUN::ECS::VSwitch 上配置 VSwitchName 以满足策略。", + "fr": "请在 ALIYUN::ECS::VSwitch 上配置 VSwitchName 以满足策略。", + "pt": "请在 ALIYUN::ECS::VSwitch 上配置 VSwitchName 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::VSwitch"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::VSwitch") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VSwitchName"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VSwitchName") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/actiontrail-trail-intact-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/actiontrail-trail-intact-enabled.rego new file mode 100644 index 0000000..1ea5e28 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/actiontrail-trail-intact-enabled.rego @@ -0,0 +1,91 @@ +package infraguard.rules.aliyun.actiontrail_trail_intact_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "actiontrail-trail-intact-enabled", + "severity": "high", + "name": { + "en": "ActionTrail Trail Intact Enabled", + "zh": "开启操作审计全量日志跟踪", + "ja": "ActionTrail トレイルが完全に有効", + "de": "ActionTrail Trail vollständig aktiviert", + "es": "Trilha ActionTrail Intacta Habilitada", + "fr": "Piste ActionTrail Intacte Activée", + "pt": "Trilha ActionTrail Intacta Habilitada" + }, + "description": { + "en": "ActionTrail trail should be enabled and track all event types (Read and Write).", + "zh": "操作审计中存在开启状态的跟踪,且跟踪全部地域和全部事件类型。", + "ja": "ActionTrail トレイルを有効にし、すべてのイベントタイプ(読み取りと書き込み)を追跡する必要があります。", + "de": "ActionTrail Trail sollte aktiviert sein und alle Ereignistypen (Lesen und Schreiben) verfolgen.", + "es": "La trilha ActionTrail debe estar habilitada y rastrear todos los tipos de eventos (Lectura y Escritura).", + "fr": "La piste ActionTrail doit être activée et suivre tous les types d'événements (Lecture et Écriture).", + "pt": "A trilha ActionTrail deve estar habilitada e rastrear todos os tipos de eventos (Leitura e Escrita)." + }, + "reason": { + "en": "The ActionTrail trail is not enabled or does not track all event types.", + "zh": "操作审计跟踪未开启或未跟踪所有事件类型。", + "ja": "ActionTrail トレイルが有効になっていないか、すべてのイベントタイプを追跡していません。", + "de": "Der ActionTrail Trail ist nicht aktiviert oder verfolgt nicht alle Ereignistypen.", + "es": "La trilha ActionTrail no está habilitada o no rastrea todos los tipos de eventos.", + "fr": "La piste ActionTrail n'est pas activée ou ne suit pas tous les types d'événements.", + "pt": "A trilha ActionTrail não está habilitada ou não rastreia todos os tipos de eventos." + }, + "recommendation": { + "en": "Enable the trail using ALIYUN::ACTIONTRAIL::TrailLogging and set EventRW to All in ALIYUN::ACTIONTRAIL::Trail.", + "zh": "使用 ALIYUN::ACTIONTRAIL::TrailLogging 启用跟踪,并在 ALIYUN::ACTIONTRAIL::Trail 中将 EventRW 设置为 All。", + "ja": "ALIYUN::ACTIONTRAIL::TrailLogging を使用してトレイルを有効にし、ALIYUN::ACTIONTRAIL::Trail で EventRW を All に設定します。", + "de": "Aktivieren Sie den Trail mit ALIYUN::ACTIONTRAIL::TrailLogging und setzen Sie EventRW in ALIYUN::ACTIONTRAIL::Trail auf All.", + "es": "Habilite la trilha usando ALIYUN::ACTIONTRAIL::TrailLogging y establezca EventRW en All en ALIYUN::ACTIONTRAIL::Trail.", + "fr": "Activez la piste en utilisant ALIYUN::ACTIONTRAIL::TrailLogging et définissez EventRW sur All dans ALIYUN::ACTIONTRAIL::Trail.", + "pt": "Habilite a trilha usando ALIYUN::ACTIONTRAIL::TrailLogging e defina EventRW como All em ALIYUN::ACTIONTRAIL::Trail." + }, + "resource_types": ["ALIYUN::ACTIONTRAIL::Trail"] +} + +# Get all enabled trail names from TrailLogging resources +enabled_trails := {name | + some logging in helpers.resources_by_type("ALIYUN::ACTIONTRAIL::TrailLogging") + helpers.get_property(logging, "Enable", false) == true + name := helpers.get_property(logging, "Name", "") + name != "" +} + +# Check if a trail is enabled (referenced by an enabled TrailLogging) +is_trail_enabled(trail_name) if { + trail_name in enabled_trails +} + +# Check if trail tracks all events +is_track_all_events(resource) if { + helpers.get_property(resource, "EventRW", "Write") == "All" +} + +deny contains result if { + some name, resource in helpers.resources_by_types(rule_meta.resource_types) + + # Get the trail name (either property Name or resource name if not set?) + # Trail Name property is required. + trail_name := helpers.get_property(resource, "Name", "") + + not is_compliant(trail_name, resource) + + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "EventRW"], # Approximate path + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(trail_name, resource) if { + is_track_all_events(resource) + is_trail_enabled(trail_name) +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/compliance-usage-guidelines.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/compliance-usage-guidelines.md new file mode 100644 index 0000000..83de3c6 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/compliance-usage-guidelines.md @@ -0,0 +1,22 @@ +# Compliance InfraGuard Usage Guidelines + +## Sources read + +- Local official InfraGuard repository: `/private/tmp/infraguard-official`. +- Alibaba Cloud ROS and Well-Architected official references for the scenario. +- Cross-cloud Well-Architected references were used as control-point background when available. + +## Write to Learn notes + +The scenario was reduced to static IaC checks only. Runtime metrics, billing history, incident evidence, and approval workflow evidence are kept out of Rego because they cannot be proven from a ROS template alone. + +## Engineer-facing guidelines + +- Prefer explicit resource intent over provider defaults. +- Make the policy failure point actionable through `violation_path`. +- Keep rule ids short and stable, without scenario prefixes. +- Keep exceptions outside Rego unless the exception is represented in the template itself. + +## Rego mapping + +The scenario pack in `../packs/iac-code-compliance-pack.rego` lists the rule ids enforced for this scenario. Rules use `package infraguard.rules.aliyun.`, `rule_meta`, and `deny contains result if` in the official InfraGuard style. diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ecs-instance-deletion-protection-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ecs-instance-deletion-protection-enabled.rego new file mode 100644 index 0000000..2463eb3 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ecs-instance-deletion-protection-enabled.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.ecs_instance_deletion_protection_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-deletion-protection-enabled", + "severity": "high", + "name": { + "en": "ECS Instance Deletion Protection Enabled", + "zh": "ECS 实例开启释放保护", + "ja": "ECS インスタンスの削除保護が有効", + "de": "ECS-Instanz Löschschutz aktiviert", + "es": "Protección de Eliminación de Instancia ECS Habilitada", + "fr": "Protection contre la Suppression d'Instance ECS Activée", + "pt": "Proteção contra Exclusão de Instância ECS Habilitada" + }, + "description": { + "en": "Ensures that ECS instances have deletion protection enabled.", + "zh": "确保 ECS 实例开启了释放保护。", + "ja": "ECS インスタンスで削除保護が有効になっていることを確認します。", + "de": "Stellt sicher, dass ECS-Instanzen Löschschutz aktiviert haben.", + "es": "Asegura que las instancias ECS tengan habilitada la protección contra eliminación.", + "fr": "Garantit que les instances ECS ont la protection contre la suppression activée.", + "pt": "Garante que as instâncias ECS tenham proteção contra exclusão habilitada." + }, + "reason": { + "en": "If deletion protection is not enabled, the instance may be released accidentally, causing service interruption or data loss.", + "zh": "如果未开启释放保护,实例可能会被意外释放,导致业务中断或数据丢失。", + "ja": "削除保護が有効になっていない場合、インスタンスが誤って解放され、サービス中断やデータ損失が発生する可能性があります。", + "de": "Wenn der Löschschutz nicht aktiviert ist, kann die Instanz versehentlich freigegeben werden, was zu Dienstunterbrechungen oder Datenverlust führt.", + "es": "Si la protección contra eliminación no está habilitada, la instancia puede ser liberada accidentalmente, causando interrupción del servicio o pérdida de datos.", + "fr": "Si la protection contre la suppression n'est pas activée, l'instance peut être libérée accidentellement, provoquant une interruption de service ou une perte de données.", + "pt": "Se a proteção contra exclusão não estiver habilitada, a instância pode ser liberada acidentalmente, causando interrupção do serviço ou perda de dados." + }, + "recommendation": { + "en": "Enable deletion protection for the ECS instance.", + "zh": "为 ECS 实例开启释放保护功能。", + "ja": "ECS インスタンスで削除保護を有効にします。", + "de": "Aktivieren Sie den Löschschutz für die ECS-Instanz.", + "es": "Habilite la protección contra eliminación para la instancia ECS.", + "fr": "Activez la protection contre la suppression pour l'instance ECS.", + "pt": "Habilite proteção contra exclusão para a instância ECS." + }, + "resource_types": ["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"] +} + +is_compliant(resource) if { + helpers.is_true(helpers.get_property(resource, "DeletionProtection", false)) +} + +deny contains result if { + some name, resource in helpers.resources_by_types(["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"]) + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DeletionProtection"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/kms-key-rotation-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/kms-key-rotation-enabled.rego new file mode 100644 index 0000000..8e92ee8 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/kms-key-rotation-enabled.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.kms_key_rotation_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "kms-key-rotation-enabled", + "severity": "medium", + "name": { + "en": "KMS key automatic rotation enabled", + "zh": "密钥管理服务设置主密钥自动轮转", + "ja": "KMS キーの自動ローテーションが有効", + "de": "KMS-Schlüssel automatische Rotation aktiviert", + "es": "Rotación automática de clave KMS habilitada", + "fr": "Rotation automatique de clé KMS activée", + "pt": "Rotação automática de chave KMS habilitada" + }, + "description": { + "en": "KMS user master key has automatic rotation enabled, considered compliant. Service keys and externally imported keys are not applicable.", + "zh": "对密钥管理服务中的用户主密钥设置自动轮转,视为合规。如果是服务密钥,视为不适用。如果来源是用户自带密钥,视为不适用。", + "ja": "KMS ユーザーマスターキーで自動ローテーションが有効になっている場合、準拠と見なされます。サービスキーと外部からインポートされたキーは適用されません。", + "de": "KMS-Benutzer-Hauptschlüssel hat automatische Rotation aktiviert, wird als konform betrachtet. Dienstschlüssel und extern importierte Schlüssel sind nicht anwendbar.", + "es": "La clave maestra de usuario KMS tiene rotación automática habilitada, considerada conforme. Las claves de servicio y las claves importadas externamente no son aplicables.", + "fr": "La clé maître utilisateur KMS a la rotation automatique activée, considérée comme conforme. Les clés de service et les clés importées externement ne sont pas applicables.", + "pt": "Chave mestra de usuário KMS tem rotação automática habilitada, considerada conforme. Chaves de serviço e chaves importadas externamente não são aplicáveis." + }, + "reason": { + "en": "KMS key does not have automatic rotation enabled", + "zh": "KMS 主密钥未开启自动轮转", + "ja": "KMS キーで自動ローテーションが有効になっていません", + "de": "KMS-Schlüssel hat keine automatische Rotation aktiviert", + "es": "La clave KMS no tiene rotación automática habilitada", + "fr": "La clé KMS n'a pas la rotation automatique activée", + "pt": "Chave KMS não tem rotação automática habilitada" + }, + "recommendation": { + "en": "Enable automatic rotation for KMS key to enhance security by regularly rotating encryption keys", + "zh": "为 KMS 主密钥启用自动轮转以通过定期轮换加密密钥来增强安全性", + "ja": "暗号化キーを定期的にローテーションしてセキュリティを強化するために、KMS キーで自動ローテーションを有効にします", + "de": "Aktivieren Sie die automatische Rotation für KMS-Schlüssel, um die Sicherheit durch regelmäßige Rotation von Verschlüsselungsschlüsseln zu verbessern", + "es": "Habilite la rotación automática para la clave KMS para mejorar la seguridad rotando claves de cifrado regularmente", + "fr": "Activez la rotation automatique pour la clé KMS pour améliorer la sécurité en faisant tourner régulièrement les clés de chiffrement", + "pt": "Habilite rotação automática para chave KMS para melhorar a segurança rotacionando chaves de criptografia regularmente" + }, + "resource_types": ["ALIYUN::KMS::Key"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::KMS::Key") + + # Check if EnableAutomaticRotation is enabled + rotation_enabled := helpers.get_property(resource, "EnableAutomaticRotation", false) + not helpers.is_true(rotation_enabled) + + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/maxcompute-project-encryption-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/maxcompute-project-encryption-enabled.rego new file mode 100644 index 0000000..1f14c93 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/maxcompute-project-encryption-enabled.rego @@ -0,0 +1,67 @@ +package infraguard.rules.aliyun.maxcompute_project_encryption_enabled + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "maxcompute-project-encryption-enabled", + "severity": "high", + "name": { + "en": "MaxCompute Project Encryption Enabled", + "zh": "MaxCompute 项目开启加密", + "ja": "MaxCompute プロジェクト暗号化が有効", + "de": "MaxCompute-Projekt Verschlüsselung aktiviert", + "es": "Cifrado de Proyecto MaxCompute Habilitado", + "fr": "Chiffrement de Projet MaxCompute Activé", + "pt": "Criptografia de Projeto MaxCompute Habilitada" + }, + "description": { + "en": "Ensures MaxCompute projects have encryption enabled to protect stored data.", + "zh": "确保 MaxCompute 项目启用了加密以保护存储的数据。", + "ja": "MaxCompute プロジェクトで保存データを保護するために暗号化が有効になっていることを確認します。", + "de": "Stellt sicher, dass MaxCompute-Projekte Verschlüsselung aktiviert haben, um gespeicherte Daten zu schützen.", + "es": "Garantiza que los proyectos MaxCompute tengan cifrado habilitado para proteger los datos almacenados.", + "fr": "Garantit que les projets MaxCompute ont le chiffrement activé pour protéger les données stockées.", + "pt": "Garante que os projetos MaxCompute tenham criptografia habilitada para proteger dados armazenados." + }, + "reason": { + "en": "Encryption protects sensitive data stored in MaxCompute projects from unauthorized access.", + "zh": "加密可以保护 MaxCompute 项目中存储的敏感数据免受非授权访问。", + "ja": "暗号化により、MaxCompute プロジェクトに保存されている機密データが不正アクセスから保護されます。", + "de": "Verschlüsselung schützt sensible Daten, die in MaxCompute-Projekten gespeichert sind, vor unbefugtem Zugriff.", + "es": "El cifrado protege los datos sensibles almacenados en proyectos MaxCompute del acceso no autorizado.", + "fr": "Le chiffrement protège les données sensibles stockées dans les projets MaxCompute contre l'accès non autorisé.", + "pt": "A criptografia protege dados sensíveis armazenados em projetos MaxCompute contra acesso não autorizado." + }, + "recommendation": { + "en": "Enable encryption for the MaxCompute project.", + "zh": "为 MaxCompute 项目启用加密。", + "ja": "MaxCompute プロジェクトの暗号化を有効にします。", + "de": "Aktivieren Sie die Verschlüsselung für das MaxCompute-Projekt.", + "es": "Habilite el cifrado para el proyecto MaxCompute.", + "fr": "Activez le chiffrement pour le projet MaxCompute.", + "pt": "Habilite a criptografia para o projeto MaxCompute." + }, + "resource_types": ["ALIYUN::MaxCompute::Project"] +} + +# Check if encryption is enabled +is_compliant(resource) if { + # Direct access to nested properties + props := resource.Properties.Properties + props != null + encryption := props.Encryption + encryption != null + encryption.Enable == true +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::MaxCompute::Project") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Encryption", "Enable"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/nas-filesystem-encrypt-type-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/nas-filesystem-encrypt-type-check.rego new file mode 100644 index 0000000..e24f003 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/nas-filesystem-encrypt-type-check.rego @@ -0,0 +1,72 @@ +package infraguard.rules.aliyun.nas_filesystem_encrypt_type_check + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "nas-filesystem-encrypt-type-check", + "severity": "low", + "name": { + "en": "NAS file system encryption configured", + "zh": "NAS 文件系统设置了加密", + "ja": "NAS ファイルシステムの暗号化が設定されている", + "de": "NAS-Dateisystem-Verschlüsselung konfiguriert", + "es": "Cifrado de Sistema de Archivos NAS Configurado", + "fr": "Chiffrement du Système de Fichiers NAS Configuré", + "pt": "Criptografia do Sistema de Arquivos NAS Configurada" + }, + "description": { + "en": "NAS file system has encryption configured, considered compliant.", + "zh": "NAS 文件系统设置了加密,视为合规。", + "ja": "NAS ファイルシステムに暗号化が設定されており、準拠と見なされます。", + "de": "NAS-Dateisystem hat Verschlüsselung konfiguriert, gilt als konform.", + "es": "El sistema de archivos NAS tiene cifrado configurado, se considera conforme.", + "fr": "Le système de fichiers NAS a le chiffrement configuré, considéré comme conforme.", + "pt": "O sistema de arquivos NAS tem criptografia configurada, considerado em conformidade." + }, + "reason": { + "en": "NAS file system does not have encryption configured", + "zh": "NAS 文件系统未设置加密", + "ja": "NAS ファイルシステムに暗号化が設定されていません", + "de": "NAS-Dateisystem hat keine Verschlüsselung konfiguriert", + "es": "El sistema de archivos NAS no tiene cifrado configurado", + "fr": "Le système de fichiers NAS n'a pas de chiffrement configuré", + "pt": "O sistema de arquivos NAS não tem criptografia configurada" + }, + "recommendation": { + "en": "Configure encryption for NAS file system to protect data at rest using KMS keys", + "zh": "为 NAS 文件系统配置加密以使用 KMS 密钥保护静态数据", + "ja": "KMS キーを使用して保存データを保護するために、NAS ファイルシステムの暗号化を設定します", + "de": "Konfigurieren Sie Verschlüsselung für das NAS-Dateisystem, um Daten im Ruhezustand mit KMS-Schlüsseln zu schützen", + "es": "Configure el cifrado para el sistema de archivos NAS para proteger los datos en reposo usando claves KMS", + "fr": "Configurez le chiffrement pour le système de fichiers NAS pour protéger les données au repos à l'aide de clés KMS", + "pt": "Configure a criptografia para o sistema de arquivos NAS para proteger dados em repouso usando chaves KMS" + }, + "resource_types": ["ALIYUN::NAS::FileSystem"] +} + +is_encrypted(resource) if { + encrypt_type := helpers.get_property(resource, "EncryptType", 0) + encrypt_type == 1 +} + +is_encrypted(resource) if { + encrypt_type := helpers.get_property(resource, "EncryptType", 0) + encrypt_type == 2 +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::NAS::FileSystem") + not is_encrypted(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-logging-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-logging-enabled.rego new file mode 100644 index 0000000..3df34e5 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-logging-enabled.rego @@ -0,0 +1,68 @@ +package infraguard.rules.aliyun.oss_bucket_logging_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-logging-enabled", + "severity": "medium", + "name": { + "en": "OSS Bucket Logging Enabled", + "zh": "OSS 存储空间开启日志转存", + "ja": "OSS バケットのログ記録が有効", + "de": "OSS-Bucket Protokollierung aktiviert", + "es": "Registro de Logs de Bucket OSS Habilitado", + "fr": "Journalisation de Bucket OSS Activée", + "pt": "Registro de Logs de Bucket OSS Habilitado" + }, + "description": { + "en": "OSS buckets should have logging enabled to track access and operations. Logging helps with security auditing, troubleshooting, and compliance requirements.", + "zh": "OSS 存储空间应开启日志转存以跟踪访问和操作。日志记录有助于安全审计、故障排查和合规要求。", + "ja": "OSS バケットは、アクセスと操作を追跡するためにログ記録を有効にする必要があります。ログ記録は、セキュリティ監査、トラブルシューティング、コンプライアンス要件に役立ちます。", + "de": "OSS-Buckets sollten Protokollierung aktiviert haben, um Zugriffe und Vorgänge zu verfolgen. Die Protokollierung hilft bei Sicherheitsaudits, Fehlerbehebung und Compliance-Anforderungen.", + "es": "Los buckets OSS deben tener registro de logs habilitado para rastrear acceso y operaciones. El registro de logs ayuda en la auditoría de seguridad, solución de problemas y requisitos de conformidad.", + "fr": "Les buckets OSS doivent avoir la journalisation activée pour suivre les accès et les opérations. La journalisation aide à l'audit de sécurité, au dépannage et aux exigences de conformité.", + "pt": "Buckets OSS devem ter registro de logs habilitado para rastrear acesso e operações. O registro de logs ajuda na auditoria de segurança, solução de problemas e requisitos de conformidade." + }, + "reason": { + "en": "The OSS bucket does not have logging enabled, which makes it difficult to track access and operations for security and compliance purposes.", + "zh": "OSS 存储空间未开启日志转存,难以跟踪访问和操作以满足安全和合规要求。", + "ja": "OSS バケットでログ記録が有効になっていないため、セキュリティとコンプライアンスの目的でアクセスと操作を追跡することが困難です。", + "de": "Der OSS-Bucket hat keine Protokollierung aktiviert, was es schwierig macht, Zugriffe und Vorgänge für Sicherheits- und Compliance-Zwecke zu verfolgen.", + "es": "El bucket OSS no tiene registro de logs habilitado, lo que dificulta rastrear acceso y operaciones para fines de seguridad y conformidad.", + "fr": "Le bucket OSS n'a pas la journalisation activée, ce qui rend difficile le suivi des accès et des opérations à des fins de sécurité et de conformité.", + "pt": "O bucket OSS não tem registro de logs habilitado, o que dificulta rastrear acesso e operações para fins de segurança e conformidade." + }, + "recommendation": { + "en": "Enable logging for the OSS bucket by configuring the LoggingConfiguration property with TargetBucket and optionally TargetPrefix.", + "zh": "通过配置 LoggingConfiguration 属性并设置 TargetBucket 和可选的 TargetPrefix,为 OSS 存储空间启用日志转存。", + "ja": "TargetBucket とオプションで TargetPrefix を使用して LoggingConfiguration プロパティを設定することで、OSS バケットのログ記録を有効にします。", + "de": "Aktivieren Sie die Protokollierung für den OSS-Bucket, indem Sie die LoggingConfiguration-Eigenschaft mit TargetBucket und optional TargetPrefix konfigurieren.", + "es": "Habilite el registro de logs para el bucket OSS configurando la propiedad LoggingConfiguration con TargetBucket y opcionalmente TargetPrefix.", + "fr": "Activez la journalisation pour le bucket OSS en configurant la propriété LoggingConfiguration avec TargetBucket et éventuellement TargetPrefix.", + "pt": "Habilite registro de logs para o bucket OSS configurando a propriedade LoggingConfiguration com TargetBucket e opcionalmente TargetPrefix." + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not has_logging_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoggingConfiguration"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +has_logging_enabled(resource) if { + helpers.has_property(resource, "LoggingConfiguration") + logging_config := resource.Properties.LoggingConfiguration + logging_config.TargetBucket != null +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-server-side-encryption-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-server-side-encryption-enabled.rego new file mode 100644 index 0000000..a5ab22c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/oss-bucket-server-side-encryption-enabled.rego @@ -0,0 +1,68 @@ +package infraguard.rules.aliyun.oss_bucket_server_side_encryption_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-server-side-encryption-enabled", + "severity": "high", + "name": { + "en": "OSS Bucket Server-Side Encryption Enabled", + "zh": "OSS 存储空间开启服务端加密", + "ja": "OSS バケットのサーバー側暗号化が有効", + "de": "OSS-Bucket-Serverseitige-Verschlüsselung aktiviert", + "es": "Cifrado del Lado del Servidor de Bucket OSS Habilitado", + "fr": "Chiffrement Côté Serveur de Bucket OSS Activé", + "pt": "Criptografia do Lado do Servidor de Bucket OSS Habilitada" + }, + "description": { + "en": "OSS buckets should have server-side encryption enabled to protect data at rest. Server-side encryption uses KMS or AES256 to encrypt data stored in OSS.", + "zh": "OSS 存储空间应开启服务端加密以保护静态数据。服务端加密使用 KMS 或 AES256 对存储在 OSS 中的数据进行加密。", + "ja": "OSS バケットは、保存データを保護するためにサーバー側暗号化を有効にする必要があります。サーバー側暗号化は KMS または AES256 を使用して OSS に保存されたデータを暗号化します。", + "de": "OSS-Buckets sollten serverseitige Verschlüsselung aktiviert haben, um ruhende Daten zu schützen. Die serverseitige Verschlüsselung verwendet KMS oder AES256, um in OSS gespeicherte Daten zu verschlüsseln.", + "es": "Los buckets OSS deben tener cifrado del lado del servidor habilitado para proteger los datos en reposo. El cifrado del lado del servidor usa KMS o AES256 para cifrar datos almacenados en OSS.", + "fr": "Les buckets OSS doivent avoir le chiffrement côté serveur activé pour protéger les données au repos. Le chiffrement côté serveur utilise KMS ou AES256 pour chiffrer les données stockées dans OSS.", + "pt": "Buckets OSS devem ter criptografia do lado do servidor habilitada para proteger dados em repouso. A criptografia do lado do servidor usa KMS ou AES256 para criptografar dados armazenados no OSS." + }, + "reason": { + "en": "The OSS bucket does not have server-side encryption enabled, which may expose sensitive data to unauthorized access.", + "zh": "OSS 存储空间未开启服务端加密,可能导致敏感数据暴露给未授权访问。", + "ja": "OSS バケットでサーバー側暗号化が有効になっていないため、機密データが不正アクセスにさらされる可能性があります。", + "de": "Der OSS-Bucket hat keine serverseitige Verschlüsselung aktiviert, was sensible Daten unbefugtem Zugriff aussetzen kann.", + "es": "El bucket OSS no tiene cifrado del lado del servidor habilitado, lo que puede exponer datos sensibles a acceso no autorizado.", + "fr": "Le bucket OSS n'a pas le chiffrement côté serveur activé, ce qui peut exposer des données sensibles à un accès non autorisé.", + "pt": "O bucket OSS não tem criptografia do lado do servidor habilitada, o que pode expor dados sensíveis a acesso não autorizado." + }, + "recommendation": { + "en": "Enable server-side encryption for the OSS bucket by configuring the ServerSideEncryptionConfiguration property with SSEAlgorithm set to KMS, AES256, or SM4.", + "zh": "通过配置 ServerSideEncryptionConfiguration 属性并将 SSEAlgorithm 设置为 KMS、AES256 或 SM4,为 OSS 存储空间启用服务端加密。", + "ja": "SSEAlgorithm を KMS、AES256、または SM4 に設定して ServerSideEncryptionConfiguration プロパティを設定することで、OSS バケットのサーバー側暗号化を有効にします。", + "de": "Aktivieren Sie die serverseitige Verschlüsselung für den OSS-Bucket, indem Sie die ServerSideEncryptionConfiguration-Eigenschaft mit SSEAlgorithm auf KMS, AES256 oder SM4 konfigurieren.", + "es": "Habilite el cifrado del lado del servidor para el bucket OSS configurando la propiedad ServerSideEncryptionConfiguration con SSEAlgorithm establecido en KMS, AES256 o SM4.", + "fr": "Activez le chiffrement côté serveur pour le bucket OSS en configurant la propriété ServerSideEncryptionConfiguration avec SSEAlgorithm défini sur KMS, AES256 ou SM4.", + "pt": "Habilite criptografia do lado do servidor para o bucket OSS configurando a propriedade ServerSideEncryptionConfiguration com SSEAlgorithm definido como KMS, AES256 ou SM4." + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not has_server_side_encryption(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ServerSideEncryptionConfiguration"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +has_server_side_encryption(resource) if { + helpers.has_property(resource, "ServerSideEncryptionConfiguration") + sse_config := resource.Properties.ServerSideEncryptionConfiguration + sse_config.SSEAlgorithm in ["KMS", "AES256", "SM4"] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/polardb-cluster-enabled-tde.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/polardb-cluster-enabled-tde.rego new file mode 100644 index 0000000..3b0f577 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/polardb-cluster-enabled-tde.rego @@ -0,0 +1,61 @@ +package infraguard.rules.aliyun.polardb_cluster_enabled_tde + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "polardb-cluster-enabled-tde", + "severity": "high", + "name": { + "en": "PolarDB Cluster TDE Enabled", + "zh": "PolarDB 集群开启 TDE", + "ja": "PolarDB クラスタで TDE が有効", + "de": "PolarDB-Cluster TDE aktiviert", + "es": "TDE de Cluster PolarDB Habilitado", + "fr": "TDE du Cluster PolarDB Activé", + "pt": "TDE de Cluster PolarDB Habilitado" + }, + "description": { + "en": "Ensures PolarDB clusters have Transparent Data Encryption (TDE) enabled.", + "zh": "确保 PolarDB 集群开启了透明数据加密(TDE)。", + "ja": "PolarDB クラスタで透過的データ暗号化(TDE)が有効になっていることを確認します。", + "de": "Stellt sicher, dass PolarDB-Cluster Transparent Data Encryption (TDE) aktiviert haben.", + "es": "Garantiza que los clústeres PolarDB tengan Transparent Data Encryption (TDE) habilitado.", + "fr": "Garantit que les clusters PolarDB ont Transparent Data Encryption (TDE) activé.", + "pt": "Garante que os clusters PolarDB tenham Transparent Data Encryption (TDE) habilitado." + }, + "reason": { + "en": "TDE provides data-at-rest encryption for sensitive data stored in the database.", + "zh": "TDE 为存储在数据库中的敏感数据提供静态数据加密。", + "ja": "TDE は、データベースに保存されている機密データに対して保存データ暗号化を提供します。", + "de": "TDE bietet Verschlüsselung ruhender Daten für sensible Daten, die in der Datenbank gespeichert sind.", + "es": "TDE proporciona cifrado de datos en reposo para datos sensibles almacenados en la base de datos.", + "fr": "TDE fournit le chiffrement des données au repos pour les données sensibles stockées dans la base de données.", + "pt": "O TDE fornece criptografia de dados em repouso para dados sensíveis armazenados no banco de dados." + }, + "recommendation": { + "en": "Enable TDE for the PolarDB cluster.", + "zh": "为 PolarDB 集群开启 TDE。", + "ja": "PolarDB クラスタで TDE を有効にします。", + "de": "Aktivieren Sie TDE für den PolarDB-Cluster.", + "es": "Habilite TDE para el clúster PolarDB.", + "fr": "Activez TDE pour le cluster PolarDB.", + "pt": "Habilite TDE para o cluster PolarDB." + }, + "resource_types": ["ALIYUN::POLARDB::DBCluster"] +} + +is_compliant(resource) if { + helpers.get_property(resource, "TDEStatus", "Disabled") == "Enabled" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::POLARDB::DBCluster") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "TDEStatus"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-password-policy-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-password-policy-check.rego new file mode 100644 index 0000000..4e25ff1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-password-policy-check.rego @@ -0,0 +1,68 @@ +package infraguard.rules.aliyun.ram_password_policy_check + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata +rule_meta := { + "id": "ram-password-policy-check", + "severity": "medium", + "name": { + "en": "RAM Password Policy Check", + "zh": "RAM 密码策略检测", + "ja": "RAM パスワードポリシーチェック", + "de": "RAM-Passwortrichtlinien-Prüfung", + "es": "Verificación de Política de Contraseña RAM", + "fr": "Vérification de la Politique de Mot de Passe RAM", + "pt": "Verificação de Política de Senha RAM" + }, + "description": { + "en": "Ensures that the RAM password policy meets the specified security requirements.", + "zh": "确保 RAM 密码策略符合指定的安全要求。", + "ja": "RAM パスワードポリシーが指定されたセキュリティ要件を満たしていることを確認します。", + "de": "Stellt sicher, dass die RAM-Passwortrichtlinie die festgelegten Sicherheitsanforderungen erfüllt.", + "es": "Garantiza que la política de contraseña RAM cumpla con los requisitos de seguridad especificados.", + "fr": "Garantit que la politique de mot de passe RAM répond aux exigences de sécurité spécifiées.", + "pt": "Garante que a política de senha RAM atenda aos requisitos de segurança especificados." + }, + "reason": { + "en": "Strong password policies help prevent unauthorized access to accounts.", + "zh": "强密码策略有助于防止对账号的未经授权访问。", + "ja": "強力なパスワードポリシーは、アカウントへの不正アクセスを防ぐのに役立ちます。", + "de": "Starke Passwortrichtlinien helfen, unbefugten Zugriff auf Konten zu verhindern.", + "es": "Las políticas de contraseña fuertes ayudan a prevenir el acceso no autorizado a las cuentas.", + "fr": "Des politiques de mot de passe fortes aident à prévenir l'accès non autorisé aux comptes.", + "pt": "Políticas de senha fortes ajudam a prevenir acesso não autorizado a contas." + }, + "recommendation": { + "en": "Configure a strong RAM password policy including length, character types, and rotation.", + "zh": "配置强 RAM 密码策略,包括长度、字符类型和定期轮换。", + "ja": "長さ、文字タイプ、ローテーションを含む強力な RAM パスワードポリシーを設定します。", + "de": "Konfigurieren Sie eine starke RAM-Passwortrichtlinie, einschließlich Länge, Zeichentypen und Rotation.", + "es": "Configure una política de contraseña RAM fuerte que incluya longitud, tipos de caracteres y rotación.", + "fr": "Configurez une politique de mot de passe RAM forte incluant la longueur, les types de caractères et la rotation.", + "pt": "Configure uma política de senha RAM forte incluindo comprimento, tipos de caracteres e rotação." + }, + "resource_types": ["ALIYUN::RAM::PasswordPolicy"] +} + +# This rule typically checks RAM::PasswordPolicy resources +# Since a ROS template might not have this, we check it if it exists. +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RAM::PasswordPolicy") + + # Logic to check properties like MinimumPasswordLength + props := resource.Properties + not props.MinimumPasswordLength >= 8 + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MinimumPasswordLength"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-user-mfa-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-user-mfa-check.rego new file mode 100644 index 0000000..89ac9a8 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/ram-user-mfa-check.rego @@ -0,0 +1,72 @@ +package infraguard.rules.aliyun.ram_user_mfa_check + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ram-user-mfa-check", + "severity": "high", + "name": { + "en": "RAM User MFA Enabled", + "zh": "RAM 用户开启 MFA", + "ja": "RAM ユーザーで MFA が有効", + "de": "RAM-Benutzer MFA aktiviert", + "es": "MFA de Usuario RAM Habilitado", + "fr": "MFA Utilisateur RAM Activé", + "pt": "MFA de Usuário RAM Habilitado" + }, + "description": { + "en": "RAM users with console access should have multi-factor authentication (MFA) enabled.", + "zh": "检测 RAM 用户是否开通 MFA 二次验证登录,开通视为合规。", + "ja": "コンソールアクセスを持つ RAM ユーザーは、多要素認証(MFA)を有効にする必要があります。", + "de": "RAM-Benutzer mit Konsolenzugriff sollten Multi-Faktor-Authentifizierung (MFA) aktiviert haben.", + "es": "Los usuarios RAM con acceso a la consola deben tener habilitada la autenticación multifactor (MFA).", + "fr": "Les utilisateurs RAM avec accès à la console doivent avoir l'authentification multifacteur (MFA) activée.", + "pt": "Usuários RAM com acesso ao console devem ter autenticação multifator (MFA) habilitada." + }, + "reason": { + "en": "RAM users without MFA are vulnerable to password compromise, posing a significant security risk.", + "zh": "RAM 用户未开启 MFA,一旦密码泄露,账号将面临极大的安全风险。", + "ja": "MFA がない RAM ユーザーはパスワードの侵害に対して脆弱で、重大なセキュリティリスクをもたらします。", + "de": "RAM-Benutzer ohne MFA sind anfällig für Passwortkompromittierung und stellen ein erhebliches Sicherheitsrisiko dar.", + "es": "Los usuarios RAM sin MFA son vulnerables al compromiso de contraseñas, lo que plantea un riesgo de seguridad significativo.", + "fr": "Les utilisateurs RAM sans MFA sont vulnérables au compromis de mot de passe, ce qui pose un risque de sécurité important.", + "pt": "Usuários RAM sem MFA são vulneráveis a comprometimento de senha, representando um risco significativo de segurança." + }, + "recommendation": { + "en": "Enable MFA for the RAM user by setting LoginProfile.MFABindRequired to true.", + "zh": "通过将 LoginProfile.MFABindRequired 设置为 true 为 RAM 用户强制开启 MFA。", + "ja": "LoginProfile.MFABindRequired を true に設定して、RAM ユーザーで MFA を有効にします。", + "de": "Aktivieren Sie MFA für den RAM-Benutzer, indem Sie LoginProfile.MFABindRequired auf true setzen.", + "es": "Habilite MFA para el usuario RAM estableciendo LoginProfile.MFABindRequired en true.", + "fr": "Activez MFA pour l'utilisateur RAM en définissant LoginProfile.MFABindRequired sur true.", + "pt": "Habilite MFA para o usuário RAM definindo LoginProfile.MFABindRequired como true." + }, + "resource_types": ["ALIYUN::RAM::User"] +} + +# Check if MFA is required for login +is_mfa_enabled(resource) if { + login_profile := helpers.get_property(resource, "LoginProfile", {}) + mfa := object.get(login_profile, "MFABindRequired", false) + helpers.is_true(mfa) +} + +deny contains result if { + some name, resource in helpers.resources_by_types(rule_meta.resource_types) + + # Only check users who have console access (LoginProfile exists) + helpers.has_property(resource, "LoginProfile") + not is_mfa_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoginProfile", "MFABindRequired"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-instance-enabled-log-backup.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-instance-enabled-log-backup.rego new file mode 100644 index 0000000..3eb4b69 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-instance-enabled-log-backup.rego @@ -0,0 +1,61 @@ +package infraguard.rules.aliyun.rds_instance_enabled_log_backup + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "rds-instance-enabled-log-backup", + "severity": "medium", + "name": { + "en": "RDS Instance Log Backup Enabled", + "zh": "RDS 实例开启日志备份", + "ja": "RDS インスタンスでログバックアップが有効", + "de": "RDS-Instanz Log-Backup aktiviert", + "es": "Backup de Log de Instancia RDS Habilitado", + "fr": "Sauvegarde de Journal d'Instance RDS Activée", + "pt": "Backup de Log de Instância RDS Habilitado" + }, + "description": { + "en": "Ensures RDS instances have log backup enabled.", + "zh": "确保 RDS 实例开启了日志备份。", + "ja": "RDS インスタンスでログバックアップが有効になっていることを確認します。", + "de": "Stellt sicher, dass RDS-Instanzen Log-Backup aktiviert haben.", + "es": "Garantiza que las instancias RDS tengan backup de log habilitado.", + "fr": "Garantit que les instances RDS ont la sauvegarde de journal activée.", + "pt": "Garante que as instâncias RDS tenham backup de log habilitado." + }, + "reason": { + "en": "Log backups are essential for point-in-time recovery of the database.", + "zh": "日志备份对于数据库的增量恢复(Point-in-time recovery)至关重要。", + "ja": "ログバックアップは、データベースのポイントインタイムリカバリに不可欠です。", + "de": "Log-Backups sind für die Point-in-Time-Wiederherstellung der Datenbank unerlässlich.", + "es": "Los backups de log son esenciales para la recuperación puntual de la base de datos.", + "fr": "Les sauvegardes de journal sont essentielles pour la récupération ponctuelle de la base de données.", + "pt": "Backups de log são essenciais para recuperação pontual do banco de dados." + }, + "recommendation": { + "en": "Enable log backup in the RDS backup policy.", + "zh": "在 RDS 备份策略中开启日志备份。", + "ja": "RDS バックアップポリシーでログバックアップを有効にします。", + "de": "Aktivieren Sie Log-Backup in der RDS-Backup-Richtlinie.", + "es": "Habilite backup de log en la política de backup RDS.", + "fr": "Activez la sauvegarde de journal dans la politique de sauvegarde RDS.", + "pt": "Habilite backup de log na política de backup RDS." + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +is_compliant(resource) if { + helpers.is_true(helpers.get_property(resource, "EnableBackupLog", false)) +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "EnableBackupLog"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-white-list-internet-ip-access-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-white-list-internet-ip-access-check.rego new file mode 100644 index 0000000..575a17d --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/rds-white-list-internet-ip-access-check.rego @@ -0,0 +1,68 @@ +package infraguard.rules.aliyun.rds_white_list_internet_ip_access_check + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "rds-white-list-internet-ip-access-check", + "severity": "high", + "name": { + "en": "RDS Whitelist Internet Restriction", + "zh": "RDS 白名单禁用公网开放", + "ja": "RDS ホワイトリストインターネット制限", + "de": "RDS-Whitelist Internet-Einschränkung", + "es": "Restricción de Internet de Lista Blanca RDS", + "fr": "Restriction Internet de Liste Blanche RDS", + "pt": "Restrição de Internet da Lista Branca RDS" + }, + "description": { + "en": "Ensures RDS security IP whitelists do not contain 0.0.0.0/0.", + "zh": "确保 RDS 安全 IP 白名单中不包含 0.0.0.0/0。", + "ja": "RDS セキュリティ IP ホワイトリストに 0.0.0.0/0 が含まれていないことを確認します。", + "de": "Stellt sicher, dass RDS-Sicherheits-IP-Whitelists 0.0.0.0/0 nicht enthalten.", + "es": "Garantiza que las listas blancas de IP de seguridad RDS no contengan 0.0.0.0/0.", + "fr": "Garantit que les listes blanches d'IP de sécurité RDS ne contiennent pas 0.0.0.0/0.", + "pt": "Garante que as listas brancas de IP de segurança RDS não contenham 0.0.0.0/0." + }, + "reason": { + "en": "Allowing 0.0.0.0/0 in the whitelist exposes the database to all public internet traffic.", + "zh": "在白名单中允许 0.0.0.0/0 会使数据库暴露给所有的公网流量。", + "ja": "ホワイトリストで 0.0.0.0/0 を許可すると、データベースがすべてのパブリックインターネットトラフィックにさらされます。", + "de": "Das Zulassen von 0.0.0.0/0 in der Whitelist setzt die Datenbank dem gesamten öffentlichen Internetverkehr aus.", + "es": "Permitir 0.0.0.0/0 en la lista blanca expone la base de datos a todo el tráfico público de Internet.", + "fr": "Autoriser 0.0.0.0/0 dans la liste blanche expose la base de données à tout le trafic Internet public.", + "pt": "Permitir 0.0.0.0/0 na lista branca expõe o banco de dados a todo o tráfego público da Internet." + }, + "recommendation": { + "en": "Remove 0.0.0.0/0 from the RDS security IP list and use specific trusted IPs.", + "zh": "从 RDS 安全 IP 列表中移除 0.0.0.0/0,并使用特定的可信 IP。", + "ja": "RDS セキュリティ IP リストから 0.0.0.0/0 を削除し、特定の信頼できる IP を使用します。", + "de": "Entfernen Sie 0.0.0.0/0 aus der RDS-Sicherheits-IP-Liste und verwenden Sie spezifische vertrauenswürdige IPs.", + "es": "Elimine 0.0.0.0/0 de la lista de IP de seguridad RDS y use IPs confiables específicas.", + "fr": "Supprimez 0.0.0.0/0 de la liste d'IP de sécurité RDS et utilisez des IP de confiance spécifiques.", + "pt": "Remova 0.0.0.0/0 da lista de IP de segurança RDS e use IPs confiáveis específicos." + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +is_compliant(resource) if { + whitelist_str := helpers.get_property(resource, "SecurityIPList", "") + whitelist := split(whitelist_str, ",") + not has_public_ip(whitelist) +} + +has_public_ip(whitelist) if { + some ip in whitelist + helpers.is_public_cidr(trim_space(ip)) +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SecurityIPList"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/sls-project-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/sls-project-multi-zone.rego new file mode 100644 index 0000000..f32bdcf --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/compliance/sls-project-multi-zone.rego @@ -0,0 +1,70 @@ +package infraguard.rules.aliyun.sls_project_multi_zone + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata +rule_meta := { + "id": "sls-project-multi-zone", + "severity": "medium", + "name": { + "en": "SLS Project Zone-Redundant Storage", + "zh": "SLS 项目使用同城冗余存储", + "ja": "SLS プロジェクトゾーン冗長ストレージ", + "de": "SLS-Projekt Zonenredundanter Speicher", + "es": "Almacenamiento Redundante de Zona del Proyecto SLS", + "fr": "Stockage Redondant par Zone du Projet SLS", + "pt": "Armazenamento Redundante de Zona do Projeto SLS" + }, + "description": { + "en": "SLS projects should use zone-redundant storage (ZRS) for high availability and data durability.", + "zh": "SLS 项目应使用同城冗余存储(ZRS)以实现高可用性和数据持久性。", + "ja": "SLS プロジェクトは、高可用性とデータの耐久性のためにゾーン冗長ストレージ(ZRS)を使用する必要があります。", + "de": "SLS-Projekte sollten zonenredundanten Speicher (ZRS) für Hochverfügbarkeit und Datenbeständigkeit verwenden.", + "es": "Los proyectos SLS deben usar almacenamiento redundante de zona (ZRS) para alta disponibilidad y durabilidad de datos.", + "fr": "Les projets SLS doivent utiliser un stockage redondant par zone (ZRS) pour une haute disponibilité et une durabilité des données.", + "pt": "Os projetos SLS devem usar armazenamento redundante de zona (ZRS) para alta disponibilidade e durabilidade dos dados." + }, + "reason": { + "en": "The SLS project does not use zone-redundant storage, which may affect data availability.", + "zh": "SLS 项目未使用同城冗余存储,可能影响数据可用性。", + "ja": "SLS プロジェクトがゾーン冗長ストレージを使用していないため、データの可用性に影響を与える可能性があります。", + "de": "Das SLS-Projekt verwendet keinen zonenredundanten Speicher, was die Datenverfügbarkeit beeinträchtigen kann.", + "es": "El proyecto SLS no usa almacenamiento redundante de zona, lo que puede afectar la disponibilidad de datos.", + "fr": "Le projet SLS n'utilise pas de stockage redondant par zone, ce qui peut affecter la disponibilité des données.", + "pt": "O projeto SLS não usa armazenamento redundante de zona, o que pode afetar a disponibilidade dos dados." + }, + "recommendation": { + "en": "Enable zone-redundant storage by setting DataRedundancyType to 'ZRS' when creating the project.", + "zh": "在创建项目时通过将 DataRedundancyType 设置为'ZRS'来启用同城冗余存储。", + "ja": "プロジェクト作成時に DataRedundancyType を 'ZRS' に設定してゾーン冗長ストレージを有効にします。", + "de": "Aktivieren Sie zonenredundanten Speicher, indem Sie DataRedundancyType beim Erstellen des Projekts auf 'ZRS' setzen.", + "es": "Habilite el almacenamiento redundante de zona estableciendo DataRedundancyType en 'ZRS' al crear el proyecto.", + "fr": "Activez le stockage redondant par zone en définissant DataRedundancyType sur 'ZRS' lors de la création du projet.", + "pt": "Habilite o armazenamento redundante de zona definindo DataRedundancyType como 'ZRS' ao criar o projeto." + }, + "resource_types": ["ALIYUN::SLS::Project"] +} + +# Check if project has ZRS enabled +has_zrs_enabled(resource) if { + redundancy_type := helpers.get_property(resource, "DataRedundancyType", "LRS") + redundancy_type == "ZRS" +} + +# Deny rule: SLS projects should have ZRS enabled +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLS::Project") + not has_zrs_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DataRedundancyType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/cost-optimization-usage-guidelines.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/cost-optimization-usage-guidelines.md new file mode 100644 index 0000000..f30d131 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/cost-optimization-usage-guidelines.md @@ -0,0 +1,22 @@ +# Cost Optimization InfraGuard Usage Guidelines + +## Sources read + +- Local official InfraGuard repository: `/private/tmp/infraguard-official`. +- Alibaba Cloud ROS and Well-Architected official references for the scenario. +- Cross-cloud Well-Architected references were used as control-point background when available. + +## Write to Learn notes + +The scenario was reduced to static IaC checks only. Runtime metrics, billing history, incident evidence, and approval workflow evidence are kept out of Rego because they cannot be proven from a ROS template alone. + +## Engineer-facing guidelines + +- Prefer explicit resource intent over provider defaults. +- Make the policy failure point actionable through `violation_path`. +- Keep rule ids short and stable, without scenario prefixes. +- Keep exceptions outside Rego unless the exception is represented in the template itself. + +## Rego mapping + +The scenario pack in `../packs/iac-code-cost-optimization-pack.rego` lists the rule ids enforced for this scenario. Rules use `package infraguard.rules.aliyun.`, `rule_meta`, and `deny contains result if` in the official InfraGuard style. diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-category-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-category-required.rego new file mode 100644 index 0000000..b57770c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-category-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_disk_category_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-disk-category-required", + "severity": "medium", + "name": { + "en": "ECS disk must set disk category", + "zh": "ECS 云盘必须设置云盘类型", + "ja": "ECS 云盘必须设置云盘类型", + "de": "ECS 云盘必须设置云盘类型", + "es": "ECS 云盘必须设置云盘类型", + "fr": "ECS 云盘必须设置云盘类型", + "pt": "ECS 云盘必须设置云盘类型" + }, + "description": { + "en": "Checks ECS disk must set disk category", + "zh": "检查ECS 云盘必须设置云盘类型", + "ja": "检查ECS 云盘必须设置云盘类型", + "de": "检查ECS 云盘必须设置云盘类型", + "es": "检查ECS 云盘必须设置云盘类型", + "fr": "检查ECS 云盘必须设置云盘类型", + "pt": "检查ECS 云盘必须设置云盘类型" + }, + "reason": { + "en": "ECS disk must set disk category is not satisfied.", + "zh": "ECS 云盘必须设置云盘类型未满足。", + "ja": "ECS 云盘必须设置云盘类型未满足。", + "de": "ECS 云盘必须设置云盘类型未满足。", + "es": "ECS 云盘必须设置云盘类型未满足。", + "fr": "ECS 云盘必须设置云盘类型未满足。", + "pt": "ECS 云盘必须设置云盘类型未满足。" + }, + "recommendation": { + "en": "Configure DiskCategory on ALIYUN::ECS::Disk to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Disk 上配置 DiskCategory 以满足策略。", + "ja": "请在 ALIYUN::ECS::Disk 上配置 DiskCategory 以满足策略。", + "de": "请在 ALIYUN::ECS::Disk 上配置 DiskCategory 以满足策略。", + "es": "请在 ALIYUN::ECS::Disk 上配置 DiskCategory 以满足策略。", + "fr": "请在 ALIYUN::ECS::Disk 上配置 DiskCategory 以满足策略。", + "pt": "请在 ALIYUN::ECS::Disk 上配置 DiskCategory 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Disk"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Disk") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DiskCategory"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "DiskCategory") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-size-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-size-required.rego new file mode 100644 index 0000000..9883cc7 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-disk-size-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_disk_size_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-disk-size-required", + "severity": "medium", + "name": { + "en": "ECS disk must set disk size", + "zh": "ECS 云盘必须设置容量", + "ja": "ECS 云盘必须设置容量", + "de": "ECS 云盘必须设置容量", + "es": "ECS 云盘必须设置容量", + "fr": "ECS 云盘必须设置容量", + "pt": "ECS 云盘必须设置容量" + }, + "description": { + "en": "Checks ECS disk must set disk size", + "zh": "检查ECS 云盘必须设置容量", + "ja": "检查ECS 云盘必须设置容量", + "de": "检查ECS 云盘必须设置容量", + "es": "检查ECS 云盘必须设置容量", + "fr": "检查ECS 云盘必须设置容量", + "pt": "检查ECS 云盘必须设置容量" + }, + "reason": { + "en": "ECS disk must set disk size is not satisfied.", + "zh": "ECS 云盘必须设置容量未满足。", + "ja": "ECS 云盘必须设置容量未满足。", + "de": "ECS 云盘必须设置容量未满足。", + "es": "ECS 云盘必须设置容量未满足。", + "fr": "ECS 云盘必须设置容量未满足。", + "pt": "ECS 云盘必须设置容量未满足。" + }, + "recommendation": { + "en": "Configure Size on ALIYUN::ECS::Disk to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Disk 上配置 Size 以满足策略。", + "ja": "请在 ALIYUN::ECS::Disk 上配置 Size 以满足策略。", + "de": "请在 ALIYUN::ECS::Disk 上配置 Size 以满足策略。", + "es": "请在 ALIYUN::ECS::Disk 上配置 Size 以满足策略。", + "fr": "请在 ALIYUN::ECS::Disk 上配置 Size 以满足策略。", + "pt": "请在 ALIYUN::ECS::Disk 上配置 Size 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Disk"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Disk") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Size"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Size") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-bandwidth-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-bandwidth-configured.rego new file mode 100644 index 0000000..1edf00f --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-bandwidth-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_instance_bandwidth_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-bandwidth-configured", + "severity": "medium", + "name": { + "en": "ECS instance must configure outbound bandwidth", + "zh": "ECS 实例必须配置出网带宽", + "ja": "ECS 实例必须配置出网带宽", + "de": "ECS 实例必须配置出网带宽", + "es": "ECS 实例必须配置出网带宽", + "fr": "ECS 实例必须配置出网带宽", + "pt": "ECS 实例必须配置出网带宽" + }, + "description": { + "en": "Checks ECS instance must configure outbound bandwidth", + "zh": "检查ECS 实例必须配置出网带宽", + "ja": "检查ECS 实例必须配置出网带宽", + "de": "检查ECS 实例必须配置出网带宽", + "es": "检查ECS 实例必须配置出网带宽", + "fr": "检查ECS 实例必须配置出网带宽", + "pt": "检查ECS 实例必须配置出网带宽" + }, + "reason": { + "en": "ECS instance must configure outbound bandwidth is not satisfied.", + "zh": "ECS 实例必须配置出网带宽未满足。", + "ja": "ECS 实例必须配置出网带宽未满足。", + "de": "ECS 实例必须配置出网带宽未满足。", + "es": "ECS 实例必须配置出网带宽未满足。", + "fr": "ECS 实例必须配置出网带宽未满足。", + "pt": "ECS 实例必须配置出网带宽未满足。" + }, + "recommendation": { + "en": "Configure InternetMaxBandwidthOut on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 InternetMaxBandwidthOut 以满足策略。", + "ja": "请在 ALIYUN::ECS::Instance 上配置 InternetMaxBandwidthOut 以满足策略。", + "de": "请在 ALIYUN::ECS::Instance 上配置 InternetMaxBandwidthOut 以满足策略。", + "es": "请在 ALIYUN::ECS::Instance 上配置 InternetMaxBandwidthOut 以满足策略。", + "fr": "请在 ALIYUN::ECS::Instance 上配置 InternetMaxBandwidthOut 以满足策略。", + "pt": "请在 ALIYUN::ECS::Instance 上配置 InternetMaxBandwidthOut 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InternetMaxBandwidthOut"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InternetMaxBandwidthOut") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-charge-type-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-charge-type-required.rego new file mode 100644 index 0000000..ee456c6 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-charge-type-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_instance_charge_type_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-charge-type-required", + "severity": "medium", + "name": { + "en": "ECS instance must set charge type", + "zh": "ECS 实例必须设置付费类型", + "ja": "ECS 实例必须设置付费类型", + "de": "ECS 实例必须设置付费类型", + "es": "ECS 实例必须设置付费类型", + "fr": "ECS 实例必须设置付费类型", + "pt": "ECS 实例必须设置付费类型" + }, + "description": { + "en": "Checks ECS instance must set charge type", + "zh": "检查ECS 实例必须设置付费类型", + "ja": "检查ECS 实例必须设置付费类型", + "de": "检查ECS 实例必须设置付费类型", + "es": "检查ECS 实例必须设置付费类型", + "fr": "检查ECS 实例必须设置付费类型", + "pt": "检查ECS 实例必须设置付费类型" + }, + "reason": { + "en": "ECS instance must set charge type is not satisfied.", + "zh": "ECS 实例必须设置付费类型未满足。", + "ja": "ECS 实例必须设置付费类型未满足。", + "de": "ECS 实例必须设置付费类型未满足。", + "es": "ECS 实例必须设置付费类型未满足。", + "fr": "ECS 实例必须设置付费类型未满足。", + "pt": "ECS 实例必须设置付费类型未满足。" + }, + "recommendation": { + "en": "Configure InstanceChargeType on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 InstanceChargeType 以满足策略。", + "ja": "请在 ALIYUN::ECS::Instance 上配置 InstanceChargeType 以满足策略。", + "de": "请在 ALIYUN::ECS::Instance 上配置 InstanceChargeType 以满足策略。", + "es": "请在 ALIYUN::ECS::Instance 上配置 InstanceChargeType 以满足策略。", + "fr": "请在 ALIYUN::ECS::Instance 上配置 InstanceChargeType 以满足策略。", + "pt": "请在 ALIYUN::ECS::Instance 上配置 InstanceChargeType 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InstanceChargeType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InstanceChargeType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-type-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-type-required.rego new file mode 100644 index 0000000..bb81bd0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/ecs-instance-type-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_instance_type_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-type-required", + "severity": "medium", + "name": { + "en": "ECS instance must set instance type", + "zh": "ECS 实例必须设置实例规格", + "ja": "ECS 实例必须设置实例规格", + "de": "ECS 实例必须设置实例规格", + "es": "ECS 实例必须设置实例规格", + "fr": "ECS 实例必须设置实例规格", + "pt": "ECS 实例必须设置实例规格" + }, + "description": { + "en": "Checks ECS instance must set instance type", + "zh": "检查ECS 实例必须设置实例规格", + "ja": "检查ECS 实例必须设置实例规格", + "de": "检查ECS 实例必须设置实例规格", + "es": "检查ECS 实例必须设置实例规格", + "fr": "检查ECS 实例必须设置实例规格", + "pt": "检查ECS 实例必须设置实例规格" + }, + "reason": { + "en": "ECS instance must set instance type is not satisfied.", + "zh": "ECS 实例必须设置实例规格未满足。", + "ja": "ECS 实例必须设置实例规格未满足。", + "de": "ECS 实例必须设置实例规格未满足。", + "es": "ECS 实例必须设置实例规格未满足。", + "fr": "ECS 实例必须设置实例规格未满足。", + "pt": "ECS 实例必须设置实例规格未满足。" + }, + "recommendation": { + "en": "Configure InstanceType on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 InstanceType 以满足策略。", + "ja": "请在 ALIYUN::ECS::Instance 上配置 InstanceType 以满足策略。", + "de": "请在 ALIYUN::ECS::Instance 上配置 InstanceType 以满足策略。", + "es": "请在 ALIYUN::ECS::Instance 上配置 InstanceType 以满足策略。", + "fr": "请在 ALIYUN::ECS::Instance 上配置 InstanceType 以满足策略。", + "pt": "请在 ALIYUN::ECS::Instance 上配置 InstanceType 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InstanceType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InstanceType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/eip-bandwidth-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/eip-bandwidth-required.rego new file mode 100644 index 0000000..97a6694 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/eip-bandwidth-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.eip_bandwidth_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "eip-bandwidth-required", + "severity": "medium", + "name": { + "en": "EIP must set bandwidth", + "zh": "EIP 必须设置带宽", + "ja": "EIP 必须设置带宽", + "de": "EIP 必须设置带宽", + "es": "EIP 必须设置带宽", + "fr": "EIP 必须设置带宽", + "pt": "EIP 必须设置带宽" + }, + "description": { + "en": "Checks EIP must set bandwidth", + "zh": "检查EIP 必须设置带宽", + "ja": "检查EIP 必须设置带宽", + "de": "检查EIP 必须设置带宽", + "es": "检查EIP 必须设置带宽", + "fr": "检查EIP 必须设置带宽", + "pt": "检查EIP 必须设置带宽" + }, + "reason": { + "en": "EIP must set bandwidth is not satisfied.", + "zh": "EIP 必须设置带宽未满足。", + "ja": "EIP 必须设置带宽未满足。", + "de": "EIP 必须设置带宽未满足。", + "es": "EIP 必须设置带宽未满足。", + "fr": "EIP 必须设置带宽未满足。", + "pt": "EIP 必须设置带宽未满足。" + }, + "recommendation": { + "en": "Configure Bandwidth on ALIYUN::VPC::EIP to satisfy the policy.", + "zh": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "ja": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "de": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "es": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "fr": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "pt": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。" + }, + "resource_types": ["ALIYUN::VPC::EIP"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::VPC::EIP") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Bandwidth"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Bandwidth") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/logstore-ttl-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/logstore-ttl-required.rego new file mode 100644 index 0000000..2d156ae --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/logstore-ttl-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.logstore_ttl_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "logstore-ttl-required", + "severity": "medium", + "name": { + "en": "SLS Logstore must set TTL", + "zh": "SLS Logstore 必须设置数据保存时间", + "ja": "SLS Logstore 必须设置数据保存时间", + "de": "SLS Logstore 必须设置数据保存时间", + "es": "SLS Logstore 必须设置数据保存时间", + "fr": "SLS Logstore 必须设置数据保存时间", + "pt": "SLS Logstore 必须设置数据保存时间" + }, + "description": { + "en": "Checks SLS Logstore must set TTL", + "zh": "检查SLS Logstore 必须设置数据保存时间", + "ja": "检查SLS Logstore 必须设置数据保存时间", + "de": "检查SLS Logstore 必须设置数据保存时间", + "es": "检查SLS Logstore 必须设置数据保存时间", + "fr": "检查SLS Logstore 必须设置数据保存时间", + "pt": "检查SLS Logstore 必须设置数据保存时间" + }, + "reason": { + "en": "SLS Logstore must set TTL is not satisfied.", + "zh": "SLS Logstore 必须设置数据保存时间未满足。", + "ja": "SLS Logstore 必须设置数据保存时间未满足。", + "de": "SLS Logstore 必须设置数据保存时间未满足。", + "es": "SLS Logstore 必须设置数据保存时间未满足。", + "fr": "SLS Logstore 必须设置数据保存时间未满足。", + "pt": "SLS Logstore 必须设置数据保存时间未满足。" + }, + "recommendation": { + "en": "Configure TTL on ALIYUN::SLS::Logstore to satisfy the policy.", + "zh": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "ja": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "de": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "es": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "fr": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "pt": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。" + }, + "resource_types": ["ALIYUN::SLS::Logstore"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLS::Logstore") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "TTL"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "TTL") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/nat-gateway-spec-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/nat-gateway-spec-required.rego new file mode 100644 index 0000000..fdce671 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/nat-gateway-spec-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.nat_gateway_spec_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "nat-gateway-spec-required", + "severity": "medium", + "name": { + "en": "NAT Gateway must set specification", + "zh": "NAT 网关必须设置规格", + "ja": "NAT 网关必须设置规格", + "de": "NAT 网关必须设置规格", + "es": "NAT 网关必须设置规格", + "fr": "NAT 网关必须设置规格", + "pt": "NAT 网关必须设置规格" + }, + "description": { + "en": "Checks NAT Gateway must set specification", + "zh": "检查NAT 网关必须设置规格", + "ja": "检查NAT 网关必须设置规格", + "de": "检查NAT 网关必须设置规格", + "es": "检查NAT 网关必须设置规格", + "fr": "检查NAT 网关必须设置规格", + "pt": "检查NAT 网关必须设置规格" + }, + "reason": { + "en": "NAT Gateway must set specification is not satisfied.", + "zh": "NAT 网关必须设置规格未满足。", + "ja": "NAT 网关必须设置规格未满足。", + "de": "NAT 网关必须设置规格未满足。", + "es": "NAT 网关必须设置规格未满足。", + "fr": "NAT 网关必须设置规格未满足。", + "pt": "NAT 网关必须设置规格未满足。" + }, + "recommendation": { + "en": "Configure NatGatewaySpec on ALIYUN::VPC::NatGateway to satisfy the policy.", + "zh": "请在 ALIYUN::VPC::NatGateway 上配置 NatGatewaySpec 以满足策略。", + "ja": "请在 ALIYUN::VPC::NatGateway 上配置 NatGatewaySpec 以满足策略。", + "de": "请在 ALIYUN::VPC::NatGateway 上配置 NatGatewaySpec 以满足策略。", + "es": "请在 ALIYUN::VPC::NatGateway 上配置 NatGatewaySpec 以满足策略。", + "fr": "请在 ALIYUN::VPC::NatGateway 上配置 NatGatewaySpec 以满足策略。", + "pt": "请在 ALIYUN::VPC::NatGateway 上配置 NatGatewaySpec 以满足策略。" + }, + "resource_types": ["ALIYUN::VPC::NatGateway"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::VPC::NatGateway") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "NatGatewaySpec"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "NatGatewaySpec") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/oss-storage-class-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/oss-storage-class-required.rego new file mode 100644 index 0000000..ad103fb --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/oss-storage-class-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.oss_storage_class_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "oss-storage-class-required", + "severity": "medium", + "name": { + "en": "OSS bucket must set storage class", + "zh": "OSS Bucket 必须设置存储类型", + "ja": "OSS Bucket 必须设置存储类型", + "de": "OSS Bucket 必须设置存储类型", + "es": "OSS Bucket 必须设置存储类型", + "fr": "OSS Bucket 必须设置存储类型", + "pt": "OSS Bucket 必须设置存储类型" + }, + "description": { + "en": "Checks OSS bucket must set storage class", + "zh": "检查OSS Bucket 必须设置存储类型", + "ja": "检查OSS Bucket 必须设置存储类型", + "de": "检查OSS Bucket 必须设置存储类型", + "es": "检查OSS Bucket 必须设置存储类型", + "fr": "检查OSS Bucket 必须设置存储类型", + "pt": "检查OSS Bucket 必须设置存储类型" + }, + "reason": { + "en": "OSS bucket must set storage class is not satisfied.", + "zh": "OSS Bucket 必须设置存储类型未满足。", + "ja": "OSS Bucket 必须设置存储类型未满足。", + "de": "OSS Bucket 必须设置存储类型未满足。", + "es": "OSS Bucket 必须设置存储类型未满足。", + "fr": "OSS Bucket 必须设置存储类型未满足。", + "pt": "OSS Bucket 必须设置存储类型未满足。" + }, + "recommendation": { + "en": "Configure StorageClass on ALIYUN::OSS::Bucket to satisfy the policy.", + "zh": "请在 ALIYUN::OSS::Bucket 上配置 StorageClass 以满足策略。", + "ja": "请在 ALIYUN::OSS::Bucket 上配置 StorageClass 以满足策略。", + "de": "请在 ALIYUN::OSS::Bucket 上配置 StorageClass 以满足策略。", + "es": "请在 ALIYUN::OSS::Bucket 上配置 StorageClass 以满足策略。", + "fr": "请在 ALIYUN::OSS::Bucket 上配置 StorageClass 以满足策略。", + "pt": "请在 ALIYUN::OSS::Bucket 上配置 StorageClass 以满足策略。" + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "StorageClass"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "StorageClass") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-pay-type-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-pay-type-required.rego new file mode 100644 index 0000000..ab64de3 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-pay-type-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.rds_pay_type_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "rds-pay-type-required", + "severity": "medium", + "name": { + "en": "RDS instance must set pay type", + "zh": "RDS 实例必须设置付费类型", + "ja": "RDS 实例必须设置付费类型", + "de": "RDS 实例必须设置付费类型", + "es": "RDS 实例必须设置付费类型", + "fr": "RDS 实例必须设置付费类型", + "pt": "RDS 实例必须设置付费类型" + }, + "description": { + "en": "Checks RDS instance must set pay type", + "zh": "检查RDS 实例必须设置付费类型", + "ja": "检查RDS 实例必须设置付费类型", + "de": "检查RDS 实例必须设置付费类型", + "es": "检查RDS 实例必须设置付费类型", + "fr": "检查RDS 实例必须设置付费类型", + "pt": "检查RDS 实例必须设置付费类型" + }, + "reason": { + "en": "RDS instance must set pay type is not satisfied.", + "zh": "RDS 实例必须设置付费类型未满足。", + "ja": "RDS 实例必须设置付费类型未满足。", + "de": "RDS 实例必须设置付费类型未满足。", + "es": "RDS 实例必须设置付费类型未满足。", + "fr": "RDS 实例必须设置付费类型未满足。", + "pt": "RDS 实例必须设置付费类型未满足。" + }, + "recommendation": { + "en": "Configure PayType on ALIYUN::RDS::DBInstance to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::DBInstance 上配置 PayType 以满足策略。", + "ja": "请在 ALIYUN::RDS::DBInstance 上配置 PayType 以满足策略。", + "de": "请在 ALIYUN::RDS::DBInstance 上配置 PayType 以满足策略。", + "es": "请在 ALIYUN::RDS::DBInstance 上配置 PayType 以满足策略。", + "fr": "请在 ALIYUN::RDS::DBInstance 上配置 PayType 以满足策略。", + "pt": "请在 ALIYUN::RDS::DBInstance 上配置 PayType 以满足策略。" + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "PayType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "PayType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-storage-type-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-storage-type-required.rego new file mode 100644 index 0000000..6f3dc24 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/rds-storage-type-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.rds_storage_type_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "rds-storage-type-required", + "severity": "medium", + "name": { + "en": "RDS instance must set storage type", + "zh": "RDS 实例必须设置存储类型", + "ja": "RDS 实例必须设置存储类型", + "de": "RDS 实例必须设置存储类型", + "es": "RDS 实例必须设置存储类型", + "fr": "RDS 实例必须设置存储类型", + "pt": "RDS 实例必须设置存储类型" + }, + "description": { + "en": "Checks RDS instance must set storage type", + "zh": "检查RDS 实例必须设置存储类型", + "ja": "检查RDS 实例必须设置存储类型", + "de": "检查RDS 实例必须设置存储类型", + "es": "检查RDS 实例必须设置存储类型", + "fr": "检查RDS 实例必须设置存储类型", + "pt": "检查RDS 实例必须设置存储类型" + }, + "reason": { + "en": "RDS instance must set storage type is not satisfied.", + "zh": "RDS 实例必须设置存储类型未满足。", + "ja": "RDS 实例必须设置存储类型未满足。", + "de": "RDS 实例必须设置存储类型未满足。", + "es": "RDS 实例必须设置存储类型未满足。", + "fr": "RDS 实例必须设置存储类型未满足。", + "pt": "RDS 实例必须设置存储类型未满足。" + }, + "recommendation": { + "en": "Configure DBInstanceStorageType on ALIYUN::RDS::DBInstance to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::DBInstance 上配置 DBInstanceStorageType 以满足策略。", + "ja": "请在 ALIYUN::RDS::DBInstance 上配置 DBInstanceStorageType 以满足策略。", + "de": "请在 ALIYUN::RDS::DBInstance 上配置 DBInstanceStorageType 以满足策略。", + "es": "请在 ALIYUN::RDS::DBInstance 上配置 DBInstanceStorageType 以满足策略。", + "fr": "请在 ALIYUN::RDS::DBInstance 上配置 DBInstanceStorageType 以满足策略。", + "pt": "请在 ALIYUN::RDS::DBInstance 上配置 DBInstanceStorageType 以满足策略。" + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DBInstanceStorageType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "DBInstanceStorageType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/redis-instance-class-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/redis-instance-class-required.rego new file mode 100644 index 0000000..b2325f8 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/redis-instance-class-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.redis_instance_class_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "redis-instance-class-required", + "severity": "medium", + "name": { + "en": "Redis instance must set instance class", + "zh": "Redis 实例必须设置规格", + "ja": "Redis 实例必须设置规格", + "de": "Redis 实例必须设置规格", + "es": "Redis 实例必须设置规格", + "fr": "Redis 实例必须设置规格", + "pt": "Redis 实例必须设置规格" + }, + "description": { + "en": "Checks Redis instance must set instance class", + "zh": "检查Redis 实例必须设置规格", + "ja": "检查Redis 实例必须设置规格", + "de": "检查Redis 实例必须设置规格", + "es": "检查Redis 实例必须设置规格", + "fr": "检查Redis 实例必须设置规格", + "pt": "检查Redis 实例必须设置规格" + }, + "reason": { + "en": "Redis instance must set instance class is not satisfied.", + "zh": "Redis 实例必须设置规格未满足。", + "ja": "Redis 实例必须设置规格未满足。", + "de": "Redis 实例必须设置规格未满足。", + "es": "Redis 实例必须设置规格未满足。", + "fr": "Redis 实例必须设置规格未满足。", + "pt": "Redis 实例必须设置规格未满足。" + }, + "recommendation": { + "en": "Configure InstanceClass on ALIYUN::REDIS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::REDIS::Instance 上配置 InstanceClass 以满足策略。", + "ja": "请在 ALIYUN::REDIS::Instance 上配置 InstanceClass 以满足策略。", + "de": "请在 ALIYUN::REDIS::Instance 上配置 InstanceClass 以满足策略。", + "es": "请在 ALIYUN::REDIS::Instance 上配置 InstanceClass 以满足策略。", + "fr": "请在 ALIYUN::REDIS::Instance 上配置 InstanceClass 以满足策略。", + "pt": "请在 ALIYUN::REDIS::Instance 上配置 InstanceClass 以满足策略。" + }, + "resource_types": ["ALIYUN::REDIS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::REDIS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InstanceClass"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InstanceClass") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/slb-internet-charge-type-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/slb-internet-charge-type-required.rego new file mode 100644 index 0000000..f830ca0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/cost-optimization/slb-internet-charge-type-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.slb_internet_charge_type_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "slb-internet-charge-type-required", + "severity": "medium", + "name": { + "en": "SLB must set internet charge type", + "zh": "SLB 必须设置公网计费类型", + "ja": "SLB 必须设置公网计费类型", + "de": "SLB 必须设置公网计费类型", + "es": "SLB 必须设置公网计费类型", + "fr": "SLB 必须设置公网计费类型", + "pt": "SLB 必须设置公网计费类型" + }, + "description": { + "en": "Checks SLB must set internet charge type", + "zh": "检查SLB 必须设置公网计费类型", + "ja": "检查SLB 必须设置公网计费类型", + "de": "检查SLB 必须设置公网计费类型", + "es": "检查SLB 必须设置公网计费类型", + "fr": "检查SLB 必须设置公网计费类型", + "pt": "检查SLB 必须设置公网计费类型" + }, + "reason": { + "en": "SLB must set internet charge type is not satisfied.", + "zh": "SLB 必须设置公网计费类型未满足。", + "ja": "SLB 必须设置公网计费类型未满足。", + "de": "SLB 必须设置公网计费类型未满足。", + "es": "SLB 必须设置公网计费类型未满足。", + "fr": "SLB 必须设置公网计费类型未满足。", + "pt": "SLB 必须设置公网计费类型未满足。" + }, + "recommendation": { + "en": "Configure InternetChargeType on ALIYUN::SLB::LoadBalancer to satisfy the policy.", + "zh": "请在 ALIYUN::SLB::LoadBalancer 上配置 InternetChargeType 以满足策略。", + "ja": "请在 ALIYUN::SLB::LoadBalancer 上配置 InternetChargeType 以满足策略。", + "de": "请在 ALIYUN::SLB::LoadBalancer 上配置 InternetChargeType 以满足策略。", + "es": "请在 ALIYUN::SLB::LoadBalancer 上配置 InternetChargeType 以满足策略。", + "fr": "请在 ALIYUN::SLB::LoadBalancer 上配置 InternetChargeType 以满足策略。", + "pt": "请在 ALIYUN::SLB::LoadBalancer 上配置 InternetChargeType 以满足策略。" + }, + "resource_types": ["ALIYUN::SLB::LoadBalancer"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLB::LoadBalancer") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InternetChargeType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InternetChargeType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-autoscaling-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-autoscaling-enabled.rego new file mode 100644 index 0000000..72ca600 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-autoscaling-enabled.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ack_cluster_node_pool_autoscaling_enabled + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ack-cluster-node-pool-autoscaling-enabled", + "severity": "high", + "name": { + "en": "ACK cluster must configure worker VSwitches", + "zh": "ACK 集群必须配置工作节点交换机", + "ja": "ACK 集群必须配置工作节点交换机", + "de": "ACK 集群必须配置工作节点交换机", + "es": "ACK 集群必须配置工作节点交换机", + "fr": "ACK 集群必须配置工作节点交换机", + "pt": "ACK 集群必须配置工作节点交换机" + }, + "description": { + "en": "Checks ACK cluster must configure worker VSwitches", + "zh": "检查ACK 集群必须配置工作节点交换机", + "ja": "检查ACK 集群必须配置工作节点交换机", + "de": "检查ACK 集群必须配置工作节点交换机", + "es": "检查ACK 集群必须配置工作节点交换机", + "fr": "检查ACK 集群必须配置工作节点交换机", + "pt": "检查ACK 集群必须配置工作节点交换机" + }, + "reason": { + "en": "ACK cluster must configure worker VSwitches is not satisfied.", + "zh": "ACK 集群必须配置工作节点交换机未满足。", + "ja": "ACK 集群必须配置工作节点交换机未满足。", + "de": "ACK 集群必须配置工作节点交换机未满足。", + "es": "ACK 集群必须配置工作节点交换机未满足。", + "fr": "ACK 集群必须配置工作节点交换机未满足。", + "pt": "ACK 集群必须配置工作节点交换机未满足。" + }, + "recommendation": { + "en": "Configure WorkerVSwitchIds on ALIYUN::CS::ClusterApplication to satisfy the policy.", + "zh": "请在 ALIYUN::CS::ClusterApplication 上配置 WorkerVSwitchIds 以满足策略。", + "ja": "请在 ALIYUN::CS::ClusterApplication 上配置 WorkerVSwitchIds 以满足策略。", + "de": "请在 ALIYUN::CS::ClusterApplication 上配置 WorkerVSwitchIds 以满足策略。", + "es": "请在 ALIYUN::CS::ClusterApplication 上配置 WorkerVSwitchIds 以满足策略。", + "fr": "请在 ALIYUN::CS::ClusterApplication 上配置 WorkerVSwitchIds 以满足策略。", + "pt": "请在 ALIYUN::CS::ClusterApplication 上配置 WorkerVSwitchIds 以满足策略。" + }, + "resource_types": ["ALIYUN::CS::ClusterApplication"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::CS::ClusterApplication") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "WorkerVSwitchIds"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "WorkerVSwitchIds") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-scaling-limits-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-scaling-limits-required.rego new file mode 100644 index 0000000..191b75b --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ack-cluster-node-pool-scaling-limits-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ack_cluster_node_pool_scaling_limits_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ack-cluster-node-pool-scaling-limits-required", + "severity": "medium", + "name": { + "en": "ESS scaling group must configure MinSize", + "zh": "ESS 伸缩组必须配置最小容量", + "ja": "ESS 伸缩组必须配置最小容量", + "de": "ESS 伸缩组必须配置最小容量", + "es": "ESS 伸缩组必须配置最小容量", + "fr": "ESS 伸缩组必须配置最小容量", + "pt": "ESS 伸缩组必须配置最小容量" + }, + "description": { + "en": "Checks ESS scaling group must configure MinSize", + "zh": "检查ESS 伸缩组必须配置最小容量", + "ja": "检查ESS 伸缩组必须配置最小容量", + "de": "检查ESS 伸缩组必须配置最小容量", + "es": "检查ESS 伸缩组必须配置最小容量", + "fr": "检查ESS 伸缩组必须配置最小容量", + "pt": "检查ESS 伸缩组必须配置最小容量" + }, + "reason": { + "en": "ESS scaling group must configure MinSize is not satisfied.", + "zh": "ESS 伸缩组必须配置最小容量未满足。", + "ja": "ESS 伸缩组必须配置最小容量未满足。", + "de": "ESS 伸缩组必须配置最小容量未满足。", + "es": "ESS 伸缩组必须配置最小容量未满足。", + "fr": "ESS 伸缩组必须配置最小容量未满足。", + "pt": "ESS 伸缩组必须配置最小容量未满足。" + }, + "recommendation": { + "en": "Configure MinSize on ALIYUN::ESS::ScalingGroup to satisfy the policy.", + "zh": "请在 ALIYUN::ESS::ScalingGroup 上配置 MinSize 以满足策略。", + "ja": "请在 ALIYUN::ESS::ScalingGroup 上配置 MinSize 以满足策略。", + "de": "请在 ALIYUN::ESS::ScalingGroup 上配置 MinSize 以满足策略。", + "es": "请在 ALIYUN::ESS::ScalingGroup 上配置 MinSize 以满足策略。", + "fr": "请在 ALIYUN::ESS::ScalingGroup 上配置 MinSize 以满足策略。", + "pt": "请在 ALIYUN::ESS::ScalingGroup 上配置 MinSize 以满足策略。" + }, + "resource_types": ["ALIYUN::ESS::ScalingGroup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingGroup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MinSize"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "MinSize") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listener-health-check-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listener-health-check-enabled.rego new file mode 100644 index 0000000..d349a1c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listener-health-check-enabled.rego @@ -0,0 +1,21 @@ +package infraguard.rules.aliyun.alb_all_listener_health_check_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "alb-all-listener-health-check-enabled", + "severity": "medium", + "name": {"en": "ALB Listener Health Check Enabled", "zh": "ALB 监听开启健康检查", "ja": "ALB 监听开启健康检查", "de": "ALB 监听开启健康检查", "es": "ALB 监听开启健康检查", "fr": "ALB 监听开启健康检查", "pt": "ALB 监听开启健康检查"}, + "description": {"en": "ALB listeners should configure health checks before serving elastic traffic.", "zh": "ALB 监听应配置健康检查。", "ja": "ALB 监听应配置健康检查。", "de": "ALB 监听应配置健康检查。", "es": "ALB 监听应配置健康检查。", "fr": "ALB 监听应配置健康检查。", "pt": "ALB 监听应配置健康检查。"}, + "reason": {"en": "The listener does not configure HealthCheckConfig.", "zh": "监听未配置 HealthCheckConfig。", "ja": "监听未配置 HealthCheckConfig。", "de": "监听未配置 HealthCheckConfig。", "es": "监听未配置 HealthCheckConfig。", "fr": "监听未配置 HealthCheckConfig。", "pt": "监听未配置 HealthCheckConfig。"}, + "recommendation": {"en": "Configure HealthCheckConfig for ALB listeners.", "zh": "为 ALB 监听配置 HealthCheckConfig。", "ja": "为 ALB 监听配置 HealthCheckConfig。", "de": "为 ALB 监听配置 HealthCheckConfig。", "es": "为 ALB 监听配置 HealthCheckConfig。", "fr": "为 ALB 监听配置 HealthCheckConfig。", "pt": "为 ALB 监听配置 HealthCheckConfig。"}, + "resource_types": ["ALIYUN::ALB::Listener"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ALB::Listener") + not helpers.has_property(resource, "HealthCheckConfig") + result := {"id": rule_meta.id, "resource_id": name, "violation_path": ["Properties", "HealthCheckConfig"], "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}} +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listenter-has-server.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listenter-has-server.rego new file mode 100644 index 0000000..f55eb5e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/alb-all-listenter-has-server.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.alb_all_listenter_has_server + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "alb-all-listenter-has-server", + "severity": "medium", + "name": { + "en": "ALB listener must configure server group", + "zh": "ALB 监听必须配置服务器组", + "ja": "ALB 监听必须配置服务器组", + "de": "ALB 监听必须配置服务器组", + "es": "ALB 监听必须配置服务器组", + "fr": "ALB 监听必须配置服务器组", + "pt": "ALB 监听必须配置服务器组" + }, + "description": { + "en": "Checks ALB listener must configure server group", + "zh": "检查ALB 监听必须配置服务器组", + "ja": "检查ALB 监听必须配置服务器组", + "de": "检查ALB 监听必须配置服务器组", + "es": "检查ALB 监听必须配置服务器组", + "fr": "检查ALB 监听必须配置服务器组", + "pt": "检查ALB 监听必须配置服务器组" + }, + "reason": { + "en": "ALB listener must configure server group is not satisfied.", + "zh": "ALB 监听必须配置服务器组未满足。", + "ja": "ALB 监听必须配置服务器组未满足。", + "de": "ALB 监听必须配置服务器组未满足。", + "es": "ALB 监听必须配置服务器组未满足。", + "fr": "ALB 监听必须配置服务器组未满足。", + "pt": "ALB 监听必须配置服务器组未满足。" + }, + "recommendation": { + "en": "Configure DefaultActions on ALIYUN::ALB::Listener to satisfy the policy.", + "zh": "请在 ALIYUN::ALB::Listener 上配置 DefaultActions 以满足策略。", + "ja": "请在 ALIYUN::ALB::Listener 上配置 DefaultActions 以满足策略。", + "de": "请在 ALIYUN::ALB::Listener 上配置 DefaultActions 以满足策略。", + "es": "请在 ALIYUN::ALB::Listener 上配置 DefaultActions 以满足策略。", + "fr": "请在 ALIYUN::ALB::Listener 上配置 DefaultActions 以满足策略。", + "pt": "请在 ALIYUN::ALB::Listener 上配置 DefaultActions 以满足策略。" + }, + "resource_types": ["ALIYUN::ALB::Listener"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ALB::Listener") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DefaultActions"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "DefaultActions") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/elasticity-usage-guidelines.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/elasticity-usage-guidelines.md new file mode 100644 index 0000000..73a2dcf --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/elasticity-usage-guidelines.md @@ -0,0 +1,22 @@ +# Elasticity InfraGuard Usage Guidelines + +## Sources read + +- Local official InfraGuard repository: `/private/tmp/infraguard-official`. +- Alibaba Cloud ROS and Well-Architected official references for the scenario. +- Cross-cloud Well-Architected references were used as control-point background when available. + +## Write to Learn notes + +The scenario was reduced to static IaC checks only. Runtime metrics, billing history, incident evidence, and approval workflow evidence are kept out of Rego because they cannot be proven from a ROS template alone. + +## Engineer-facing guidelines + +- Prefer explicit resource intent over provider defaults. +- Make the policy failure point actionable through `violation_path`. +- Keep rule ids short and stable, without scenario prefixes. +- Keep exceptions outside Rego unless the exception is represented in the template itself. + +## Rego mapping + +The scenario pack in `../packs/iac-code-elasticity-pack.rego` lists the rule ids enforced for this scenario. Rules use `package infraguard.rules.aliyun.`, `rule_meta`, and `deny contains result if` in the official InfraGuard style. diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-group-health-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-group-health-check.rego new file mode 100644 index 0000000..49e2fe1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-group-health-check.rego @@ -0,0 +1,21 @@ +package infraguard.rules.aliyun.ess_group_health_check + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ess-group-health-check", + "severity": "medium", + "name": {"en": "ESS Group Health Check", "zh": "ESS 伸缩组健康检查", "ja": "ESS 伸缩组健康检查", "de": "ESS 伸缩组健康检查", "es": "ESS 伸缩组健康检查", "fr": "ESS 伸缩组健康检查", "pt": "ESS 伸缩组健康检查"}, + "description": {"en": "ESS scaling groups should configure health checks before automatic scaling is used.", "zh": "ESS 伸缩组应配置健康检查。", "ja": "ESS 伸缩组应配置健康检查。", "de": "ESS 伸缩组应配置健康检查。", "es": "ESS 伸缩组应配置健康检查。", "fr": "ESS 伸缩组应配置健康检查。", "pt": "ESS 伸缩组应配置健康检查。"}, + "reason": {"en": "The scaling group does not configure HealthCheckType.", "zh": "伸缩组未配置 HealthCheckType。", "ja": "伸缩组未配置 HealthCheckType。", "de": "伸缩组未配置 HealthCheckType。", "es": "伸缩组未配置 HealthCheckType。", "fr": "伸缩组未配置 HealthCheckType。", "pt": "伸缩组未配置 HealthCheckType。"}, + "recommendation": {"en": "Configure HealthCheckType for the ESS scaling group.", "zh": "为 ESS 伸缩组配置 HealthCheckType。", "ja": "为 ESS 伸缩组配置 HealthCheckType。", "de": "为 ESS 伸缩组配置 HealthCheckType。", "es": "为 ESS 伸缩组配置 HealthCheckType。", "fr": "为 ESS 伸缩组配置 HealthCheckType。", "pt": "为 ESS 伸缩组配置 HealthCheckType。"}, + "resource_types": ["ALIYUN::ESS::ScalingGroup"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingGroup") + not helpers.has_property(resource, "HealthCheckType") + result := {"id": rule_meta.id, "resource_id": name, "violation_path": ["Properties", "HealthCheckType"], "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}} +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-image-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-image-check.rego new file mode 100644 index 0000000..1b1af02 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-image-check.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ess_scaling_configuration_image_check + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ess-scaling-configuration-image-check", + "severity": "medium", + "name": { + "en": "ESS scaling configuration must set image", + "zh": "ESS 伸缩配置必须设置镜像", + "ja": "ESS 伸缩配置必须设置镜像", + "de": "ESS 伸缩配置必须设置镜像", + "es": "ESS 伸缩配置必须设置镜像", + "fr": "ESS 伸缩配置必须设置镜像", + "pt": "ESS 伸缩配置必须设置镜像" + }, + "description": { + "en": "Checks ESS scaling configuration must set image", + "zh": "检查ESS 伸缩配置必须设置镜像", + "ja": "检查ESS 伸缩配置必须设置镜像", + "de": "检查ESS 伸缩配置必须设置镜像", + "es": "检查ESS 伸缩配置必须设置镜像", + "fr": "检查ESS 伸缩配置必须设置镜像", + "pt": "检查ESS 伸缩配置必须设置镜像" + }, + "reason": { + "en": "ESS scaling configuration must set image is not satisfied.", + "zh": "ESS 伸缩配置必须设置镜像未满足。", + "ja": "ESS 伸缩配置必须设置镜像未满足。", + "de": "ESS 伸缩配置必须设置镜像未满足。", + "es": "ESS 伸缩配置必须设置镜像未满足。", + "fr": "ESS 伸缩配置必须设置镜像未满足。", + "pt": "ESS 伸缩配置必须设置镜像未满足。" + }, + "recommendation": { + "en": "Configure ImageId on ALIYUN::ESS::ScalingConfiguration to satisfy the policy.", + "zh": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 ImageId 以满足策略。", + "ja": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 ImageId 以满足策略。", + "de": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 ImageId 以满足策略。", + "es": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 ImageId 以满足策略。", + "fr": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 ImageId 以满足策略。", + "pt": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 ImageId 以满足策略。" + }, + "resource_types": ["ALIYUN::ESS::ScalingConfiguration"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingConfiguration") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ImageId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "ImageId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-instance-type-candidates-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-instance-type-candidates-required.rego new file mode 100644 index 0000000..090f170 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-configuration-instance-type-candidates-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ess_scaling_configuration_instance_type_candidates_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ess-scaling-configuration-instance-type-candidates-required", + "severity": "medium", + "name": { + "en": "ESS scaling configuration must set instance type", + "zh": "ESS 伸缩配置必须设置实例规格", + "ja": "ESS 伸缩配置必须设置实例规格", + "de": "ESS 伸缩配置必须设置实例规格", + "es": "ESS 伸缩配置必须设置实例规格", + "fr": "ESS 伸缩配置必须设置实例规格", + "pt": "ESS 伸缩配置必须设置实例规格" + }, + "description": { + "en": "Checks ESS scaling configuration must set instance type", + "zh": "检查ESS 伸缩配置必须设置实例规格", + "ja": "检查ESS 伸缩配置必须设置实例规格", + "de": "检查ESS 伸缩配置必须设置实例规格", + "es": "检查ESS 伸缩配置必须设置实例规格", + "fr": "检查ESS 伸缩配置必须设置实例规格", + "pt": "检查ESS 伸缩配置必须设置实例规格" + }, + "reason": { + "en": "ESS scaling configuration must set instance type is not satisfied.", + "zh": "ESS 伸缩配置必须设置实例规格未满足。", + "ja": "ESS 伸缩配置必须设置实例规格未满足。", + "de": "ESS 伸缩配置必须设置实例规格未满足。", + "es": "ESS 伸缩配置必须设置实例规格未满足。", + "fr": "ESS 伸缩配置必须设置实例规格未满足。", + "pt": "ESS 伸缩配置必须设置实例规格未满足。" + }, + "recommendation": { + "en": "Configure InstanceType on ALIYUN::ESS::ScalingConfiguration to satisfy the policy.", + "zh": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 InstanceType 以满足策略。", + "ja": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 InstanceType 以满足策略。", + "de": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 InstanceType 以满足策略。", + "es": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 InstanceType 以满足策略。", + "fr": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 InstanceType 以满足策略。", + "pt": "请在 ALIYUN::ESS::ScalingConfiguration 上配置 InstanceType 以满足策略。" + }, + "resource_types": ["ALIYUN::ESS::ScalingConfiguration"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingConfiguration") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InstanceType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InstanceType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-attach-multi-switch.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-attach-multi-switch.rego new file mode 100644 index 0000000..6f64975 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-attach-multi-switch.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ess_scaling_group_attach_multi_switch + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ess-scaling-group-attach-multi-switch", + "severity": "high", + "name": { + "en": "ESS scaling group must configure VSwitches for elasticity", + "zh": "ESS 伸缩组必须配置交换机以支持弹性", + "ja": "ESS 伸缩组必须配置交换机以支持弹性", + "de": "ESS 伸缩组必须配置交换机以支持弹性", + "es": "ESS 伸缩组必须配置交换机以支持弹性", + "fr": "ESS 伸缩组必须配置交换机以支持弹性", + "pt": "ESS 伸缩组必须配置交换机以支持弹性" + }, + "description": { + "en": "Checks ESS scaling group must configure VSwitches for elasticity", + "zh": "检查ESS 伸缩组必须配置交换机以支持弹性", + "ja": "检查ESS 伸缩组必须配置交换机以支持弹性", + "de": "检查ESS 伸缩组必须配置交换机以支持弹性", + "es": "检查ESS 伸缩组必须配置交换机以支持弹性", + "fr": "检查ESS 伸缩组必须配置交换机以支持弹性", + "pt": "检查ESS 伸缩组必须配置交换机以支持弹性" + }, + "reason": { + "en": "ESS scaling group must configure VSwitches for elasticity is not satisfied.", + "zh": "ESS 伸缩组必须配置交换机以支持弹性未满足。", + "ja": "ESS 伸缩组必须配置交换机以支持弹性未满足。", + "de": "ESS 伸缩组必须配置交换机以支持弹性未满足。", + "es": "ESS 伸缩组必须配置交换机以支持弹性未满足。", + "fr": "ESS 伸缩组必须配置交换机以支持弹性未满足。", + "pt": "ESS 伸缩组必须配置交换机以支持弹性未满足。" + }, + "recommendation": { + "en": "Configure VSwitchIds on ALIYUN::ESS::ScalingGroup to satisfy the policy.", + "zh": "请在 ALIYUN::ESS::ScalingGroup 上配置 VSwitchIds 以满足策略。", + "ja": "请在 ALIYUN::ESS::ScalingGroup 上配置 VSwitchIds 以满足策略。", + "de": "请在 ALIYUN::ESS::ScalingGroup 上配置 VSwitchIds 以满足策略。", + "es": "请在 ALIYUN::ESS::ScalingGroup 上配置 VSwitchIds 以满足策略。", + "fr": "请在 ALIYUN::ESS::ScalingGroup 上配置 VSwitchIds 以满足策略。", + "pt": "请在 ALIYUN::ESS::ScalingGroup 上配置 VSwitchIds 以满足策略。" + }, + "resource_types": ["ALIYUN::ESS::ScalingGroup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingGroup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VSwitchIds"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VSwitchIds") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-capacity-bounds-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-capacity-bounds-required.rego new file mode 100644 index 0000000..f45c2dc --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-capacity-bounds-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ess_scaling_group_capacity_bounds_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ess-scaling-group-capacity-bounds-required", + "severity": "medium", + "name": { + "en": "ESS scaling group must configure MaxSize", + "zh": "ESS 伸缩组必须配置最大容量", + "ja": "ESS 伸缩组必须配置最大容量", + "de": "ESS 伸缩组必须配置最大容量", + "es": "ESS 伸缩组必须配置最大容量", + "fr": "ESS 伸缩组必须配置最大容量", + "pt": "ESS 伸缩组必须配置最大容量" + }, + "description": { + "en": "Checks ESS scaling group must configure MaxSize", + "zh": "检查ESS 伸缩组必须配置最大容量", + "ja": "检查ESS 伸缩组必须配置最大容量", + "de": "检查ESS 伸缩组必须配置最大容量", + "es": "检查ESS 伸缩组必须配置最大容量", + "fr": "检查ESS 伸缩组必须配置最大容量", + "pt": "检查ESS 伸缩组必须配置最大容量" + }, + "reason": { + "en": "ESS scaling group must configure MaxSize is not satisfied.", + "zh": "ESS 伸缩组必须配置最大容量未满足。", + "ja": "ESS 伸缩组必须配置最大容量未满足。", + "de": "ESS 伸缩组必须配置最大容量未满足。", + "es": "ESS 伸缩组必须配置最大容量未满足。", + "fr": "ESS 伸缩组必须配置最大容量未满足。", + "pt": "ESS 伸缩组必须配置最大容量未满足。" + }, + "recommendation": { + "en": "Configure MaxSize on ALIYUN::ESS::ScalingGroup to satisfy the policy.", + "zh": "请在 ALIYUN::ESS::ScalingGroup 上配置 MaxSize 以满足策略。", + "ja": "请在 ALIYUN::ESS::ScalingGroup 上配置 MaxSize 以满足策略。", + "de": "请在 ALIYUN::ESS::ScalingGroup 上配置 MaxSize 以满足策略。", + "es": "请在 ALIYUN::ESS::ScalingGroup 上配置 MaxSize 以满足策略。", + "fr": "请在 ALIYUN::ESS::ScalingGroup 上配置 MaxSize 以满足策略。", + "pt": "请在 ALIYUN::ESS::ScalingGroup 上配置 MaxSize 以满足策略。" + }, + "resource_types": ["ALIYUN::ESS::ScalingGroup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingGroup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MaxSize"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "MaxSize") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-cooldown-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-cooldown-configured.rego new file mode 100644 index 0000000..8ba5d9c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-group-cooldown-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ess_scaling_group_cooldown_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ess-scaling-group-cooldown-configured", + "severity": "medium", + "name": { + "en": "ESS scaling group must configure cooldown", + "zh": "ESS 伸缩组必须配置冷却时间", + "ja": "ESS 伸缩组必须配置冷却时间", + "de": "ESS 伸缩组必须配置冷却时间", + "es": "ESS 伸缩组必须配置冷却时间", + "fr": "ESS 伸缩组必须配置冷却时间", + "pt": "ESS 伸缩组必须配置冷却时间" + }, + "description": { + "en": "Checks ESS scaling group must configure cooldown", + "zh": "检查ESS 伸缩组必须配置冷却时间", + "ja": "检查ESS 伸缩组必须配置冷却时间", + "de": "检查ESS 伸缩组必须配置冷却时间", + "es": "检查ESS 伸缩组必须配置冷却时间", + "fr": "检查ESS 伸缩组必须配置冷却时间", + "pt": "检查ESS 伸缩组必须配置冷却时间" + }, + "reason": { + "en": "ESS scaling group must configure cooldown is not satisfied.", + "zh": "ESS 伸缩组必须配置冷却时间未满足。", + "ja": "ESS 伸缩组必须配置冷却时间未满足。", + "de": "ESS 伸缩组必须配置冷却时间未满足。", + "es": "ESS 伸缩组必须配置冷却时间未满足。", + "fr": "ESS 伸缩组必须配置冷却时间未满足。", + "pt": "ESS 伸缩组必须配置冷却时间未满足。" + }, + "recommendation": { + "en": "Configure DefaultCooldown on ALIYUN::ESS::ScalingGroup to satisfy the policy.", + "zh": "请在 ALIYUN::ESS::ScalingGroup 上配置 DefaultCooldown 以满足策略。", + "ja": "请在 ALIYUN::ESS::ScalingGroup 上配置 DefaultCooldown 以满足策略。", + "de": "请在 ALIYUN::ESS::ScalingGroup 上配置 DefaultCooldown 以满足策略。", + "es": "请在 ALIYUN::ESS::ScalingGroup 上配置 DefaultCooldown 以满足策略。", + "fr": "请在 ALIYUN::ESS::ScalingGroup 上配置 DefaultCooldown 以满足策略。", + "pt": "请在 ALIYUN::ESS::ScalingGroup 上配置 DefaultCooldown 以满足策略。" + }, + "resource_types": ["ALIYUN::ESS::ScalingGroup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingGroup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DefaultCooldown"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "DefaultCooldown") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-rule-action-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-rule-action-configured.rego new file mode 100644 index 0000000..856008e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/ess-scaling-rule-action-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ess_scaling_rule_action_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ess-scaling-rule-action-configured", + "severity": "medium", + "name": { + "en": "ESS scaling rule must configure adjustment", + "zh": "ESS 伸缩规则必须配置调整方式", + "ja": "ESS 伸缩规则必须配置调整方式", + "de": "ESS 伸缩规则必须配置调整方式", + "es": "ESS 伸缩规则必须配置调整方式", + "fr": "ESS 伸缩规则必须配置调整方式", + "pt": "ESS 伸缩规则必须配置调整方式" + }, + "description": { + "en": "Checks ESS scaling rule must configure adjustment", + "zh": "检查ESS 伸缩规则必须配置调整方式", + "ja": "检查ESS 伸缩规则必须配置调整方式", + "de": "检查ESS 伸缩规则必须配置调整方式", + "es": "检查ESS 伸缩规则必须配置调整方式", + "fr": "检查ESS 伸缩规则必须配置调整方式", + "pt": "检查ESS 伸缩规则必须配置调整方式" + }, + "reason": { + "en": "ESS scaling rule must configure adjustment is not satisfied.", + "zh": "ESS 伸缩规则必须配置调整方式未满足。", + "ja": "ESS 伸缩规则必须配置调整方式未满足。", + "de": "ESS 伸缩规则必须配置调整方式未满足。", + "es": "ESS 伸缩规则必须配置调整方式未满足。", + "fr": "ESS 伸缩规则必须配置调整方式未满足。", + "pt": "ESS 伸缩规则必须配置调整方式未满足。" + }, + "recommendation": { + "en": "Configure AdjustmentType on ALIYUN::ESS::ScalingRule to satisfy the policy.", + "zh": "请在 ALIYUN::ESS::ScalingRule 上配置 AdjustmentType 以满足策略。", + "ja": "请在 ALIYUN::ESS::ScalingRule 上配置 AdjustmentType 以满足策略。", + "de": "请在 ALIYUN::ESS::ScalingRule 上配置 AdjustmentType 以满足策略。", + "es": "请在 ALIYUN::ESS::ScalingRule 上配置 AdjustmentType 以满足策略。", + "fr": "请在 ALIYUN::ESS::ScalingRule 上配置 AdjustmentType 以满足策略。", + "pt": "请在 ALIYUN::ESS::ScalingRule 上配置 AdjustmentType 以满足策略。" + }, + "resource_types": ["ALIYUN::ESS::ScalingRule"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingRule") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AdjustmentType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "AdjustmentType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-instance-concurrency-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-instance-concurrency-configured.rego new file mode 100644 index 0000000..9ea52c8 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-instance-concurrency-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.fc_function_instance_concurrency_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "fc-function-instance-concurrency-configured", + "severity": "medium", + "name": { + "en": "FC function must configure instance concurrency", + "zh": "函数计算函数必须配置实例并发", + "ja": "函数计算函数必须配置实例并发", + "de": "函数计算函数必须配置实例并发", + "es": "函数计算函数必须配置实例并发", + "fr": "函数计算函数必须配置实例并发", + "pt": "函数计算函数必须配置实例并发" + }, + "description": { + "en": "Checks FC function must configure instance concurrency", + "zh": "检查函数计算函数必须配置实例并发", + "ja": "检查函数计算函数必须配置实例并发", + "de": "检查函数计算函数必须配置实例并发", + "es": "检查函数计算函数必须配置实例并发", + "fr": "检查函数计算函数必须配置实例并发", + "pt": "检查函数计算函数必须配置实例并发" + }, + "reason": { + "en": "FC function must configure instance concurrency is not satisfied.", + "zh": "函数计算函数必须配置实例并发未满足。", + "ja": "函数计算函数必须配置实例并发未满足。", + "de": "函数计算函数必须配置实例并发未满足。", + "es": "函数计算函数必须配置实例并发未满足。", + "fr": "函数计算函数必须配置实例并发未满足。", + "pt": "函数计算函数必须配置实例并发未满足。" + }, + "recommendation": { + "en": "Configure InstanceConcurrency on ALIYUN::FC::Function to satisfy the policy.", + "zh": "请在 ALIYUN::FC::Function 上配置 InstanceConcurrency 以满足策略。", + "ja": "请在 ALIYUN::FC::Function 上配置 InstanceConcurrency 以满足策略。", + "de": "请在 ALIYUN::FC::Function 上配置 InstanceConcurrency 以满足策略。", + "es": "请在 ALIYUN::FC::Function 上配置 InstanceConcurrency 以满足策略。", + "fr": "请在 ALIYUN::FC::Function 上配置 InstanceConcurrency 以满足策略。", + "pt": "请在 ALIYUN::FC::Function 上配置 InstanceConcurrency 以满足策略。" + }, + "resource_types": ["ALIYUN::FC::Function"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::FC::Function") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InstanceConcurrency"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "InstanceConcurrency") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-timeout-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-timeout-configured.rego new file mode 100644 index 0000000..1a90fdf --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/fc-function-timeout-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.fc_function_timeout_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "fc-function-timeout-configured", + "severity": "medium", + "name": { + "en": "FC function must configure timeout", + "zh": "函数计算函数必须配置超时时间", + "ja": "函数计算函数必须配置超时时间", + "de": "函数计算函数必须配置超时时间", + "es": "函数计算函数必须配置超时时间", + "fr": "函数计算函数必须配置超时时间", + "pt": "函数计算函数必须配置超时时间" + }, + "description": { + "en": "Checks FC function must configure timeout", + "zh": "检查函数计算函数必须配置超时时间", + "ja": "检查函数计算函数必须配置超时时间", + "de": "检查函数计算函数必须配置超时时间", + "es": "检查函数计算函数必须配置超时时间", + "fr": "检查函数计算函数必须配置超时时间", + "pt": "检查函数计算函数必须配置超时时间" + }, + "reason": { + "en": "FC function must configure timeout is not satisfied.", + "zh": "函数计算函数必须配置超时时间未满足。", + "ja": "函数计算函数必须配置超时时间未满足。", + "de": "函数计算函数必须配置超时时间未满足。", + "es": "函数计算函数必须配置超时时间未满足。", + "fr": "函数计算函数必须配置超时时间未满足。", + "pt": "函数计算函数必须配置超时时间未满足。" + }, + "recommendation": { + "en": "Configure Timeout on ALIYUN::FC::Function to satisfy the policy.", + "zh": "请在 ALIYUN::FC::Function 上配置 Timeout 以满足策略。", + "ja": "请在 ALIYUN::FC::Function 上配置 Timeout 以满足策略。", + "de": "请在 ALIYUN::FC::Function 上配置 Timeout 以满足策略。", + "es": "请在 ALIYUN::FC::Function 上配置 Timeout 以满足策略。", + "fr": "请在 ALIYUN::FC::Function 上配置 Timeout 以满足策略。", + "pt": "请在 ALIYUN::FC::Function 上配置 Timeout 以满足策略。" + }, + "resource_types": ["ALIYUN::FC::Function"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::FC::Function") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Timeout"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Timeout") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/mse-cluster-high-availability-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/mse-cluster-high-availability-configured.rego new file mode 100644 index 0000000..c10c02d --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/mse-cluster-high-availability-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.mse_cluster_high_availability_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "mse-cluster-high-availability-configured", + "severity": "medium", + "name": { + "en": "MSE cluster must configure replicas", + "zh": "MSE 集群必须配置副本数", + "ja": "MSE 集群必须配置副本数", + "de": "MSE 集群必须配置副本数", + "es": "MSE 集群必须配置副本数", + "fr": "MSE 集群必须配置副本数", + "pt": "MSE 集群必须配置副本数" + }, + "description": { + "en": "Checks MSE cluster must configure replicas", + "zh": "检查MSE 集群必须配置副本数", + "ja": "检查MSE 集群必须配置副本数", + "de": "检查MSE 集群必须配置副本数", + "es": "检查MSE 集群必须配置副本数", + "fr": "检查MSE 集群必须配置副本数", + "pt": "检查MSE 集群必须配置副本数" + }, + "reason": { + "en": "MSE cluster must configure replicas is not satisfied.", + "zh": "MSE 集群必须配置副本数未满足。", + "ja": "MSE 集群必须配置副本数未满足。", + "de": "MSE 集群必须配置副本数未满足。", + "es": "MSE 集群必须配置副本数未满足。", + "fr": "MSE 集群必须配置副本数未满足。", + "pt": "MSE 集群必须配置副本数未满足。" + }, + "recommendation": { + "en": "Configure Replicas on ALIYUN::MSE::Cluster to satisfy the policy.", + "zh": "请在 ALIYUN::MSE::Cluster 上配置 Replicas 以满足策略。", + "ja": "请在 ALIYUN::MSE::Cluster 上配置 Replicas 以满足策略。", + "de": "请在 ALIYUN::MSE::Cluster 上配置 Replicas 以满足策略。", + "es": "请在 ALIYUN::MSE::Cluster 上配置 Replicas 以满足策略。", + "fr": "请在 ALIYUN::MSE::Cluster 上配置 Replicas 以满足策略。", + "pt": "请在 ALIYUN::MSE::Cluster 上配置 Replicas 以满足策略。" + }, + "resource_types": ["ALIYUN::MSE::Cluster"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::MSE::Cluster") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Replicas"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Replicas") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/slb-all-listener-health-check-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/slb-all-listener-health-check-enabled.rego new file mode 100644 index 0000000..fe09ca1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/elasticity/slb-all-listener-health-check-enabled.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.slb_all_listener_health_check_enabled + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "slb-all-listener-health-check-enabled", + "severity": "medium", + "name": { + "en": "SLB listener must configure backend server port", + "zh": "SLB 监听必须配置后端端口", + "ja": "SLB 监听必须配置后端端口", + "de": "SLB 监听必须配置后端端口", + "es": "SLB 监听必须配置后端端口", + "fr": "SLB 监听必须配置后端端口", + "pt": "SLB 监听必须配置后端端口" + }, + "description": { + "en": "Checks SLB listener must configure backend server port", + "zh": "检查SLB 监听必须配置后端端口", + "ja": "检查SLB 监听必须配置后端端口", + "de": "检查SLB 监听必须配置后端端口", + "es": "检查SLB 监听必须配置后端端口", + "fr": "检查SLB 监听必须配置后端端口", + "pt": "检查SLB 监听必须配置后端端口" + }, + "reason": { + "en": "SLB listener must configure backend server port is not satisfied.", + "zh": "SLB 监听必须配置后端端口未满足。", + "ja": "SLB 监听必须配置后端端口未满足。", + "de": "SLB 监听必须配置后端端口未满足。", + "es": "SLB 监听必须配置后端端口未满足。", + "fr": "SLB 监听必须配置后端端口未满足。", + "pt": "SLB 监听必须配置后端端口未满足。" + }, + "recommendation": { + "en": "Configure BackendServerPort on ALIYUN::SLB::Listener to satisfy the policy.", + "zh": "请在 ALIYUN::SLB::Listener 上配置 BackendServerPort 以满足策略。", + "ja": "请在 ALIYUN::SLB::Listener 上配置 BackendServerPort 以满足策略。", + "de": "请在 ALIYUN::SLB::Listener 上配置 BackendServerPort 以满足策略。", + "es": "请在 ALIYUN::SLB::Listener 上配置 BackendServerPort 以满足策略。", + "fr": "请在 ALIYUN::SLB::Listener 上配置 BackendServerPort 以满足策略。", + "pt": "请在 ALIYUN::SLB::Listener 上配置 BackendServerPort 以满足策略。" + }, + "resource_types": ["ALIYUN::SLB::Listener"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLB::Listener") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "BackendServerPort"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "BackendServerPort") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/alb-instance-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/alb-instance-multi-zone.rego new file mode 100644 index 0000000..165993a --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/alb-instance-multi-zone.rego @@ -0,0 +1,72 @@ +package infraguard.rules.aliyun.alb_instance_multi_zone + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "alb-instance-multi-zone", + "severity": "high", + "name": { + "en": "ALB Instance Multi-Zone Deployment", + "zh": "使用多可用区的 ALB 实例", + "ja": "ALB インスタンスのマルチゾーン展開", + "de": "ALB-Instanz Multi-Zone-Bereitstellung", + "es": "Despliegue Multi-zona de Instancia ALB", + "fr": "Déploiement Multi-Zones de l'Instance ALB", + "pt": "Implantação Multi-zona da Instância ALB", + }, + "description": { + "en": "ALB instances should be deployed across multiple availability zones for high availability and real-time disaster recovery.", + "zh": "ALB 实例应部署在多个可用区,以实现高可用和实时容灾。", + "ja": "ALB インスタンスは、高可用性とリアルタイム災害復旧のために複数の可用性ゾーンに展開する必要があります。", + "de": "ALB-Instanzen sollten für Hochverfügbarkeit und Disaster Recovery in Echtzeit über mehrere Verfügbarkeitszonen bereitgestellt werden.", + "es": "Las instancias ALB deben implementarse en múltiples zonas de disponibilidad para alta disponibilidad y recuperación ante desastres en tiempo real.", + "fr": "Les instances ALB doivent être déployées sur plusieurs zones de disponibilité pour la haute disponibilité et la reprise après sinistre en temps réel.", + "pt": "Instâncias ALB devem ser implantadas em múltiplas zonas de disponibilidade para alta disponibilidade e recuperação de desastres em tempo real.", + }, + "reason": { + "en": "The ALB instance is deployed in fewer than two availability zones, which creates a single point of failure.", + "zh": "ALB 实例部署在少于两个可用区,存在单点故障风险。", + "ja": "ALB インスタンスが 2 つ未満の可用性ゾーンに展開されているため、単一障害点が発生します。", + "de": "Die ALB-Instanz ist in weniger als zwei Verfügbarkeitszonen bereitgestellt, was einen Single Point of Failure schafft.", + "es": "La instancia ALB está implementada en menos de dos zonas de disponibilidad, lo que crea un punto único de falla.", + "fr": "L'instance ALB est déployée dans moins de deux zones de disponibilité, ce qui crée un point de défaillance unique.", + "pt": "A instância ALB está implantada em menos de duas zonas de disponibilidade, criando um ponto único de falha.", + }, + "recommendation": { + "en": "Configure at least two zone mappings in ZoneMappings.", + "zh": "在 ZoneMappings 中配置至少两个可用区映射。", + "ja": "ZoneMappings に少なくとも 2 つのゾーンマッピングを設定します。", + "de": "Konfigurieren Sie mindestens zwei Zonen-Zuordnungen in ZoneMappings.", + "es": "Configure al menos dos mapeos de zona en ZoneMappings.", + "fr": "Configurez au moins deux mappages de zone dans ZoneMappings.", + "pt": "Configure pelo menos dois mapeamentos de zona em ZoneMappings.", + }, + "resource_types": ["ALIYUN::ALB::LoadBalancer"], +} + +is_multi_zone(resource) if { + mappings := object.get(resource.Properties, "ZoneMappings", []) + unique_zones := {zone | + some mapping in mappings + zone := object.get(mapping, "ZoneId", "") + zone != "" + } + count(unique_zones) >= 2 +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ALB::LoadBalancer") + not is_multi_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ZoneMappings"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-max-amount-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-max-amount-required.rego new file mode 100644 index 0000000..f338475 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-max-amount-required.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.ecs_instance_group_max_amount_required + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-group-max-amount-required", + "severity": "medium", + "name": { + "en": "ECS Instance Group Maximum Amount Required", + "zh": "ECS 实例组必须配置最大实例数", + "ja": "ECS インスタンスグループの最大数必須", + "de": "Maximalanzahl für ECS-Instanzgruppe erforderlich", + "es": "Cantidad máxima requerida para grupo de instancias ECS", + "fr": "Nombre maximal requis pour le groupe d'instances ECS", + "pt": "Quantidade máxima obrigatória para grupo de instâncias ECS", + }, + "description": { + "en": "ECS instance groups should declare MaxAmount so the intended replica ceiling is explicit.", + "zh": "ECS 实例组应声明 MaxAmount,使计划的副本上限清晰可见。", + "ja": "ECS インスタンスグループは、意図したレプリカ上限を明確にするため MaxAmount を宣言する必要があります。", + "de": "ECS-Instanzgruppen sollten MaxAmount deklarieren, damit die beabsichtigte Replikatobergrenze explizit ist.", + "es": "Los grupos de instancias ECS deben declarar MaxAmount para que el límite de réplicas previsto sea explícito.", + "fr": "Les groupes d'instances ECS doivent déclarer MaxAmount afin que le plafond de réplicas prévu soit explicite.", + "pt": "Grupos de instâncias ECS devem declarar MaxAmount para tornar explícito o limite planejado de réplicas.", + }, + "reason": { + "en": "The ECS instance group does not specify MaxAmount.", + "zh": "ECS 实例组未指定 MaxAmount。", + "ja": "ECS インスタンスグループで MaxAmount が指定されていません。", + "de": "Die ECS-Instanzgruppe gibt MaxAmount nicht an.", + "es": "El grupo de instancias ECS no especifica MaxAmount.", + "fr": "Le groupe d'instances ECS ne spécifie pas MaxAmount.", + "pt": "O grupo de instâncias ECS não especifica MaxAmount.", + }, + "recommendation": { + "en": "Configure MaxAmount, preferably at least 2 for production workloads.", + "zh": "配置 MaxAmount,生产工作负载建议至少为 2。", + "ja": "MaxAmount を設定します。本番ワークロードでは少なくとも 2 を推奨します。", + "de": "Konfigurieren Sie MaxAmount, für Produktionsworkloads vorzugsweise mindestens 2.", + "es": "Configure MaxAmount, preferiblemente al menos 2 para cargas de trabajo de producción.", + "fr": "Configurez MaxAmount, de préférence au moins 2 pour les charges de travail de production.", + "pt": "Configure MaxAmount, de preferência pelo menos 2 para cargas de trabalho de produção.", + }, + "resource_types": ["ALIYUN::ECS::InstanceGroup"], +} + +has_max_amount(resource) if { + helpers.has_property(resource, "MaxAmount") +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::InstanceGroup") + not has_max_amount(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MaxAmount"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-min-amount-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-min-amount-required.rego new file mode 100644 index 0000000..d9eeeaa --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ecs-instance-group-min-amount-required.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.ecs_instance_group_min_amount_required + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-group-min-amount-required", + "severity": "medium", + "name": { + "en": "ECS Instance Group Minimum Amount Required", + "zh": "ECS 实例组必须配置最小实例数", + "ja": "ECS インスタンスグループの最小数必須", + "de": "Mindestanzahl für ECS-Instanzgruppe erforderlich", + "es": "Cantidad mínima requerida para grupo de instancias ECS", + "fr": "Nombre minimal requis pour le groupe d'instances ECS", + "pt": "Quantidade mínima obrigatória para grupo de instâncias ECS", + }, + "description": { + "en": "ECS instance groups should declare MinAmount so the baseline replica count is explicit.", + "zh": "ECS 实例组应声明 MinAmount,使基线副本数清晰可见。", + "ja": "ECS インスタンスグループは、基準レプリカ数を明確にするため MinAmount を宣言する必要があります。", + "de": "ECS-Instanzgruppen sollten MinAmount deklarieren, damit die Basis-Replikatanzahl explizit ist.", + "es": "Los grupos de instancias ECS deben declarar MinAmount para que el número base de réplicas sea explícito.", + "fr": "Les groupes d'instances ECS doivent déclarer MinAmount afin que le nombre de réplicas de base soit explicite.", + "pt": "Grupos de instâncias ECS devem declarar MinAmount para tornar explícita a contagem base de réplicas.", + }, + "reason": { + "en": "The ECS instance group does not specify MinAmount.", + "zh": "ECS 实例组未指定 MinAmount。", + "ja": "ECS インスタンスグループで MinAmount が指定されていません。", + "de": "Die ECS-Instanzgruppe gibt MinAmount nicht an.", + "es": "El grupo de instancias ECS no especifica MinAmount.", + "fr": "Le groupe d'instances ECS ne spécifie pas MinAmount.", + "pt": "O grupo de instâncias ECS não especifica MinAmount.", + }, + "recommendation": { + "en": "Configure MinAmount, preferably at least 2 for production workloads.", + "zh": "配置 MinAmount,生产工作负载建议至少为 2。", + "ja": "MinAmount を設定します。本番ワークロードでは少なくとも 2 を推奨します。", + "de": "Konfigurieren Sie MinAmount, für Produktionsworkloads vorzugsweise mindestens 2.", + "es": "Configure MinAmount, preferiblemente al menos 2 para cargas de trabajo de producción.", + "fr": "Configurez MinAmount, de préférence au moins 2 pour les charges de travail de production.", + "pt": "Configure MinAmount, de preferência pelo menos 2 para cargas de trabalho de produção.", + }, + "resource_types": ["ALIYUN::ECS::InstanceGroup"], +} + +has_min_amount(resource) if { + helpers.has_property(resource, "MinAmount") +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::InstanceGroup") + not has_min_amount(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MinAmount"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ess-scaling-group-multi-vswitch-distribution.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ess-scaling-group-multi-vswitch-distribution.rego new file mode 100644 index 0000000..53ffa95 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/ess-scaling-group-multi-vswitch-distribution.rego @@ -0,0 +1,67 @@ +package infraguard.rules.aliyun.ess_scaling_group_multi_vswitch_distribution + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ess-scaling-group-multi-vswitch-distribution", + "severity": "high", + "name": { + "en": "ESS Scaling Group Multi-VSwitch Distribution", + "zh": "弹性伸缩组关联至少两个交换机", + "ja": "ESS スケーリンググループマルチ VSwitch", + "de": "ESS-Skalierungsgruppe Multi-VSwitch", + "es": "Grupo de escalado ESS con múltiples VSwitches", + "fr": "Groupe ESS avec plusieurs VSwitches", + "pt": "Grupo ESS com múltiplos VSwitches", + }, + "description": { + "en": "ESS scaling groups should attach at least two VSwitches so instances can be distributed across zones for high availability.", + "zh": "弹性伸缩组应关联至少两个交换机,使实例可以跨可用区分布。", + "ja": "ESS スケーリンググループは、インスタンスをゾーン間で分散できるように少なくとも 2 つの VSwitch を関連付ける必要があります。", + "de": "ESS-Skalierungsgruppen sollten mindestens zwei VSwitches zuordnen, damit Instanzen über Zonen verteilt werden können.", + "es": "Los grupos de escalado ESS deben asociar al menos dos VSwitches para distribuir instancias entre zonas.", + "fr": "Les groupes ESS doivent associer au moins deux VSwitches afin de répartir les instances entre les zones.", + "pt": "Grupos ESS devem associar pelo menos dois VSwitches para distribuir instâncias entre zonas.", + }, + "reason": { + "en": "The ESS scaling group has fewer than two VSwitchIds.", + "zh": "弹性伸缩组的 VSwitchIds 少于两个。", + "ja": "ESS スケーリンググループの VSwitchIds が 2 つ未満です。", + "de": "Die ESS-Skalierungsgruppe hat weniger als zwei VSwitchIds.", + "es": "El grupo de escalado ESS tiene menos de dos VSwitchIds.", + "fr": "Le groupe ESS a moins de deux VSwitchIds.", + "pt": "O grupo ESS tem menos de dois VSwitchIds.", + }, + "recommendation": { + "en": "Configure at least two VSwitchIds.", + "zh": "配置至少两个 VSwitchIds。", + "ja": "少なくとも 2 つの VSwitchIds を設定します。", + "de": "Konfigurieren Sie mindestens zwei VSwitchIds.", + "es": "Configure al menos dos VSwitchIds.", + "fr": "Configurez au moins deux VSwitchIds.", + "pt": "Configure pelo menos dois VSwitchIds.", + }, + "resource_types": ["ALIYUN::ESS::ScalingGroup"], +} + +has_multiple_vswitches(resource) if { + vswitches := object.get(resource.Properties, "VSwitchIds", []) + count(vswitches) >= 2 +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ESS::ScalingGroup") + not has_multiple_vswitches(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VSwitchIds"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/high-availability-usage-guidelines.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/high-availability-usage-guidelines.md new file mode 100644 index 0000000..b71c334 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/high-availability-usage-guidelines.md @@ -0,0 +1,22 @@ +# High Availability InfraGuard Usage Guidelines + +## Sources read + +- Local official InfraGuard repository: `/private/tmp/infraguard-official`. +- Alibaba Cloud ROS and Well-Architected official references for the scenario. +- Cross-cloud Well-Architected references were used as control-point background when available. + +## Write to Learn notes + +The scenario was reduced to static IaC checks only. Runtime metrics, billing history, incident evidence, and approval workflow evidence are kept out of Rego because they cannot be proven from a ROS template alone. + +## Engineer-facing guidelines + +- Prefer explicit resource intent over provider defaults. +- Make the policy failure point actionable through `violation_path`. +- Keep rule ids short and stable, without scenario prefixes. +- Keep exceptions outside Rego unless the exception is represented in the template itself. + +## Rego mapping + +The scenario pack in `../packs/iac-code-high-availability-pack.rego` lists the rule ids enforced for this scenario. Rules use `package infraguard.rules.aliyun.`, `rule_meta`, and `deny contains result if` in the official InfraGuard style. diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/mongodb-instance-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/mongodb-instance-multi-zone.rego new file mode 100644 index 0000000..06a8eef --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/mongodb-instance-multi-zone.rego @@ -0,0 +1,70 @@ +package infraguard.rules.aliyun.mongodb_instance_multi_zone + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "mongodb-instance-multi-zone", + "severity": "medium", + "name": { + "en": "MongoDB Instance Multi-Zone Deployment", + "zh": "MongoDB 实例多可用区部署", + "ja": "MongoDB インスタンスのマルチゾーン展開", + "de": "MongoDB-Instanz Multi-Zone-Bereitstellung", + "es": "Despliegue Multi-zona de instancia MongoDB", + "fr": "Déploiement Multi-Zones d'instance MongoDB", + "pt": "Implantação Multi-zona de instância MongoDB", + }, + "description": { + "en": "MongoDB instances should configure a secondary or hidden zone for high availability.", + "zh": "MongoDB 实例应配置备用可用区或隐藏可用区以实现高可用。", + "ja": "MongoDB インスタンスは高可用性のためにセカンダリゾーンまたは隠しゾーンを設定する必要があります。", + "de": "MongoDB-Instanzen sollten für Hochverfügbarkeit eine sekundäre oder versteckte Zone konfigurieren.", + "es": "Las instancias MongoDB deben configurar una zona secundaria u oculta para alta disponibilidad.", + "fr": "Les instances MongoDB doivent configurer une zone secondaire ou cachée pour la haute disponibilité.", + "pt": "Instâncias MongoDB devem configurar uma zona secundária ou oculta para alta disponibilidade.", + }, + "reason": { + "en": "The MongoDB instance does not have a secondary or hidden zone configured.", + "zh": "MongoDB 实例未配置备用可用区或隐藏可用区。", + "ja": "MongoDB インスタンスにセカンダリゾーンまたは隠しゾーンが設定されていません。", + "de": "Die MongoDB-Instanz hat keine sekundäre oder versteckte Zone konfiguriert.", + "es": "La instancia MongoDB no tiene configurada una zona secundaria u oculta.", + "fr": "L'instance MongoDB n'a pas de zone secondaire ou cachée configurée.", + "pt": "A instância MongoDB não tem uma zona secundária ou oculta configurada.", + }, + "recommendation": { + "en": "Configure SecondaryZoneId or HiddenZoneId to enable multi-zone deployment.", + "zh": "配置 SecondaryZoneId 或 HiddenZoneId 以启用多可用区部署。", + "ja": "SecondaryZoneId または HiddenZoneId を設定してマルチゾーン展開を有効にします。", + "de": "Konfigurieren Sie SecondaryZoneId oder HiddenZoneId, um Multi-Zone-Bereitstellung zu aktivieren.", + "es": "Configure SecondaryZoneId o HiddenZoneId para habilitar el despliegue multi-zona.", + "fr": "Configurez SecondaryZoneId ou HiddenZoneId pour activer le déploiement multi-zones.", + "pt": "Configure SecondaryZoneId ou HiddenZoneId para habilitar implantação multi-zona.", + }, + "resource_types": ["ALIYUN::MONGODB::Instance"], +} + +is_multi_zone(resource) if { + object.get(resource.Properties, "SecondaryZoneId", "") != "" +} + +is_multi_zone(resource) if { + object.get(resource.Properties, "HiddenZoneId", "") != "" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::MONGODB::Instance") + not is_multi_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/nlb-loadbalancer-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/nlb-loadbalancer-multi-zone.rego new file mode 100644 index 0000000..25c9bec --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/nlb-loadbalancer-multi-zone.rego @@ -0,0 +1,67 @@ +package infraguard.rules.aliyun.nlb_loadbalancer_multi_zone + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "nlb-loadbalancer-multi-zone", + "severity": "high", + "name": { + "en": "NLB Load Balancer Multi-Zone Deployment", + "zh": "使用多可用区的 NLB 实例", + "ja": "NLB ロードバランサーのマルチゾーン展開", + "de": "NLB Load Balancer Multi-Zone-Bereitstellung", + "es": "Implementación Multi-zona del Balanceador NLB", + "fr": "Déploiement Multi-Zones de l'Équilibreur NLB", + "pt": "Implantação Multi-zona do Balanceador NLB", + }, + "description": { + "en": "NLB instances should span at least two zones to support active-active traffic distribution and zone failover.", + "zh": "NLB 实例应跨至少两个可用区,以支持多可用区主动主动流量分发和可用区故障转移。", + "ja": "NLB インスタンスは、アクティブアクティブのトラフィック分散とゾーンフェイルオーバーをサポートするため、少なくとも 2 つのゾーンにまたがる必要があります。", + "de": "NLB-Instanzen sollten mindestens zwei Zonen umfassen, um Active-Active-Traffic-Verteilung und Zonen-Failover zu unterstützen.", + "es": "Las instancias NLB deben abarcar al menos dos zonas para admitir distribución de tráfico activo-activo y conmutación por error de zona.", + "fr": "Les instances NLB doivent couvrir au moins deux zones pour prendre en charge la distribution de trafic actif-actif et le basculement de zone.", + "pt": "Instâncias NLB devem abranger pelo menos duas zonas para oferecer distribuição de tráfego ativo-ativo e failover de zona.", + }, + "reason": { + "en": "The NLB instance is deployed in fewer than two availability zones, which weakens zone-level disaster recovery.", + "zh": "NLB 实例部署在少于两个可用区,削弱了可用区级容灾能力。", + "ja": "NLB インスタンスが 2 つ未満の可用性ゾーンに展開されているため、ゾーンレベルの災害復旧能力が低下します。", + "de": "Die NLB-Instanz ist in weniger als zwei Verfügbarkeitszonen bereitgestellt, wodurch die zonenbezogene Disaster-Recovery-Fähigkeit geschwächt wird.", + "es": "La instancia NLB está implementada en menos de dos zonas de disponibilidad, lo que debilita la recuperación ante desastres a nivel de zona.", + "fr": "L'instance NLB est déployée dans moins de deux zones de disponibilité, ce qui affaiblit la reprise après sinistre au niveau de la zone.", + "pt": "A instância NLB está implantada em menos de duas zonas de disponibilidade, enfraquecendo a recuperação de desastres no nível da zona.", + }, + "recommendation": { + "en": "Configure at least two zone mappings in ZoneMappings.", + "zh": "在 ZoneMappings 中配置至少两个可用区映射。", + "ja": "ZoneMappings に少なくとも 2 つのゾーンマッピングを設定します。", + "de": "Konfigurieren Sie mindestens zwei Zonen-Zuordnungen in ZoneMappings.", + "es": "Configure al menos dos mapeos de zona en ZoneMappings.", + "fr": "Configurez au moins deux mappages de zone dans ZoneMappings.", + "pt": "Configure pelo menos dois mapeamentos de zona em ZoneMappings.", + }, + "resource_types": ["ALIYUN::NLB::LoadBalancer"], +} + +has_multiple_zones(resource) if { + zone_mappings := object.get(resource.Properties, "ZoneMappings", []) + count(zone_mappings) >= 2 +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::NLB::LoadBalancer") + not has_multiple_zones(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ZoneMappings"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/oss-zrs-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/oss-zrs-enabled.rego new file mode 100644 index 0000000..b813e13 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/oss-zrs-enabled.rego @@ -0,0 +1,67 @@ +package infraguard.rules.aliyun.oss_zrs_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-zrs-enabled", + "severity": "medium", + "name": { + "en": "OSS Bucket Zone-Redundant Storage Enabled", + "zh": "OSS Bucket 启用同城冗余存储", + "ja": "OSS バケットのゾーン冗長ストレージ有効化", + "de": "OSS-Bucket mit zonenredundantem Speicher", + "es": "Almacenamiento con redundancia de zona para bucket OSS", + "fr": "Stockage redondant par zone pour bucket OSS", + "pt": "Armazenamento com redundância de zona para bucket OSS", + }, + "description": { + "en": "OSS buckets should use zone-redundant storage to keep data available when one zone becomes unavailable.", + "zh": "OSS Bucket 应使用同城冗余存储,以便在单个可用区不可用时仍可访问数据。", + "ja": "OSS バケットは、1 つのゾーンが利用できなくなってもデータにアクセスできるように、ゾーン冗長ストレージを使用する必要があります。", + "de": "OSS-Buckets sollten zonenredundanten Speicher verwenden, damit Daten verfügbar bleiben, wenn eine Zone nicht verfügbar ist.", + "es": "Los buckets OSS deben usar almacenamiento con redundancia de zona para mantener los datos disponibles si una zona deja de estar disponible.", + "fr": "Les buckets OSS doivent utiliser le stockage redondant par zone afin que les données restent disponibles lorsqu'une zone devient indisponible.", + "pt": "Buckets OSS devem usar armazenamento com redundância de zona para manter os dados disponíveis quando uma zona ficar indisponível.", + }, + "reason": { + "en": "The OSS bucket does not use ZRS, so data availability depends on locally redundant storage.", + "zh": "OSS Bucket 未使用 ZRS,数据可用性依赖本地冗余存储。", + "ja": "OSS バケットが ZRS を使用していないため、データ可用性はローカル冗長ストレージに依存します。", + "de": "Der OSS-Bucket verwendet kein ZRS, daher hängt die Datenverfügbarkeit von lokal redundantem Speicher ab.", + "es": "El bucket OSS no usa ZRS, por lo que la disponibilidad de datos depende del almacenamiento redundante local.", + "fr": "Le bucket OSS n'utilise pas ZRS, la disponibilité des données dépend donc du stockage redondant local.", + "pt": "O bucket OSS não usa ZRS, portanto a disponibilidade dos dados depende de armazenamento redundante local.", + }, + "recommendation": { + "en": "Set RedundancyType to ZRS when creating the bucket.", + "zh": "创建 Bucket 时将 RedundancyType 设置为 ZRS。", + "ja": "バケット作成時に RedundancyType を ZRS に設定します。", + "de": "Setzen Sie RedundancyType beim Erstellen des Buckets auf ZRS.", + "es": "Establezca RedundancyType en ZRS al crear el bucket.", + "fr": "Définissez RedundancyType sur ZRS lors de la création du bucket.", + "pt": "Defina RedundancyType como ZRS ao criar o bucket.", + }, + "resource_types": ["ALIYUN::OSS::Bucket"], +} + +has_zrs_enabled(resource) if { + redundancy_type := helpers.get_property(resource, "RedundancyType", "LRS") + redundancy_type == "ZRS" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not has_zrs_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "RedundancyType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/polardb-cluster-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/polardb-cluster-multi-zone.rego new file mode 100644 index 0000000..5ab2eee --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/polardb-cluster-multi-zone.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.polardb_cluster_multi_zone + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "polardb-cluster-multi-zone", + "severity": "medium", + "name": { + "en": "PolarDB Cluster Multi-Zone Deployment", + "zh": "PolarDB 集群多可用区部署", + "ja": "PolarDB クラスタのマルチゾーン展開", + "de": "PolarDB-Cluster Multi-Zone-Bereitstellung", + "es": "Implementación Multi-zona de clúster PolarDB", + "fr": "Déploiement Multi-Zones du cluster PolarDB", + "pt": "Implantação Multi-zona de cluster PolarDB", + }, + "description": { + "en": "PolarDB clusters should configure a standby availability zone for zone-level failover.", + "zh": "PolarDB 集群应配置备用可用区,以支持可用区级故障转移。", + "ja": "PolarDB クラスタは、ゾーンレベルのフェイルオーバーのためにスタンバイ可用性ゾーンを設定する必要があります。", + "de": "PolarDB-Cluster sollten eine Standby-Verfügbarkeitszone für zonenbezogenes Failover konfigurieren.", + "es": "Los clústeres PolarDB deben configurar una zona de disponibilidad en espera para la conmutación por error a nivel de zona.", + "fr": "Les clusters PolarDB doivent configurer une zone de disponibilité de secours pour le basculement au niveau de la zone.", + "pt": "Clusters PolarDB devem configurar uma zona de disponibilidade em espera para failover no nível da zona.", + }, + "reason": { + "en": "The PolarDB cluster does not have a standby availability zone configured.", + "zh": "PolarDB 集群未配置备用可用区。", + "ja": "PolarDB クラスタにスタンバイ可用性ゾーンが設定されていません。", + "de": "Der PolarDB-Cluster hat keine Standby-Verfügbarkeitszone konfiguriert.", + "es": "El clúster PolarDB no tiene configurada una zona de disponibilidad en espera.", + "fr": "Le cluster PolarDB n'a pas de zone de disponibilité de secours configurée.", + "pt": "O cluster PolarDB não tem uma zona de disponibilidade em espera configurada.", + }, + "recommendation": { + "en": "Configure StandbyAZ to enable multi-zone deployment.", + "zh": "配置 StandbyAZ 以启用多可用区部署。", + "ja": "マルチゾーン展開を有効にするために StandbyAZ を設定します。", + "de": "Konfigurieren Sie StandbyAZ, um Multi-Zone-Bereitstellung zu aktivieren.", + "es": "Configure StandbyAZ para habilitar la implementación multi-zona.", + "fr": "Configurez StandbyAZ pour activer le déploiement multi-zones.", + "pt": "Configure StandbyAZ para habilitar implantação multi-zona.", + }, + "resource_types": ["ALIYUN::POLARDB::DBCluster"], +} + +is_multi_zone(resource) if { + object.get(resource.Properties, "StandbyAZ", "") != "" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::POLARDB::DBCluster") + not is_multi_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "StandbyAZ"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-secondary-zone-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-secondary-zone-required.rego new file mode 100644 index 0000000..9f9800c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-secondary-zone-required.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.rds_instance_secondary_zone_required + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "rds-instance-secondary-zone-required", + "severity": "high", + "name": { + "en": "RDS Instance Secondary Zone Required", + "zh": "RDS 实例必须配置备用可用区", + "ja": "RDS インスタンスのセカンダリゾーン必須", + "de": "Sekundäre Zone für RDS-Instanz erforderlich", + "es": "Zona secundaria requerida para instancia RDS", + "fr": "Zone secondaire requise pour l'instance RDS", + "pt": "Zona secundária obrigatória para instância RDS", + }, + "description": { + "en": "RDS high-availability deployments should place the secondary instance in another zone.", + "zh": "RDS 高可用部署应将备实例放置在另一个可用区。", + "ja": "RDS 高可用性展開では、セカンダリインスタンスを別のゾーンに配置する必要があります。", + "de": "RDS-Hochverfügbarkeitsbereitstellungen sollten die sekundäre Instanz in einer anderen Zone platzieren.", + "es": "Las implementaciones RDS de alta disponibilidad deben ubicar la instancia secundaria en otra zona.", + "fr": "Les déploiements RDS haute disponibilité doivent placer l'instance secondaire dans une autre zone.", + "pt": "Implantações RDS de alta disponibilidade devem colocar a instância secundária em outra zona.", + }, + "reason": { + "en": "The RDS instance does not specify ZoneIdSlave1.", + "zh": "RDS 实例未指定 ZoneIdSlave1。", + "ja": "RDS インスタンスで ZoneIdSlave1 が指定されていません。", + "de": "Die RDS-Instanz gibt ZoneIdSlave1 nicht an.", + "es": "La instancia RDS no especifica ZoneIdSlave1.", + "fr": "L'instance RDS ne spécifie pas ZoneIdSlave1.", + "pt": "A instância RDS não especifica ZoneIdSlave1.", + }, + "recommendation": { + "en": "Configure ZoneIdSlave1 for cross-zone high availability.", + "zh": "配置 ZoneIdSlave1 以支持跨可用区高可用。", + "ja": "クロスゾーン高可用性のために ZoneIdSlave1 を設定します。", + "de": "Konfigurieren Sie ZoneIdSlave1 für zonenübergreifende Hochverfügbarkeit.", + "es": "Configure ZoneIdSlave1 para alta disponibilidad entre zonas.", + "fr": "Configurez ZoneIdSlave1 pour la haute disponibilité entre zones.", + "pt": "Configure ZoneIdSlave1 para alta disponibilidade entre zonas.", + }, + "resource_types": ["ALIYUN::RDS::DBInstance"], +} + +has_secondary_zone(resource) if { + object.get(resource.Properties, "ZoneIdSlave1", "") != "" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not has_secondary_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ZoneIdSlave1"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-zone-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-zone-required.rego new file mode 100644 index 0000000..a467dc4 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/rds-instance-zone-required.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.rds_instance_zone_required + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "rds-instance-zone-required", + "severity": "medium", + "name": { + "en": "RDS Instance Primary Zone Required", + "zh": "RDS 实例必须配置主可用区", + "ja": "RDS インスタンスのプライマリゾーン必須", + "de": "Primäre Zone für RDS-Instanz erforderlich", + "es": "Zona primaria requerida para instancia RDS", + "fr": "Zone principale requise pour l'instance RDS", + "pt": "Zona primária obrigatória para instância RDS", + }, + "description": { + "en": "RDS instances should explicitly configure the primary zone used for placement and failover planning.", + "zh": "RDS 实例应显式配置主可用区,用于资源放置和故障转移规划。", + "ja": "RDS インスタンスは、配置とフェイルオーバー計画に使用するプライマリゾーンを明示的に設定する必要があります。", + "de": "RDS-Instanzen sollten die primäre Zone für Platzierung und Failover-Planung explizit konfigurieren.", + "es": "Las instancias RDS deben configurar explícitamente la zona primaria usada para ubicación y planificación de failover.", + "fr": "Les instances RDS doivent configurer explicitement la zone principale utilisée pour le placement et la planification du basculement.", + "pt": "Instâncias RDS devem configurar explicitamente a zona primária usada para posicionamento e planejamento de failover.", + }, + "reason": { + "en": "The RDS instance does not specify ZoneId.", + "zh": "RDS 实例未指定 ZoneId。", + "ja": "RDS インスタンスで ZoneId が指定されていません。", + "de": "Die RDS-Instanz gibt ZoneId nicht an.", + "es": "La instancia RDS no especifica ZoneId.", + "fr": "L'instance RDS ne spécifie pas ZoneId.", + "pt": "A instância RDS não especifica ZoneId.", + }, + "recommendation": { + "en": "Configure ZoneId on the RDS instance.", + "zh": "在 RDS 实例上配置 ZoneId。", + "ja": "RDS インスタンスに ZoneId を設定します。", + "de": "Konfigurieren Sie ZoneId für die RDS-Instanz.", + "es": "Configure ZoneId en la instancia RDS.", + "fr": "Configurez ZoneId sur l'instance RDS.", + "pt": "Configure ZoneId na instância RDS.", + }, + "resource_types": ["ALIYUN::RDS::DBInstance"], +} + +has_zone(resource) if { + object.get(resource.Properties, "ZoneId", "") != "" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not has_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ZoneId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/redis-instance-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/redis-instance-multi-zone.rego new file mode 100644 index 0000000..7d2b8bc --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/redis-instance-multi-zone.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.redis_instance_multi_zone + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "redis-instance-multi-zone", + "severity": "medium", + "name": { + "en": "Redis Instance Multi-Zone Deployment", + "zh": "Redis 实例多可用区部署", + "ja": "Redis インスタンスのマルチゾーン展開", + "de": "Redis-Instanz Multi-Zone-Bereitstellung", + "es": "Despliegue Multi-zona de instancia Redis", + "fr": "Déploiement Multi-Zones d'instance Redis", + "pt": "Implantação Multi-zona de instância Redis", + }, + "description": { + "en": "Redis instances should configure a secondary zone for high availability.", + "zh": "Redis 实例应配置备用可用区以实现高可用。", + "ja": "Redis インスタンスは高可用性のためにセカンダリゾーンを設定する必要があります。", + "de": "Redis-Instanzen sollten für Hochverfügbarkeit eine sekundäre Zone konfigurieren.", + "es": "Las instancias Redis deben configurar una zona secundaria para alta disponibilidad.", + "fr": "Les instances Redis doivent configurer une zone secondaire pour la haute disponibilité.", + "pt": "Instâncias Redis devem configurar uma zona secundária para alta disponibilidade.", + }, + "reason": { + "en": "The Redis instance does not have a secondary zone configured.", + "zh": "Redis 实例未配置备用可用区。", + "ja": "Redis インスタンスにセカンダリゾーンが設定されていません。", + "de": "Die Redis-Instanz hat keine sekundäre Zone konfiguriert.", + "es": "La instancia Redis no tiene configurada una zona secundaria.", + "fr": "L'instance Redis n'a pas de zone secondaire configurée.", + "pt": "A instância Redis não tem uma zona secundária configurada.", + }, + "recommendation": { + "en": "Configure SecondaryZoneId to enable multi-zone deployment.", + "zh": "配置 SecondaryZoneId 以启用多可用区部署。", + "ja": "マルチゾーン展開を有効にするために SecondaryZoneId を設定します。", + "de": "Konfigurieren Sie SecondaryZoneId, um Multi-Zone-Bereitstellung zu aktivieren.", + "es": "Configure SecondaryZoneId para habilitar la implementación multi-zona.", + "fr": "Configurez SecondaryZoneId pour activer le déploiement multi-zones.", + "pt": "Configure SecondaryZoneId para habilitar implantação multi-zona.", + }, + "resource_types": ["ALIYUN::REDIS::Instance"], +} + +is_multi_zone(resource) if { + object.get(resource.Properties, "SecondaryZoneId", "") != "" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::REDIS::Instance") + not is_multi_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SecondaryZoneId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-master-zone-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-master-zone-required.rego new file mode 100644 index 0000000..bc5b48c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-master-zone-required.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.slb_instance_master_zone_required + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "slb-instance-master-zone-required", + "severity": "medium", + "name": { + "en": "SLB Instance Master Zone Required", + "zh": "SLB 实例必须配置主可用区", + "ja": "SLB インスタンスのマスターゾーン必須", + "de": "Master-Zone für SLB-Instanz erforderlich", + "es": "Zona maestra requerida para instancia SLB", + "fr": "Zone maître requise pour l'instance SLB", + "pt": "Zona mestre obrigatória para instância SLB", + }, + "description": { + "en": "SLB instances should configure a master zone as part of primary and secondary zone deployment.", + "zh": "SLB 实例应配置主可用区,作为主备可用区部署的一部分。", + "ja": "SLB インスタンスは、プライマリ/セカンダリゾーン展開の一部としてマスターゾーンを設定する必要があります。", + "de": "SLB-Instanzen sollten als Teil der primären und sekundären Zonenbereitstellung eine Master-Zone konfigurieren.", + "es": "Las instancias SLB deben configurar una zona maestra como parte del despliegue de zonas primaria y secundaria.", + "fr": "Les instances SLB doivent configurer une zone maître dans le cadre du déploiement des zones principale et secondaire.", + "pt": "Instâncias SLB devem configurar uma zona mestre como parte da implantação de zonas primária e secundária.", + }, + "reason": { + "en": "The SLB instance does not specify MasterZoneId.", + "zh": "SLB 实例未指定 MasterZoneId。", + "ja": "SLB インスタンスで MasterZoneId が指定されていません。", + "de": "Die SLB-Instanz gibt MasterZoneId nicht an.", + "es": "La instancia SLB no especifica MasterZoneId.", + "fr": "L'instance SLB ne spécifie pas MasterZoneId.", + "pt": "A instância SLB não especifica MasterZoneId.", + }, + "recommendation": { + "en": "Configure MasterZoneId on the SLB instance.", + "zh": "在 SLB 实例上配置 MasterZoneId。", + "ja": "SLB インスタンスに MasterZoneId を設定します。", + "de": "Konfigurieren Sie MasterZoneId für die SLB-Instanz.", + "es": "Configure MasterZoneId en la instancia SLB.", + "fr": "Configurez MasterZoneId sur l'instance SLB.", + "pt": "Configure MasterZoneId na instância SLB.", + }, + "resource_types": ["ALIYUN::SLB::LoadBalancer"], +} + +has_master_zone(resource) if { + object.get(resource.Properties, "MasterZoneId", "") != "" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLB::LoadBalancer") + not has_master_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MasterZoneId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-multi-zone.rego new file mode 100644 index 0000000..d477f87 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/high-availability/slb-instance-multi-zone.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.slb_instance_multi_zone + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "slb-instance-multi-zone", + "severity": "high", + "name": { + "en": "SLB Instance Multi-Zone Deployment", + "zh": "SLB 实例多可用区部署", + "ja": "SLB インスタンスのマルチゾーン展開", + "de": "SLB-Instanz Multi-Zone-Bereitstellung", + "es": "Implementación Multi-zona de instancia SLB", + "fr": "Déploiement Multi-Zones de l'instance SLB", + "pt": "Implantação Multi-zona de instância SLB", + }, + "description": { + "en": "SLB instances should configure a secondary zone for cross-zone failover.", + "zh": "SLB 实例应配置备可用区,以支持跨可用区故障转移。", + "ja": "SLB インスタンスは、クロスゾーンフェイルオーバーのためにセカンダリゾーンを設定する必要があります。", + "de": "SLB-Instanzen sollten für zonenübergreifendes Failover eine sekundäre Zone konfigurieren.", + "es": "Las instancias SLB deben configurar una zona secundaria para failover entre zonas.", + "fr": "Les instances SLB doivent configurer une zone secondaire pour le basculement entre zones.", + "pt": "Instâncias SLB devem configurar uma zona secundária para failover entre zonas.", + }, + "reason": { + "en": "The SLB instance does not have SlaveZoneId configured.", + "zh": "SLB 实例未配置 SlaveZoneId。", + "ja": "SLB インスタンスに SlaveZoneId が設定されていません。", + "de": "Die SLB-Instanz hat SlaveZoneId nicht konfiguriert.", + "es": "La instancia SLB no tiene configurado SlaveZoneId.", + "fr": "L'instance SLB n'a pas SlaveZoneId configuré.", + "pt": "A instância SLB não tem SlaveZoneId configurado.", + }, + "recommendation": { + "en": "Configure SlaveZoneId to enable multi-zone deployment.", + "zh": "配置 SlaveZoneId 以启用多可用区部署。", + "ja": "マルチゾーン展開を有効にするために SlaveZoneId を設定します。", + "de": "Konfigurieren Sie SlaveZoneId, um Multi-Zone-Bereitstellung zu aktivieren.", + "es": "Configure SlaveZoneId para habilitar la implementación multi-zona.", + "fr": "Configurez SlaveZoneId pour activer le déploiement multi-zones.", + "pt": "Configure SlaveZoneId para habilitar implantação multi-zona.", + }, + "resource_types": ["ALIYUN::SLB::LoadBalancer"], +} + +has_slave_zone(resource) if { + object.get(resource.Properties, "SlaveZoneId", "") != "" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLB::LoadBalancer") + not has_slave_zone(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SlaveZoneId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/lib/helpers.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/lib/helpers.rego new file mode 100644 index 0000000..a40633e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/lib/helpers.rego @@ -0,0 +1,327 @@ +# Package for InfraGuard helper functions +# These functions are built-in to InfraGuard and available in all policy files +# Usage: import data.infraguard.helpers +package infraguard.helpers + +import rego.v1 + +# ============================================================================ +# Value Checking Helpers +# ============================================================================ + +# Check if a value is true (handles string "true" as well) +is_true(v) if { + v == true +} + +is_true(v) if { + v == "true" +} + +# Check if a value is false (handles string "false" as well) +is_false(v) if { + v == false +} + +is_false(v) if { + v == "false" +} + +# Check if a value is in a list +includes(list, elem) if { + list[_] == elem +} + +# ============================================================================ +# Network Helpers +# ============================================================================ + +# Check if CIDR is public IPv4 (0.0.0.0/0) +is_public_cidr(cidr) if { + cidr == "0.0.0.0/0" +} + +# Check if CIDR is public IPv6 (::/0) +is_public_cidr(cidr) if { + cidr == "::/0" +} + +# Private IPv4 CIDR ranges (RFC 1918 and others) +private_cidrs := [ + "10.0.0.0/8", # Class A private + "172.16.0.0/12", # Class B private + "192.168.0.0/16", # Class C private + "127.0.0.0/8", # Loopback + "169.254.0.0/16", # Link-local + "100.64.0.0/10", # Carrier-grade NAT +] + +# Check if a CIDR/IP is within private ranges (not public internet) +# Returns true if the CIDR is private (not routable on public internet) +is_private_cidr(cidr) if { + some private_range in private_cidrs + net.cidr_contains(private_range, cidr) +} + +# Check if a CIDR/IP is a public internet address +# Returns true if the CIDR contains public internet IPs +is_internet_cidr(cidr) if { + # First check if it's a valid CIDR format (has /) + contains(cidr, "/") + + # If it's 0.0.0.0/0 or ::/0, it includes public internet + is_public_cidr(cidr) +} + +is_internet_cidr(cidr) if { + # Check if it contains public internet IPs (not in any private range) + contains(cidr, "/") + not is_private_cidr(cidr) + not is_public_cidr(cidr) +} + +is_internet_cidr(cidr) if { + # Handle single IP address (no CIDR notation) + not contains(cidr, "/") + + # Add /32 suffix and check + cidr_with_mask := concat("/", [cidr, "32"]) + not is_private_cidr(cidr_with_mask) +} + +# ============================================================================ +# Port Helpers +# ============================================================================ + +# Parse port range string (e.g., "22/22", "1/65535", "-1/-1") into [start, end] +parse_port_range(port_range) := [start, end] if { + parts := split(port_range, "/") + count(parts) == 2 + start := to_number(parts[0]) + end := to_number(parts[1]) +} + +# Check if a specific port is within a port range +port_in_range(port, port_range) if { + [start, end] := parse_port_range(port_range) + start != -1 + end != -1 + port >= start + port <= end +} + +# Check if port range is all ports (-1/-1) +is_all_ports(port_range) if { + port_range == "-1/-1" +} + +# ============================================================================ +# Resource Helpers +# ============================================================================ + +# Get all resources of a specific type as a map (name -> resource) +resources_by_type(resource_type) := resources if { + resources := {name: resource | + some name, resource in input.Resources + resource.Type == resource_type + } +} + +# Get all resources of multiple types as a map (name -> resource) +resources_by_types(resource_types) := resources if { + resources := {name: resource | + some name, resource in input.Resources + resource.Type in resource_types + } +} + +# Get all resource names of a specific type +resource_names_by_type(resource_type) := [name | + some name, res in input.Resources + res.Type == resource_type +] + +# Count resources of a specific type +count_resources_by_type(resource_type) := count(resources_by_type(resource_type)) + +# Check if a resource type exists in the template +resource_exists(resource_type) if { + count_resources_by_type(resource_type) > 0 +} + +# Check if a resource type does NOT exist in the template +resource_not_exists(resource_type) if { + count_resources_by_type(resource_type) == 0 +} + +# ============================================================================ +# Property Helpers +# ============================================================================ + +# Check if property exists and is not null +has_property(resource, prop) if { + resource.Properties[prop] != null +} + +# Get property with default value +get_property(resource, prop, default_value) := value if { + has_property(resource, prop) + value := resource.Properties[prop] +} else := default_value + +# ============================================================================ +# Reference Helpers +# ============================================================================ + +# Resolve a value (handles Ref) +# If v is {"Ref": "Name"}, returns "Name" +# Otherwise returns v +resolve_ref(v) := name if { + is_object(v) + name := v.Ref +} else := v + +# Check if a value refers to a specific resource (by logical ID) +# target_id is the Logical ID of the resource +is_referencing(val, target_id) if { + resolve_ref(val) == target_id +} + +# Resolve Fn::GetAtt reference +# If v is {"Fn::GetAtt": ["ResourceName", "PropertyName"]}, returns "ResourceName" +# Otherwise returns v +resolve_get_att(v) := name if { + is_object(v) + name := v["Fn::GetAtt"][0] +} else := v + +# Check if a value is a Fn::GetAtt reference to a specific resource +# target_id is the Logical ID of the resource +is_get_att_referencing(val, target_id) if { + resolve_get_att(val) == target_id +} + +# Check if a value matches a resource's identity (Logical ID or its name property) +# resource_id is the Logical ID of the resource +# name_prop is the property name that contains the actual resource name (e.g., "UserName") +matches_resource_id(val, resource_id, name_prop) if { + is_referencing(val, resource_id) +} + +matches_resource_id(val, resource_id, name_prop) if { + res := input.Resources[resource_id] + actual_name := get_property(res, name_prop, resource_id) + val == actual_name +} + +# Check if a resource is referenced by another resource's property +# target_id: Logical ID of the resource to check if it's referenced +# ref_resource_type: Type of resource that might reference it (e.g., "ALIYUN::ECS::DiskAttachment") +# property_path: Property path to check, supports paths like ["DiskId"] +is_referenced_by_property(target_id, ref_resource_type, property_path) if { + some name, ref_resource in resources_by_type(ref_resource_type) + count(property_path) == 1 + prop := property_path[0] + has_property(ref_resource, prop) + prop_value := ref_resource.Properties[prop] + is_referencing(prop_value, target_id) +} + +is_referenced_by_property(target_id, ref_resource_type, property_path) if { + some name, ref_resource in resources_by_type(ref_resource_type) + count(property_path) == 1 + prop := property_path[0] + has_property(ref_resource, prop) + prop_value := ref_resource.Properties[prop] + is_get_att_referencing(prop_value, target_id) +} + +# ============================================================================ +# Tag Helpers +# ============================================================================ + +# Get tags from resource, handling different tag property names +# Different resources may use different property names for tags: +# - Most resources: "Tags" (array of {Key, Value}) +# - Some resources: "Tag" (single object or array) +# - OSS Bucket: "Tags" (array of {Key, Value}) +get_resource_tags(resource) := tags if { + # Standard Tags property (array of {Key, Value}) + has_property(resource, "Tags") + tags := resource.Properties.Tags + is_array(tags) + count(tags) > 0 +} + +get_resource_tags(resource) := tags if { + # Alternative Tag property (array of {Key, Value}) + has_property(resource, "Tag") + tags := resource.Properties.Tag + is_array(tags) + count(tags) > 0 +} + +# Check if resource has any tags +has_tags(resource) if { + get_resource_tags(resource) != null +} + +# Check if resource has a specific tag key +has_tag_key(resource, tag_key) if { + tags := get_resource_tags(resource) + some tag in tags + tag.Key == tag_key +} + +# Get tag value by key +get_tag_value(resource, tag_key) := tag.Value if { + tags := get_resource_tags(resource) + some tag in tags + tag.Key == tag_key +} + +# Check if resource has a specific tag key-value pair +has_tag_key_value(resource, tag_key, tag_value) if { + tags := get_resource_tags(resource) + some tag in tags + tag.Key == tag_key + tag.Value == tag_value +} + +# Check if resource has a specific tag key-value pair (supports wildcards) +# tag_value_pattern can contain * and ? wildcards +# * matches any sequence of characters +# ? matches any single character +matches_tag_value(resource, tag_key, tag_value_pattern) if { + actual_value := get_tag_value(resource, tag_key) + + # Use regex matching for wildcard support + # Convert * to .* and ? to . for regex + regex_pattern := replace_wildcards(tag_value_pattern) + regex.match(regex_pattern, actual_value) +} + +# Convert wildcard pattern to regex pattern +# * -> .* +# ? -> . +replace_wildcards(pattern) := regex if { + # Replace * with .* and ? with . + regex := replace(replace(pattern, "*", ".*"), "?", ".") +} + +# Check if resource has all specified tags +# required_tags is an array of tag objects with Key and Value +has_all_tags(resource, required_tags) if { + # Check that all required tags exist and match + count(required_tags) == count([tag | + some tag in required_tags + has_tag_key_value(resource, tag.Key, tag.Value) + ]) +} + +# Check if resource has at least one of the specified tags +# tag_patterns is an array of tag objects with Key and Value (supports wildcards in Value) +has_any_tag(resource, tag_patterns) if { + some tag in tag_patterns + matches_tag_value(resource, tag.Key, tag.Value) +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/alb-address-type-intranet.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/alb-address-type-intranet.rego new file mode 100644 index 0000000..42d0ab0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/alb-address-type-intranet.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.alb_address_type_intranet + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "alb-address-type-intranet", + "severity": "medium", + "name": { + "en": "ALB should use intranet address type", + "zh": "ALB 应使用内网地址类型", + "ja": "ALB 应使用内网地址类型", + "de": "ALB 应使用内网地址类型", + "es": "ALB 应使用内网地址类型", + "fr": "ALB 应使用内网地址类型", + "pt": "ALB 应使用内网地址类型" + }, + "description": { + "en": "Checks ALB should use intranet address type", + "zh": "检查ALB 应使用内网地址类型", + "ja": "检查ALB 应使用内网地址类型", + "de": "检查ALB 应使用内网地址类型", + "es": "检查ALB 应使用内网地址类型", + "fr": "检查ALB 应使用内网地址类型", + "pt": "检查ALB 应使用内网地址类型" + }, + "reason": { + "en": "ALB should use intranet address type is not satisfied.", + "zh": "ALB 应使用内网地址类型未满足。", + "ja": "ALB 应使用内网地址类型未满足。", + "de": "ALB 应使用内网地址类型未满足。", + "es": "ALB 应使用内网地址类型未满足。", + "fr": "ALB 应使用内网地址类型未满足。", + "pt": "ALB 应使用内网地址类型未满足。" + }, + "recommendation": { + "en": "Configure AddressType on ALIYUN::ALB::LoadBalancer to satisfy the policy.", + "zh": "请在 ALIYUN::ALB::LoadBalancer 上配置 AddressType 以满足策略。", + "ja": "请在 ALIYUN::ALB::LoadBalancer 上配置 AddressType 以满足策略。", + "de": "请在 ALIYUN::ALB::LoadBalancer 上配置 AddressType 以满足策略。", + "es": "请在 ALIYUN::ALB::LoadBalancer 上配置 AddressType 以满足策略。", + "fr": "请在 ALIYUN::ALB::LoadBalancer 上配置 AddressType 以满足策略。", + "pt": "请在 ALIYUN::ALB::LoadBalancer 上配置 AddressType 以满足策略。" + }, + "resource_types": ["ALIYUN::ALB::LoadBalancer"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ALB::LoadBalancer") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AddressType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "AddressType", "") == "Intranet" +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/cen-instance-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/cen-instance-name-required.rego new file mode 100644 index 0000000..7698326 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/cen-instance-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.cen_instance_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "cen-instance-name-required", + "severity": "medium", + "name": { + "en": "CEN instance must configure name", + "zh": "CEN 实例必须配置名称", + "ja": "CEN 实例必须配置名称", + "de": "CEN 实例必须配置名称", + "es": "CEN 实例必须配置名称", + "fr": "CEN 实例必须配置名称", + "pt": "CEN 实例必须配置名称" + }, + "description": { + "en": "Checks CEN instance must configure name", + "zh": "检查CEN 实例必须配置名称", + "ja": "检查CEN 实例必须配置名称", + "de": "检查CEN 实例必须配置名称", + "es": "检查CEN 实例必须配置名称", + "fr": "检查CEN 实例必须配置名称", + "pt": "检查CEN 实例必须配置名称" + }, + "reason": { + "en": "CEN instance must configure name is not satisfied.", + "zh": "CEN 实例必须配置名称未满足。", + "ja": "CEN 实例必须配置名称未满足。", + "de": "CEN 实例必须配置名称未满足。", + "es": "CEN 实例必须配置名称未满足。", + "fr": "CEN 实例必须配置名称未满足。", + "pt": "CEN 实例必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure Name on ALIYUN::CEN::CenInstance to satisfy the policy.", + "zh": "请在 ALIYUN::CEN::CenInstance 上配置 Name 以满足策略。", + "ja": "请在 ALIYUN::CEN::CenInstance 上配置 Name 以满足策略。", + "de": "请在 ALIYUN::CEN::CenInstance 上配置 Name 以满足策略。", + "es": "请在 ALIYUN::CEN::CenInstance 上配置 Name 以满足策略。", + "fr": "请在 ALIYUN::CEN::CenInstance 上配置 Name 以满足策略。", + "pt": "请在 ALIYUN::CEN::CenInstance 上配置 Name 以满足策略。" + }, + "resource_types": ["ALIYUN::CEN::CenInstance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::CEN::CenInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Name"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Name") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/eip-explicit-bandwidth-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/eip-explicit-bandwidth-required.rego new file mode 100644 index 0000000..0cf1a25 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/eip-explicit-bandwidth-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.eip_explicit_bandwidth_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "eip-explicit-bandwidth-required", + "severity": "medium", + "name": { + "en": "EIP must configure bandwidth", + "zh": "EIP 必须配置带宽", + "ja": "EIP 必须配置带宽", + "de": "EIP 必须配置带宽", + "es": "EIP 必须配置带宽", + "fr": "EIP 必须配置带宽", + "pt": "EIP 必须配置带宽" + }, + "description": { + "en": "Checks EIP must configure bandwidth", + "zh": "检查EIP 必须配置带宽", + "ja": "检查EIP 必须配置带宽", + "de": "检查EIP 必须配置带宽", + "es": "检查EIP 必须配置带宽", + "fr": "检查EIP 必须配置带宽", + "pt": "检查EIP 必须配置带宽" + }, + "reason": { + "en": "EIP must configure bandwidth is not satisfied.", + "zh": "EIP 必须配置带宽未满足。", + "ja": "EIP 必须配置带宽未满足。", + "de": "EIP 必须配置带宽未满足。", + "es": "EIP 必须配置带宽未满足。", + "fr": "EIP 必须配置带宽未满足。", + "pt": "EIP 必须配置带宽未满足。" + }, + "recommendation": { + "en": "Configure Bandwidth on ALIYUN::VPC::EIP to satisfy the policy.", + "zh": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "ja": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "de": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "es": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "fr": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。", + "pt": "请在 ALIYUN::VPC::EIP 上配置 Bandwidth 以满足策略。" + }, + "resource_types": ["ALIYUN::VPC::EIP"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::VPC::EIP") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Bandwidth"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Bandwidth") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nat-gateway-vpc-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nat-gateway-vpc-required.rego new file mode 100644 index 0000000..c8184cd --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nat-gateway-vpc-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.nat_gateway_vpc_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "nat-gateway-vpc-required", + "severity": "high", + "name": { + "en": "NAT Gateway must bind VPC", + "zh": "NAT 网关必须绑定 VPC", + "ja": "NAT 网关必须绑定 VPC", + "de": "NAT 网关必须绑定 VPC", + "es": "NAT 网关必须绑定 VPC", + "fr": "NAT 网关必须绑定 VPC", + "pt": "NAT 网关必须绑定 VPC" + }, + "description": { + "en": "Checks NAT Gateway must bind VPC", + "zh": "检查NAT 网关必须绑定 VPC", + "ja": "检查NAT 网关必须绑定 VPC", + "de": "检查NAT 网关必须绑定 VPC", + "es": "检查NAT 网关必须绑定 VPC", + "fr": "检查NAT 网关必须绑定 VPC", + "pt": "检查NAT 网关必须绑定 VPC" + }, + "reason": { + "en": "NAT Gateway must bind VPC is not satisfied.", + "zh": "NAT 网关必须绑定 VPC未满足。", + "ja": "NAT 网关必须绑定 VPC未满足。", + "de": "NAT 网关必须绑定 VPC未满足。", + "es": "NAT 网关必须绑定 VPC未满足。", + "fr": "NAT 网关必须绑定 VPC未满足。", + "pt": "NAT 网关必须绑定 VPC未满足。" + }, + "recommendation": { + "en": "Configure VpcId on ALIYUN::VPC::NatGateway to satisfy the policy.", + "zh": "请在 ALIYUN::VPC::NatGateway 上配置 VpcId 以满足策略。", + "ja": "请在 ALIYUN::VPC::NatGateway 上配置 VpcId 以满足策略。", + "de": "请在 ALIYUN::VPC::NatGateway 上配置 VpcId 以满足策略。", + "es": "请在 ALIYUN::VPC::NatGateway 上配置 VpcId 以满足策略。", + "fr": "请在 ALIYUN::VPC::NatGateway 上配置 VpcId 以满足策略。", + "pt": "请在 ALIYUN::VPC::NatGateway 上配置 VpcId 以满足策略。" + }, + "resource_types": ["ALIYUN::VPC::NatGateway"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::VPC::NatGateway") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VpcId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VpcId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/network-architecture-usage-guidelines.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/network-architecture-usage-guidelines.md new file mode 100644 index 0000000..4aa06c6 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/network-architecture-usage-guidelines.md @@ -0,0 +1,22 @@ +# Network Architecture InfraGuard Usage Guidelines + +## Sources read + +- Local official InfraGuard repository: `/private/tmp/infraguard-official`. +- Alibaba Cloud ROS and Well-Architected official references for the scenario. +- Cross-cloud Well-Architected references were used as control-point background when available. + +## Write to Learn notes + +The scenario was reduced to static IaC checks only. Runtime metrics, billing history, incident evidence, and approval workflow evidence are kept out of Rego because they cannot be proven from a ROS template alone. + +## Engineer-facing guidelines + +- Prefer explicit resource intent over provider defaults. +- Make the policy failure point actionable through `violation_path`. +- Keep rule ids short and stable, without scenario prefixes. +- Keep exceptions outside Rego unless the exception is represented in the template itself. + +## Rego mapping + +The scenario pack in `../packs/iac-code-network-architecture-pack.rego` lists the rule ids enforced for this scenario. Rules use `package infraguard.rules.aliyun.`, `rule_meta`, and `deny contains result if` in the official InfraGuard style. diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nlb-address-type-intranet.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nlb-address-type-intranet.rego new file mode 100644 index 0000000..432a9e7 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/nlb-address-type-intranet.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.nlb_address_type_intranet + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "nlb-address-type-intranet", + "severity": "medium", + "name": { + "en": "NLB should use intranet address type", + "zh": "NLB 应使用内网地址类型", + "ja": "NLB 应使用内网地址类型", + "de": "NLB 应使用内网地址类型", + "es": "NLB 应使用内网地址类型", + "fr": "NLB 应使用内网地址类型", + "pt": "NLB 应使用内网地址类型" + }, + "description": { + "en": "Checks NLB should use intranet address type", + "zh": "检查NLB 应使用内网地址类型", + "ja": "检查NLB 应使用内网地址类型", + "de": "检查NLB 应使用内网地址类型", + "es": "检查NLB 应使用内网地址类型", + "fr": "检查NLB 应使用内网地址类型", + "pt": "检查NLB 应使用内网地址类型" + }, + "reason": { + "en": "NLB should use intranet address type is not satisfied.", + "zh": "NLB 应使用内网地址类型未满足。", + "ja": "NLB 应使用内网地址类型未满足。", + "de": "NLB 应使用内网地址类型未满足。", + "es": "NLB 应使用内网地址类型未满足。", + "fr": "NLB 应使用内网地址类型未满足。", + "pt": "NLB 应使用内网地址类型未满足。" + }, + "recommendation": { + "en": "Configure AddressType on ALIYUN::NLB::LoadBalancer to satisfy the policy.", + "zh": "请在 ALIYUN::NLB::LoadBalancer 上配置 AddressType 以满足策略。", + "ja": "请在 ALIYUN::NLB::LoadBalancer 上配置 AddressType 以满足策略。", + "de": "请在 ALIYUN::NLB::LoadBalancer 上配置 AddressType 以满足策略。", + "es": "请在 ALIYUN::NLB::LoadBalancer 上配置 AddressType 以满足策略。", + "fr": "请在 ALIYUN::NLB::LoadBalancer 上配置 AddressType 以满足策略。", + "pt": "请在 ALIYUN::NLB::LoadBalancer 上配置 AddressType 以满足策略。" + }, + "resource_types": ["ALIYUN::NLB::LoadBalancer"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::NLB::LoadBalancer") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AddressType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "AddressType", "") == "Intranet" +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-enterprise-type.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-enterprise-type.rego new file mode 100644 index 0000000..3c0bbcb --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-enterprise-type.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.security_group_enterprise_type + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-group-enterprise-type", + "severity": "medium", + "name": { + "en": "Security group must set type", + "zh": "安全组必须设置类型", + "ja": "安全组必须设置类型", + "de": "安全组必须设置类型", + "es": "安全组必须设置类型", + "fr": "安全组必须设置类型", + "pt": "安全组必须设置类型" + }, + "description": { + "en": "Checks Security group must set type", + "zh": "检查安全组必须设置类型", + "ja": "检查安全组必须设置类型", + "de": "检查安全组必须设置类型", + "es": "检查安全组必须设置类型", + "fr": "检查安全组必须设置类型", + "pt": "检查安全组必须设置类型" + }, + "reason": { + "en": "Security group must set type is not satisfied.", + "zh": "安全组必须设置类型未满足。", + "ja": "安全组必须设置类型未满足。", + "de": "安全组必须设置类型未满足。", + "es": "安全组必须设置类型未满足。", + "fr": "安全组必须设置类型未满足。", + "pt": "安全组必须设置类型未满足。" + }, + "recommendation": { + "en": "Configure SecurityGroupType on ALIYUN::ECS::SecurityGroup to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::SecurityGroup 上配置 SecurityGroupType 以满足策略。", + "ja": "请在 ALIYUN::ECS::SecurityGroup 上配置 SecurityGroupType 以满足策略。", + "de": "请在 ALIYUN::ECS::SecurityGroup 上配置 SecurityGroupType 以满足策略。", + "es": "请在 ALIYUN::ECS::SecurityGroup 上配置 SecurityGroupType 以满足策略。", + "fr": "请在 ALIYUN::ECS::SecurityGroup 上配置 SecurityGroupType 以满足策略。", + "pt": "请在 ALIYUN::ECS::SecurityGroup 上配置 SecurityGroupType 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::SecurityGroup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SecurityGroupType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "SecurityGroupType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-vpc-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-vpc-required.rego new file mode 100644 index 0000000..35d0bfb --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/security-group-vpc-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.security_group_vpc_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-group-vpc-required", + "severity": "high", + "name": { + "en": "Security group must bind VPC", + "zh": "安全组必须绑定 VPC", + "ja": "安全组必须绑定 VPC", + "de": "安全组必须绑定 VPC", + "es": "安全组必须绑定 VPC", + "fr": "安全组必须绑定 VPC", + "pt": "安全组必须绑定 VPC" + }, + "description": { + "en": "Checks Security group must bind VPC", + "zh": "检查安全组必须绑定 VPC", + "ja": "检查安全组必须绑定 VPC", + "de": "检查安全组必须绑定 VPC", + "es": "检查安全组必须绑定 VPC", + "fr": "检查安全组必须绑定 VPC", + "pt": "检查安全组必须绑定 VPC" + }, + "reason": { + "en": "Security group must bind VPC is not satisfied.", + "zh": "安全组必须绑定 VPC未满足。", + "ja": "安全组必须绑定 VPC未满足。", + "de": "安全组必须绑定 VPC未满足。", + "es": "安全组必须绑定 VPC未满足。", + "fr": "安全组必须绑定 VPC未满足。", + "pt": "安全组必须绑定 VPC未满足。" + }, + "recommendation": { + "en": "Configure VpcId on ALIYUN::ECS::SecurityGroup to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::SecurityGroup 上配置 VpcId 以满足策略。", + "ja": "请在 ALIYUN::ECS::SecurityGroup 上配置 VpcId 以满足策略。", + "de": "请在 ALIYUN::ECS::SecurityGroup 上配置 VpcId 以满足策略。", + "es": "请在 ALIYUN::ECS::SecurityGroup 上配置 VpcId 以满足策略。", + "fr": "请在 ALIYUN::ECS::SecurityGroup 上配置 VpcId 以满足策略。", + "pt": "请在 ALIYUN::ECS::SecurityGroup 上配置 VpcId 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::SecurityGroup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VpcId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VpcId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/slb-address-type-intranet.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/slb-address-type-intranet.rego new file mode 100644 index 0000000..6146d00 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/slb-address-type-intranet.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.slb_address_type_intranet + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "slb-address-type-intranet", + "severity": "medium", + "name": { + "en": "SLB should use intranet address type", + "zh": "SLB 应使用内网地址类型", + "ja": "SLB 应使用内网地址类型", + "de": "SLB 应使用内网地址类型", + "es": "SLB 应使用内网地址类型", + "fr": "SLB 应使用内网地址类型", + "pt": "SLB 应使用内网地址类型" + }, + "description": { + "en": "Checks SLB should use intranet address type", + "zh": "检查SLB 应使用内网地址类型", + "ja": "检查SLB 应使用内网地址类型", + "de": "检查SLB 应使用内网地址类型", + "es": "检查SLB 应使用内网地址类型", + "fr": "检查SLB 应使用内网地址类型", + "pt": "检查SLB 应使用内网地址类型" + }, + "reason": { + "en": "SLB should use intranet address type is not satisfied.", + "zh": "SLB 应使用内网地址类型未满足。", + "ja": "SLB 应使用内网地址类型未满足。", + "de": "SLB 应使用内网地址类型未满足。", + "es": "SLB 应使用内网地址类型未满足。", + "fr": "SLB 应使用内网地址类型未满足。", + "pt": "SLB 应使用内网地址类型未满足。" + }, + "recommendation": { + "en": "Configure AddressType on ALIYUN::SLB::LoadBalancer to satisfy the policy.", + "zh": "请在 ALIYUN::SLB::LoadBalancer 上配置 AddressType 以满足策略。", + "ja": "请在 ALIYUN::SLB::LoadBalancer 上配置 AddressType 以满足策略。", + "de": "请在 ALIYUN::SLB::LoadBalancer 上配置 AddressType 以满足策略。", + "es": "请在 ALIYUN::SLB::LoadBalancer 上配置 AddressType 以满足策略。", + "fr": "请在 ALIYUN::SLB::LoadBalancer 上配置 AddressType 以满足策略。", + "pt": "请在 ALIYUN::SLB::LoadBalancer 上配置 AddressType 以满足策略。" + }, + "resource_types": ["ALIYUN::SLB::LoadBalancer"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLB::LoadBalancer") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AddressType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "AddressType", "") == "intranet" +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/transit-router-vpc-attachment-multi-zone.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/transit-router-vpc-attachment-multi-zone.rego new file mode 100644 index 0000000..4ed2c56 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/transit-router-vpc-attachment-multi-zone.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.transit_router_vpc_attachment_multi_zone + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "transit-router-vpc-attachment-multi-zone", + "severity": "high", + "name": { + "en": "Transit router VPC attachment must configure zone mapping", + "zh": "转发路由器 VPC 连接必须配置可用区映射", + "ja": "转发路由器 VPC 连接必须配置可用区映射", + "de": "转发路由器 VPC 连接必须配置可用区映射", + "es": "转发路由器 VPC 连接必须配置可用区映射", + "fr": "转发路由器 VPC 连接必须配置可用区映射", + "pt": "转发路由器 VPC 连接必须配置可用区映射" + }, + "description": { + "en": "Checks Transit router VPC attachment must configure zone mapping", + "zh": "检查转发路由器 VPC 连接必须配置可用区映射", + "ja": "检查转发路由器 VPC 连接必须配置可用区映射", + "de": "检查转发路由器 VPC 连接必须配置可用区映射", + "es": "检查转发路由器 VPC 连接必须配置可用区映射", + "fr": "检查转发路由器 VPC 连接必须配置可用区映射", + "pt": "检查转发路由器 VPC 连接必须配置可用区映射" + }, + "reason": { + "en": "Transit router VPC attachment must configure zone mapping is not satisfied.", + "zh": "转发路由器 VPC 连接必须配置可用区映射未满足。", + "ja": "转发路由器 VPC 连接必须配置可用区映射未满足。", + "de": "转发路由器 VPC 连接必须配置可用区映射未满足。", + "es": "转发路由器 VPC 连接必须配置可用区映射未满足。", + "fr": "转发路由器 VPC 连接必须配置可用区映射未满足。", + "pt": "转发路由器 VPC 连接必须配置可用区映射未满足。" + }, + "recommendation": { + "en": "Configure ZoneMappings on ALIYUN::CEN::TransitRouterVpcAttachment to satisfy the policy.", + "zh": "请在 ALIYUN::CEN::TransitRouterVpcAttachment 上配置 ZoneMappings 以满足策略。", + "ja": "请在 ALIYUN::CEN::TransitRouterVpcAttachment 上配置 ZoneMappings 以满足策略。", + "de": "请在 ALIYUN::CEN::TransitRouterVpcAttachment 上配置 ZoneMappings 以满足策略。", + "es": "请在 ALIYUN::CEN::TransitRouterVpcAttachment 上配置 ZoneMappings 以满足策略。", + "fr": "请在 ALIYUN::CEN::TransitRouterVpcAttachment 上配置 ZoneMappings 以满足策略。", + "pt": "请在 ALIYUN::CEN::TransitRouterVpcAttachment 上配置 ZoneMappings 以满足策略。" + }, + "resource_types": ["ALIYUN::CEN::TransitRouterVpcAttachment"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::CEN::TransitRouterVpcAttachment") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ZoneMappings"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "ZoneMappings") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpc-cidr-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpc-cidr-required.rego new file mode 100644 index 0000000..aaf2b2f --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpc-cidr-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.vpc_cidr_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "vpc-cidr-required", + "severity": "high", + "name": { + "en": "VPC must configure CIDR block", + "zh": "VPC 必须配置网段", + "ja": "VPC 必须配置网段", + "de": "VPC 必须配置网段", + "es": "VPC 必须配置网段", + "fr": "VPC 必须配置网段", + "pt": "VPC 必须配置网段" + }, + "description": { + "en": "Checks VPC must configure CIDR block", + "zh": "检查VPC 必须配置网段", + "ja": "检查VPC 必须配置网段", + "de": "检查VPC 必须配置网段", + "es": "检查VPC 必须配置网段", + "fr": "检查VPC 必须配置网段", + "pt": "检查VPC 必须配置网段" + }, + "reason": { + "en": "VPC must configure CIDR block is not satisfied.", + "zh": "VPC 必须配置网段未满足。", + "ja": "VPC 必须配置网段未满足。", + "de": "VPC 必须配置网段未满足。", + "es": "VPC 必须配置网段未满足。", + "fr": "VPC 必须配置网段未满足。", + "pt": "VPC 必须配置网段未满足。" + }, + "recommendation": { + "en": "Configure CidrBlock on ALIYUN::ECS::VPC to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::VPC 上配置 CidrBlock 以满足策略。", + "ja": "请在 ALIYUN::ECS::VPC 上配置 CidrBlock 以满足策略。", + "de": "请在 ALIYUN::ECS::VPC 上配置 CidrBlock 以满足策略。", + "es": "请在 ALIYUN::ECS::VPC 上配置 CidrBlock 以满足策略。", + "fr": "请在 ALIYUN::ECS::VPC 上配置 CidrBlock 以满足策略。", + "pt": "请在 ALIYUN::ECS::VPC 上配置 CidrBlock 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::VPC"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::VPC") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "CidrBlock"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "CidrBlock") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpn-gateway-vpc-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpn-gateway-vpc-required.rego new file mode 100644 index 0000000..8cc7b1d --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vpn-gateway-vpc-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.vpn_gateway_vpc_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "vpn-gateway-vpc-required", + "severity": "high", + "name": { + "en": "VPN Gateway must bind VPC", + "zh": "VPN 网关必须绑定 VPC", + "ja": "VPN 网关必须绑定 VPC", + "de": "VPN 网关必须绑定 VPC", + "es": "VPN 网关必须绑定 VPC", + "fr": "VPN 网关必须绑定 VPC", + "pt": "VPN 网关必须绑定 VPC" + }, + "description": { + "en": "Checks VPN Gateway must bind VPC", + "zh": "检查VPN 网关必须绑定 VPC", + "ja": "检查VPN 网关必须绑定 VPC", + "de": "检查VPN 网关必须绑定 VPC", + "es": "检查VPN 网关必须绑定 VPC", + "fr": "检查VPN 网关必须绑定 VPC", + "pt": "检查VPN 网关必须绑定 VPC" + }, + "reason": { + "en": "VPN Gateway must bind VPC is not satisfied.", + "zh": "VPN 网关必须绑定 VPC未满足。", + "ja": "VPN 网关必须绑定 VPC未满足。", + "de": "VPN 网关必须绑定 VPC未满足。", + "es": "VPN 网关必须绑定 VPC未满足。", + "fr": "VPN 网关必须绑定 VPC未满足。", + "pt": "VPN 网关必须绑定 VPC未满足。" + }, + "recommendation": { + "en": "Configure VpcId on ALIYUN::VPC::VpnGateway to satisfy the policy.", + "zh": "请在 ALIYUN::VPC::VpnGateway 上配置 VpcId 以满足策略。", + "ja": "请在 ALIYUN::VPC::VpnGateway 上配置 VpcId 以满足策略。", + "de": "请在 ALIYUN::VPC::VpnGateway 上配置 VpcId 以满足策略。", + "es": "请在 ALIYUN::VPC::VpnGateway 上配置 VpcId 以满足策略。", + "fr": "请在 ALIYUN::VPC::VpnGateway 上配置 VpcId 以满足策略。", + "pt": "请在 ALIYUN::VPC::VpnGateway 上配置 VpcId 以满足策略。" + }, + "resource_types": ["ALIYUN::VPC::VpnGateway"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::VPC::VpnGateway") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VpcId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VpcId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-cidr-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-cidr-required.rego new file mode 100644 index 0000000..fa3d062 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-cidr-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.vswitch_cidr_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "vswitch-cidr-required", + "severity": "high", + "name": { + "en": "VSwitch must configure CIDR block", + "zh": "交换机必须配置网段", + "ja": "交换机必须配置网段", + "de": "交换机必须配置网段", + "es": "交换机必须配置网段", + "fr": "交换机必须配置网段", + "pt": "交换机必须配置网段" + }, + "description": { + "en": "Checks VSwitch must configure CIDR block", + "zh": "检查交换机必须配置网段", + "ja": "检查交换机必须配置网段", + "de": "检查交换机必须配置网段", + "es": "检查交换机必须配置网段", + "fr": "检查交换机必须配置网段", + "pt": "检查交换机必须配置网段" + }, + "reason": { + "en": "VSwitch must configure CIDR block is not satisfied.", + "zh": "交换机必须配置网段未满足。", + "ja": "交换机必须配置网段未满足。", + "de": "交换机必须配置网段未满足。", + "es": "交换机必须配置网段未满足。", + "fr": "交换机必须配置网段未满足。", + "pt": "交换机必须配置网段未满足。" + }, + "recommendation": { + "en": "Configure CidrBlock on ALIYUN::ECS::VSwitch to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::VSwitch 上配置 CidrBlock 以满足策略。", + "ja": "请在 ALIYUN::ECS::VSwitch 上配置 CidrBlock 以满足策略。", + "de": "请在 ALIYUN::ECS::VSwitch 上配置 CidrBlock 以满足策略。", + "es": "请在 ALIYUN::ECS::VSwitch 上配置 CidrBlock 以满足策略。", + "fr": "请在 ALIYUN::ECS::VSwitch 上配置 CidrBlock 以满足策略。", + "pt": "请在 ALIYUN::ECS::VSwitch 上配置 CidrBlock 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::VSwitch"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::VSwitch") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "CidrBlock"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "CidrBlock") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-zone-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-zone-required.rego new file mode 100644 index 0000000..4427adc --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/network-architecture/vswitch-zone-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.vswitch_zone_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "vswitch-zone-required", + "severity": "medium", + "name": { + "en": "VSwitch must configure zone", + "zh": "交换机必须配置可用区", + "ja": "交换机必须配置可用区", + "de": "交换机必须配置可用区", + "es": "交换机必须配置可用区", + "fr": "交换机必须配置可用区", + "pt": "交换机必须配置可用区" + }, + "description": { + "en": "Checks VSwitch must configure zone", + "zh": "检查交换机必须配置可用区", + "ja": "检查交换机必须配置可用区", + "de": "检查交换机必须配置可用区", + "es": "检查交换机必须配置可用区", + "fr": "检查交换机必须配置可用区", + "pt": "检查交换机必须配置可用区" + }, + "reason": { + "en": "VSwitch must configure zone is not satisfied.", + "zh": "交换机必须配置可用区未满足。", + "ja": "交换机必须配置可用区未满足。", + "de": "交换机必须配置可用区未满足。", + "es": "交换机必须配置可用区未满足。", + "fr": "交换机必须配置可用区未满足。", + "pt": "交换机必须配置可用区未满足。" + }, + "recommendation": { + "en": "Configure ZoneId on ALIYUN::ECS::VSwitch to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::VSwitch 上配置 ZoneId 以满足策略。", + "ja": "请在 ALIYUN::ECS::VSwitch 上配置 ZoneId 以满足策略。", + "de": "请在 ALIYUN::ECS::VSwitch 上配置 ZoneId 以满足策略。", + "es": "请在 ALIYUN::ECS::VSwitch 上配置 ZoneId 以满足策略。", + "fr": "请在 ALIYUN::ECS::VSwitch 上配置 ZoneId 以满足策略。", + "pt": "请在 ALIYUN::ECS::VSwitch 上配置 ZoneId 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::VSwitch"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::VSwitch") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ZoneId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "ZoneId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/actiontrail-trail-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/actiontrail-trail-name-required.rego new file mode 100644 index 0000000..a5f2b63 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/actiontrail-trail-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.actiontrail_trail_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "actiontrail-trail-name-required", + "severity": "medium", + "name": { + "en": "ActionTrail trail must configure name", + "zh": "ActionTrail 跟踪必须配置名称", + "ja": "ActionTrail 跟踪必须配置名称", + "de": "ActionTrail 跟踪必须配置名称", + "es": "ActionTrail 跟踪必须配置名称", + "fr": "ActionTrail 跟踪必须配置名称", + "pt": "ActionTrail 跟踪必须配置名称" + }, + "description": { + "en": "Checks ActionTrail trail must configure name", + "zh": "检查ActionTrail 跟踪必须配置名称", + "ja": "检查ActionTrail 跟踪必须配置名称", + "de": "检查ActionTrail 跟踪必须配置名称", + "es": "检查ActionTrail 跟踪必须配置名称", + "fr": "检查ActionTrail 跟踪必须配置名称", + "pt": "检查ActionTrail 跟踪必须配置名称" + }, + "reason": { + "en": "ActionTrail trail must configure name is not satisfied.", + "zh": "ActionTrail 跟踪必须配置名称未满足。", + "ja": "ActionTrail 跟踪必须配置名称未满足。", + "de": "ActionTrail 跟踪必须配置名称未满足。", + "es": "ActionTrail 跟踪必须配置名称未满足。", + "fr": "ActionTrail 跟踪必须配置名称未满足。", + "pt": "ActionTrail 跟踪必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure TrailName on ALIYUN::ACTIONTRAIL::Trail to satisfy the policy.", + "zh": "请在 ALIYUN::ACTIONTRAIL::Trail 上配置 TrailName 以满足策略。", + "ja": "请在 ALIYUN::ACTIONTRAIL::Trail 上配置 TrailName 以满足策略。", + "de": "请在 ALIYUN::ACTIONTRAIL::Trail 上配置 TrailName 以满足策略。", + "es": "请在 ALIYUN::ACTIONTRAIL::Trail 上配置 TrailName 以满足策略。", + "fr": "请在 ALIYUN::ACTIONTRAIL::Trail 上配置 TrailName 以满足策略。", + "pt": "请在 ALIYUN::ACTIONTRAIL::Trail 上配置 TrailName 以满足策略。" + }, + "resource_types": ["ALIYUN::ACTIONTRAIL::Trail"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ACTIONTRAIL::Trail") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "TrailName"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "TrailName") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/cms-alarm-name-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/cms-alarm-name-required.rego new file mode 100644 index 0000000..89bf84b --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/cms-alarm-name-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.cms_alarm_name_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "cms-alarm-name-required", + "severity": "medium", + "name": { + "en": "CMS alarm must configure name", + "zh": "云监控告警必须配置名称", + "ja": "云监控告警必须配置名称", + "de": "云监控告警必须配置名称", + "es": "云监控告警必须配置名称", + "fr": "云监控告警必须配置名称", + "pt": "云监控告警必须配置名称" + }, + "description": { + "en": "Checks CMS alarm must configure name", + "zh": "检查云监控告警必须配置名称", + "ja": "检查云监控告警必须配置名称", + "de": "检查云监控告警必须配置名称", + "es": "检查云监控告警必须配置名称", + "fr": "检查云监控告警必须配置名称", + "pt": "检查云监控告警必须配置名称" + }, + "reason": { + "en": "CMS alarm must configure name is not satisfied.", + "zh": "云监控告警必须配置名称未满足。", + "ja": "云监控告警必须配置名称未满足。", + "de": "云监控告警必须配置名称未满足。", + "es": "云监控告警必须配置名称未满足。", + "fr": "云监控告警必须配置名称未满足。", + "pt": "云监控告警必须配置名称未满足。" + }, + "recommendation": { + "en": "Configure Name on ALIYUN::CMS::Alarm to satisfy the policy.", + "zh": "请在 ALIYUN::CMS::Alarm 上配置 Name 以满足策略。", + "ja": "请在 ALIYUN::CMS::Alarm 上配置 Name 以满足策略。", + "de": "请在 ALIYUN::CMS::Alarm 上配置 Name 以满足策略。", + "es": "请在 ALIYUN::CMS::Alarm 上配置 Name 以满足策略。", + "fr": "请在 ALIYUN::CMS::Alarm 上配置 Name 以满足策略。", + "pt": "请在 ALIYUN::CMS::Alarm 上配置 Name 以满足策略。" + }, + "resource_types": ["ALIYUN::CMS::Alarm"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::CMS::Alarm") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Name"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "Name") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-disk-auto-snapshot-policy.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-disk-auto-snapshot-policy.rego new file mode 100644 index 0000000..e830a04 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-disk-auto-snapshot-policy.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_disk_auto_snapshot_policy + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-disk-auto-snapshot-policy", + "severity": "medium", + "name": { + "en": "ECS disk must attach auto snapshot policy", + "zh": "ECS 云盘必须绑定自动快照策略", + "ja": "ECS 云盘必须绑定自动快照策略", + "de": "ECS 云盘必须绑定自动快照策略", + "es": "ECS 云盘必须绑定自动快照策略", + "fr": "ECS 云盘必须绑定自动快照策略", + "pt": "ECS 云盘必须绑定自动快照策略" + }, + "description": { + "en": "Checks ECS disk must attach auto snapshot policy", + "zh": "检查ECS 云盘必须绑定自动快照策略", + "ja": "检查ECS 云盘必须绑定自动快照策略", + "de": "检查ECS 云盘必须绑定自动快照策略", + "es": "检查ECS 云盘必须绑定自动快照策略", + "fr": "检查ECS 云盘必须绑定自动快照策略", + "pt": "检查ECS 云盘必须绑定自动快照策略" + }, + "reason": { + "en": "ECS disk must attach auto snapshot policy is not satisfied.", + "zh": "ECS 云盘必须绑定自动快照策略未满足。", + "ja": "ECS 云盘必须绑定自动快照策略未满足。", + "de": "ECS 云盘必须绑定自动快照策略未满足。", + "es": "ECS 云盘必须绑定自动快照策略未满足。", + "fr": "ECS 云盘必须绑定自动快照策略未满足。", + "pt": "ECS 云盘必须绑定自动快照策略未满足。" + }, + "recommendation": { + "en": "Configure AutoSnapshotPolicyId on ALIYUN::ECS::Disk to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Disk 上配置 AutoSnapshotPolicyId 以满足策略。", + "ja": "请在 ALIYUN::ECS::Disk 上配置 AutoSnapshotPolicyId 以满足策略。", + "de": "请在 ALIYUN::ECS::Disk 上配置 AutoSnapshotPolicyId 以满足策略。", + "es": "请在 ALIYUN::ECS::Disk 上配置 AutoSnapshotPolicyId 以满足策略。", + "fr": "请在 ALIYUN::ECS::Disk 上配置 AutoSnapshotPolicyId 以满足策略。", + "pt": "请在 ALIYUN::ECS::Disk 上配置 AutoSnapshotPolicyId 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Disk"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Disk") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AutoSnapshotPolicyId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "AutoSnapshotPolicyId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-instance-operational-deletion-protection.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-instance-operational-deletion-protection.rego new file mode 100644 index 0000000..3fae247 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/ecs-instance-operational-deletion-protection.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.ecs_instance_operational_deletion_protection + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-instance-operational-deletion-protection", + "severity": "medium", + "name": { + "en": "ECS instance must enable deletion protection for operations", + "zh": "ECS 实例必须启用运维删除保护", + "ja": "ECS 实例必须启用运维删除保护", + "de": "ECS 实例必须启用运维删除保护", + "es": "ECS 实例必须启用运维删除保护", + "fr": "ECS 实例必须启用运维删除保护", + "pt": "ECS 实例必须启用运维删除保护" + }, + "description": { + "en": "Checks ECS instance must enable deletion protection for operations", + "zh": "检查ECS 实例必须启用运维删除保护", + "ja": "检查ECS 实例必须启用运维删除保护", + "de": "检查ECS 实例必须启用运维删除保护", + "es": "检查ECS 实例必须启用运维删除保护", + "fr": "检查ECS 实例必须启用运维删除保护", + "pt": "检查ECS 实例必须启用运维删除保护" + }, + "reason": { + "en": "ECS instance must enable deletion protection for operations is not satisfied.", + "zh": "ECS 实例必须启用运维删除保护未满足。", + "ja": "ECS 实例必须启用运维删除保护未满足。", + "de": "ECS 实例必须启用运维删除保护未满足。", + "es": "ECS 实例必须启用运维删除保护未满足。", + "fr": "ECS 实例必须启用运维删除保护未满足。", + "pt": "ECS 实例必须启用运维删除保护未满足。" + }, + "recommendation": { + "en": "Configure DeletionProtection on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 DeletionProtection 以满足策略。", + "ja": "请在 ALIYUN::ECS::Instance 上配置 DeletionProtection 以满足策略。", + "de": "请在 ALIYUN::ECS::Instance 上配置 DeletionProtection 以满足策略。", + "es": "请在 ALIYUN::ECS::Instance 上配置 DeletionProtection 以满足策略。", + "fr": "请在 ALIYUN::ECS::Instance 上配置 DeletionProtection 以满足策略。", + "pt": "请在 ALIYUN::ECS::Instance 上配置 DeletionProtection 以满足策略。" + }, + "resource_types": ["ALIYUN::ECS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DeletionProtection"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "DeletionProtection", false) == true +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-log-enable.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-log-enable.rego new file mode 100644 index 0000000..140a0d9 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-log-enable.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.fc_service_log_enable + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "fc-service-log-enable", + "severity": "medium", + "name": { + "en": "FC service must configure logging", + "zh": "函数计算服务必须配置日志", + "ja": "函数计算服务必须配置日志", + "de": "函数计算服务必须配置日志", + "es": "函数计算服务必须配置日志", + "fr": "函数计算服务必须配置日志", + "pt": "函数计算服务必须配置日志" + }, + "description": { + "en": "Checks FC service must configure logging", + "zh": "检查函数计算服务必须配置日志", + "ja": "检查函数计算服务必须配置日志", + "de": "检查函数计算服务必须配置日志", + "es": "检查函数计算服务必须配置日志", + "fr": "检查函数计算服务必须配置日志", + "pt": "检查函数计算服务必须配置日志" + }, + "reason": { + "en": "FC service must configure logging is not satisfied.", + "zh": "函数计算服务必须配置日志未满足。", + "ja": "函数计算服务必须配置日志未满足。", + "de": "函数计算服务必须配置日志未满足。", + "es": "函数计算服务必须配置日志未满足。", + "fr": "函数计算服务必须配置日志未满足。", + "pt": "函数计算服务必须配置日志未满足。" + }, + "recommendation": { + "en": "Configure LogConfig on ALIYUN::FC::Service to satisfy the policy.", + "zh": "请在 ALIYUN::FC::Service 上配置 LogConfig 以满足策略。", + "ja": "请在 ALIYUN::FC::Service 上配置 LogConfig 以满足策略。", + "de": "请在 ALIYUN::FC::Service 上配置 LogConfig 以满足策略。", + "es": "请在 ALIYUN::FC::Service 上配置 LogConfig 以满足策略。", + "fr": "请在 ALIYUN::FC::Service 上配置 LogConfig 以满足策略。", + "pt": "请在 ALIYUN::FC::Service 上配置 LogConfig 以满足策略。" + }, + "resource_types": ["ALIYUN::FC::Service"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::FC::Service") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LogConfig"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "LogConfig") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-tracing-enable.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-tracing-enable.rego new file mode 100644 index 0000000..8727fbb --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/fc-service-tracing-enable.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.fc_service_tracing_enable + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "fc-service-tracing-enable", + "severity": "medium", + "name": { + "en": "FC service must configure tracing", + "zh": "函数计算服务必须配置链路追踪", + "ja": "函数计算服务必须配置链路追踪", + "de": "函数计算服务必须配置链路追踪", + "es": "函数计算服务必须配置链路追踪", + "fr": "函数计算服务必须配置链路追踪", + "pt": "函数计算服务必须配置链路追踪" + }, + "description": { + "en": "Checks FC service must configure tracing", + "zh": "检查函数计算服务必须配置链路追踪", + "ja": "检查函数计算服务必须配置链路追踪", + "de": "检查函数计算服务必须配置链路追踪", + "es": "检查函数计算服务必须配置链路追踪", + "fr": "检查函数计算服务必须配置链路追踪", + "pt": "检查函数计算服务必须配置链路追踪" + }, + "reason": { + "en": "FC service must configure tracing is not satisfied.", + "zh": "函数计算服务必须配置链路追踪未满足。", + "ja": "函数计算服务必须配置链路追踪未满足。", + "de": "函数计算服务必须配置链路追踪未满足。", + "es": "函数计算服务必须配置链路追踪未满足。", + "fr": "函数计算服务必须配置链路追踪未满足。", + "pt": "函数计算服务必须配置链路追踪未满足。" + }, + "recommendation": { + "en": "Configure TracingConfig on ALIYUN::FC::Service to satisfy the policy.", + "zh": "请在 ALIYUN::FC::Service 上配置 TracingConfig 以满足策略。", + "ja": "请在 ALIYUN::FC::Service 上配置 TracingConfig 以满足策略。", + "de": "请在 ALIYUN::FC::Service 上配置 TracingConfig 以满足策略。", + "es": "请在 ALIYUN::FC::Service 上配置 TracingConfig 以满足策略。", + "fr": "请在 ALIYUN::FC::Service 上配置 TracingConfig 以满足策略。", + "pt": "请在 ALIYUN::FC::Service 上配置 TracingConfig 以满足策略。" + }, + "resource_types": ["ALIYUN::FC::Service"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::FC::Service") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "TracingConfig"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "TracingConfig") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/operations-usage-guidelines.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/operations-usage-guidelines.md new file mode 100644 index 0000000..fc0ea9e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/operations-usage-guidelines.md @@ -0,0 +1,22 @@ +# Operations InfraGuard Usage Guidelines + +## Sources read + +- Local official InfraGuard repository: `/private/tmp/infraguard-official`. +- Alibaba Cloud ROS and Well-Architected official references for the scenario. +- Cross-cloud Well-Architected references were used as control-point background when available. + +## Write to Learn notes + +The scenario was reduced to static IaC checks only. Runtime metrics, billing history, incident evidence, and approval workflow evidence are kept out of Rego because they cannot be proven from a ROS template alone. + +## Engineer-facing guidelines + +- Prefer explicit resource intent over provider defaults. +- Make the policy failure point actionable through `violation_path`. +- Keep rule ids short and stable, without scenario prefixes. +- Keep exceptions outside Rego unless the exception is represented in the template itself. + +## Rego mapping + +The scenario pack in `../packs/iac-code-operations-pack.rego` lists the rule ids enforced for this scenario. Rules use `package infraguard.rules.aliyun.`, `rule_meta`, and `deny contains result if` in the official InfraGuard style. diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/oss-bucket-operational-access-logging.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/oss-bucket-operational-access-logging.rego new file mode 100644 index 0000000..ffeff40 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/oss-bucket-operational-access-logging.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.oss_bucket_operational_access_logging + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-operational-access-logging", + "severity": "medium", + "name": { + "en": "OSS bucket must enable logging", + "zh": "OSS Bucket 必须启用日志", + "ja": "OSS Bucket 必须启用日志", + "de": "OSS Bucket 必须启用日志", + "es": "OSS Bucket 必须启用日志", + "fr": "OSS Bucket 必须启用日志", + "pt": "OSS Bucket 必须启用日志" + }, + "description": { + "en": "Checks OSS bucket must enable logging", + "zh": "检查OSS Bucket 必须启用日志", + "ja": "检查OSS Bucket 必须启用日志", + "de": "检查OSS Bucket 必须启用日志", + "es": "检查OSS Bucket 必须启用日志", + "fr": "检查OSS Bucket 必须启用日志", + "pt": "检查OSS Bucket 必须启用日志" + }, + "reason": { + "en": "OSS bucket must enable logging is not satisfied.", + "zh": "OSS Bucket 必须启用日志未满足。", + "ja": "OSS Bucket 必须启用日志未满足。", + "de": "OSS Bucket 必须启用日志未满足。", + "es": "OSS Bucket 必须启用日志未满足。", + "fr": "OSS Bucket 必须启用日志未满足。", + "pt": "OSS Bucket 必须启用日志未满足。" + }, + "recommendation": { + "en": "Configure LoggingConfiguration on ALIYUN::OSS::Bucket to satisfy the policy.", + "zh": "请在 ALIYUN::OSS::Bucket 上配置 LoggingConfiguration 以满足策略。", + "ja": "请在 ALIYUN::OSS::Bucket 上配置 LoggingConfiguration 以满足策略。", + "de": "请在 ALIYUN::OSS::Bucket 上配置 LoggingConfiguration 以满足策略。", + "es": "请在 ALIYUN::OSS::Bucket 上配置 LoggingConfiguration 以满足策略。", + "fr": "请在 ALIYUN::OSS::Bucket 上配置 LoggingConfiguration 以满足策略。", + "pt": "请在 ALIYUN::OSS::Bucket 上配置 LoggingConfiguration 以满足策略。" + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoggingConfiguration"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "LoggingConfiguration") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/polardb-cluster-delete-protection-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/polardb-cluster-delete-protection-enabled.rego new file mode 100644 index 0000000..1072061 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/polardb-cluster-delete-protection-enabled.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.polardb_cluster_delete_protection_enabled + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "polardb-cluster-delete-protection-enabled", + "severity": "medium", + "name": { + "en": "PolarDB cluster must enable deletion protection", + "zh": "PolarDB 集群必须启用删除保护", + "ja": "PolarDB 集群必须启用删除保护", + "de": "PolarDB 集群必须启用删除保护", + "es": "PolarDB 集群必须启用删除保护", + "fr": "PolarDB 集群必须启用删除保护", + "pt": "PolarDB 集群必须启用删除保护" + }, + "description": { + "en": "Checks PolarDB cluster must enable deletion protection", + "zh": "检查PolarDB 集群必须启用删除保护", + "ja": "检查PolarDB 集群必须启用删除保护", + "de": "检查PolarDB 集群必须启用删除保护", + "es": "检查PolarDB 集群必须启用删除保护", + "fr": "检查PolarDB 集群必须启用删除保护", + "pt": "检查PolarDB 集群必须启用删除保护" + }, + "reason": { + "en": "PolarDB cluster must enable deletion protection is not satisfied.", + "zh": "PolarDB 集群必须启用删除保护未满足。", + "ja": "PolarDB 集群必须启用删除保护未满足。", + "de": "PolarDB 集群必须启用删除保护未满足。", + "es": "PolarDB 集群必须启用删除保护未满足。", + "fr": "PolarDB 集群必须启用删除保护未满足。", + "pt": "PolarDB 集群必须启用删除保护未满足。" + }, + "recommendation": { + "en": "Configure DeletionProtection on ALIYUN::POLARDB::DBCluster to satisfy the policy.", + "zh": "请在 ALIYUN::POLARDB::DBCluster 上配置 DeletionProtection 以满足策略。", + "ja": "请在 ALIYUN::POLARDB::DBCluster 上配置 DeletionProtection 以满足策略。", + "de": "请在 ALIYUN::POLARDB::DBCluster 上配置 DeletionProtection 以满足策略。", + "es": "请在 ALIYUN::POLARDB::DBCluster 上配置 DeletionProtection 以满足策略。", + "fr": "请在 ALIYUN::POLARDB::DBCluster 上配置 DeletionProtection 以满足策略。", + "pt": "请在 ALIYUN::POLARDB::DBCluster 上配置 DeletionProtection 以满足策略。" + }, + "resource_types": ["ALIYUN::POLARDB::DBCluster"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::POLARDB::DBCluster") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DeletionProtection"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "DeletionProtection", false) == true +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-backup-policy-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-backup-policy-required.rego new file mode 100644 index 0000000..656e7d4 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-backup-policy-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.rds_backup_policy_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "rds-backup-policy-required", + "severity": "medium", + "name": { + "en": "RDS backup policy must be configured", + "zh": "RDS 必须配置备份策略", + "ja": "RDS 必须配置备份策略", + "de": "RDS 必须配置备份策略", + "es": "RDS 必须配置备份策略", + "fr": "RDS 必须配置备份策略", + "pt": "RDS 必须配置备份策略" + }, + "description": { + "en": "Checks RDS backup policy must be configured", + "zh": "检查RDS 必须配置备份策略", + "ja": "检查RDS 必须配置备份策略", + "de": "检查RDS 必须配置备份策略", + "es": "检查RDS 必须配置备份策略", + "fr": "检查RDS 必须配置备份策略", + "pt": "检查RDS 必须配置备份策略" + }, + "reason": { + "en": "RDS backup policy must be configured is not satisfied.", + "zh": "RDS 必须配置备份策略未满足。", + "ja": "RDS 必须配置备份策略未满足。", + "de": "RDS 必须配置备份策略未满足。", + "es": "RDS 必须配置备份策略未满足。", + "fr": "RDS 必须配置备份策略未满足。", + "pt": "RDS 必须配置备份策略未满足。" + }, + "recommendation": { + "en": "Configure BackupTime on ALIYUN::RDS::Backup to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::Backup 上配置 BackupTime 以满足策略。", + "ja": "请在 ALIYUN::RDS::Backup 上配置 BackupTime 以满足策略。", + "de": "请在 ALIYUN::RDS::Backup 上配置 BackupTime 以满足策略。", + "es": "请在 ALIYUN::RDS::Backup 上配置 BackupTime 以满足策略。", + "fr": "请在 ALIYUN::RDS::Backup 上配置 BackupTime 以满足策略。", + "pt": "请在 ALIYUN::RDS::Backup 上配置 BackupTime 以满足策略。" + }, + "resource_types": ["ALIYUN::RDS::Backup"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::Backup") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "BackupTime"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "BackupTime") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-instance-deletion-protection-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-instance-deletion-protection-enabled.rego new file mode 100644 index 0000000..9e0b4a3 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/rds-instance-deletion-protection-enabled.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.rds_instance_deletion_protection_enabled + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "rds-instance-deletion-protection-enabled", + "severity": "medium", + "name": { + "en": "RDS instance must enable deletion protection", + "zh": "RDS 实例必须启用删除保护", + "ja": "RDS 实例必须启用删除保护", + "de": "RDS 实例必须启用删除保护", + "es": "RDS 实例必须启用删除保护", + "fr": "RDS 实例必须启用删除保护", + "pt": "RDS 实例必须启用删除保护" + }, + "description": { + "en": "Checks RDS instance must enable deletion protection", + "zh": "检查RDS 实例必须启用删除保护", + "ja": "检查RDS 实例必须启用删除保护", + "de": "检查RDS 实例必须启用删除保护", + "es": "检查RDS 实例必须启用删除保护", + "fr": "检查RDS 实例必须启用删除保护", + "pt": "检查RDS 实例必须启用删除保护" + }, + "reason": { + "en": "RDS instance must enable deletion protection is not satisfied.", + "zh": "RDS 实例必须启用删除保护未满足。", + "ja": "RDS 实例必须启用删除保护未满足。", + "de": "RDS 实例必须启用删除保护未满足。", + "es": "RDS 实例必须启用删除保护未满足。", + "fr": "RDS 实例必须启用删除保护未满足。", + "pt": "RDS 实例必须启用删除保护未满足。" + }, + "recommendation": { + "en": "Configure DeletionProtection on ALIYUN::RDS::DBInstance to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::DBInstance 上配置 DeletionProtection 以满足策略。", + "ja": "请在 ALIYUN::RDS::DBInstance 上配置 DeletionProtection 以满足策略。", + "de": "请在 ALIYUN::RDS::DBInstance 上配置 DeletionProtection 以满足策略。", + "es": "请在 ALIYUN::RDS::DBInstance 上配置 DeletionProtection 以满足策略。", + "fr": "请在 ALIYUN::RDS::DBInstance 上配置 DeletionProtection 以满足策略。", + "pt": "请在 ALIYUN::RDS::DBInstance 上配置 DeletionProtection 以满足策略。" + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "DeletionProtection"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "DeletionProtection", false) == true +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/redis-backup-policy-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/redis-backup-policy-required.rego new file mode 100644 index 0000000..ea6bff6 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/redis-backup-policy-required.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.redis_backup_policy_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "redis-backup-policy-required", + "severity": "medium", + "name": { + "en": "Redis backup policy must be configured", + "zh": "Redis 必须配置备份策略", + "ja": "Redis 必须配置备份策略", + "de": "Redis 必须配置备份策略", + "es": "Redis 必须配置备份策略", + "fr": "Redis 必须配置备份策略", + "pt": "Redis 必须配置备份策略" + }, + "description": { + "en": "Checks Redis backup policy must be configured", + "zh": "检查Redis 必须配置备份策略", + "ja": "检查Redis 必须配置备份策略", + "de": "检查Redis 必须配置备份策略", + "es": "检查Redis 必须配置备份策略", + "fr": "检查Redis 必须配置备份策略", + "pt": "检查Redis 必须配置备份策略" + }, + "reason": { + "en": "Redis backup policy must be configured is not satisfied.", + "zh": "Redis 必须配置备份策略未满足。", + "ja": "Redis 必须配置备份策略未满足。", + "de": "Redis 必须配置备份策略未满足。", + "es": "Redis 必须配置备份策略未满足。", + "fr": "Redis 必须配置备份策略未满足。", + "pt": "Redis 必须配置备份策略未满足。" + }, + "recommendation": { + "en": "Configure BackupPolicy on ALIYUN::REDIS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::REDIS::Instance 上配置 BackupPolicy 以满足策略。", + "ja": "请在 ALIYUN::REDIS::Instance 上配置 BackupPolicy 以满足策略。", + "de": "请在 ALIYUN::REDIS::Instance 上配置 BackupPolicy 以满足策略。", + "es": "请在 ALIYUN::REDIS::Instance 上配置 BackupPolicy 以满足策略。", + "fr": "请在 ALIYUN::REDIS::Instance 上配置 BackupPolicy 以满足策略。", + "pt": "请在 ALIYUN::REDIS::Instance 上配置 BackupPolicy 以满足策略。" + }, + "resource_types": ["ALIYUN::REDIS::Instance"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::REDIS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "BackupPolicy"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "BackupPolicy") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-shard-count-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-shard-count-configured.rego new file mode 100644 index 0000000..c0f850b --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-shard-count-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.sls_logstore_shard_count_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "sls-logstore-shard-count-configured", + "severity": "medium", + "name": { + "en": "SLS Logstore must configure shard count", + "zh": "SLS Logstore 必须配置分区数", + "ja": "SLS Logstore 必须配置分区数", + "de": "SLS Logstore 必须配置分区数", + "es": "SLS Logstore 必须配置分区数", + "fr": "SLS Logstore 必须配置分区数", + "pt": "SLS Logstore 必须配置分区数" + }, + "description": { + "en": "Checks SLS Logstore must configure shard count", + "zh": "检查SLS Logstore 必须配置分区数", + "ja": "检查SLS Logstore 必须配置分区数", + "de": "检查SLS Logstore 必须配置分区数", + "es": "检查SLS Logstore 必须配置分区数", + "fr": "检查SLS Logstore 必须配置分区数", + "pt": "检查SLS Logstore 必须配置分区数" + }, + "reason": { + "en": "SLS Logstore must configure shard count is not satisfied.", + "zh": "SLS Logstore 必须配置分区数未满足。", + "ja": "SLS Logstore 必须配置分区数未满足。", + "de": "SLS Logstore 必须配置分区数未满足。", + "es": "SLS Logstore 必须配置分区数未满足。", + "fr": "SLS Logstore 必须配置分区数未满足。", + "pt": "SLS Logstore 必须配置分区数未满足。" + }, + "recommendation": { + "en": "Configure ShardCount on ALIYUN::SLS::Logstore to satisfy the policy.", + "zh": "请在 ALIYUN::SLS::Logstore 上配置 ShardCount 以满足策略。", + "ja": "请在 ALIYUN::SLS::Logstore 上配置 ShardCount 以满足策略。", + "de": "请在 ALIYUN::SLS::Logstore 上配置 ShardCount 以满足策略。", + "es": "请在 ALIYUN::SLS::Logstore 上配置 ShardCount 以满足策略。", + "fr": "请在 ALIYUN::SLS::Logstore 上配置 ShardCount 以满足策略。", + "pt": "请在 ALIYUN::SLS::Logstore 上配置 ShardCount 以满足策略。" + }, + "resource_types": ["ALIYUN::SLS::Logstore"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLS::Logstore") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ShardCount"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "ShardCount") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-ttl-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-ttl-configured.rego new file mode 100644 index 0000000..09fad6e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/operations/sls-logstore-ttl-configured.rego @@ -0,0 +1,65 @@ +package infraguard.rules.aliyun.sls_logstore_ttl_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "sls-logstore-ttl-configured", + "severity": "medium", + "name": { + "en": "SLS Logstore must configure TTL", + "zh": "SLS Logstore 必须配置 TTL", + "ja": "SLS Logstore 必须配置 TTL", + "de": "SLS Logstore 必须配置 TTL", + "es": "SLS Logstore 必须配置 TTL", + "fr": "SLS Logstore 必须配置 TTL", + "pt": "SLS Logstore 必须配置 TTL" + }, + "description": { + "en": "Checks SLS Logstore must configure TTL", + "zh": "检查SLS Logstore 必须配置 TTL", + "ja": "检查SLS Logstore 必须配置 TTL", + "de": "检查SLS Logstore 必须配置 TTL", + "es": "检查SLS Logstore 必须配置 TTL", + "fr": "检查SLS Logstore 必须配置 TTL", + "pt": "检查SLS Logstore 必须配置 TTL" + }, + "reason": { + "en": "SLS Logstore must configure TTL is not satisfied.", + "zh": "SLS Logstore 必须配置 TTL未满足。", + "ja": "SLS Logstore 必须配置 TTL未满足。", + "de": "SLS Logstore 必须配置 TTL未满足。", + "es": "SLS Logstore 必须配置 TTL未满足。", + "fr": "SLS Logstore 必须配置 TTL未满足。", + "pt": "SLS Logstore 必须配置 TTL未满足。" + }, + "recommendation": { + "en": "Configure TTL on ALIYUN::SLS::Logstore to satisfy the policy.", + "zh": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "ja": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "de": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "es": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "fr": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。", + "pt": "请在 ALIYUN::SLS::Logstore 上配置 TTL 以满足策略。" + }, + "resource_types": ["ALIYUN::SLS::Logstore"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::SLS::Logstore") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "TTL"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "TTL") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/cloud-infrastructure-security-baseline.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/cloud-infrastructure-security-baseline.rego new file mode 100644 index 0000000..422801f --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/cloud-infrastructure-security-baseline.rego @@ -0,0 +1,52 @@ +package infraguard.packs.aliyun.cloud_infrastructure_security_baseline + +import rego.v1 + +pack_meta := { + "id": "cloud-infrastructure-security-baseline", + "name": { + "en": "Cloud Infrastructure Security Baseline", + "zh": "云基础设施安全基线", + "ja": "クラウドインフラストラクチャセキュリティベースライン", + "de": "Cloud-Infrastruktur-Sicherheitsbaseline", + "es": "Línea Base de Seguridad de Infraestructura en la Nube", + "fr": "Référentiel de Sécurité de l'Infrastructure Cloud", + "pt": "Linha de Base de Segurança da Infraestrutura em Nuvem" + }, + "description": { + "en": "Baseline policies for identity, network exposure, data protection, audit logging, supply chain, and key management in Alibaba Cloud ROS templates.", + "zh": "面向阿里云 ROS 模板的身份、网络暴露、数据保护、审计日志、供应链和密钥管理安全基线。", + "ja": "Alibaba Cloud ROS テンプレートにおける ID、ネットワーク公開、データ保護、監査ログ、サプライチェーン、鍵管理のベースラインポリシー。", + "de": "Baseline-Richtlinien für Identität, Netzwerkexposition, Datenschutz, Audit-Protokollierung, Lieferkette und Schlüsselverwaltung in Alibaba Cloud ROS-Vorlagen.", + "es": "Políticas base para identidad, exposición de red, protección de datos, registro de auditoría, cadena de suministro y gestión de claves en plantillas ROS de Alibaba Cloud.", + "fr": "Politiques de base pour l'identité, l'exposition réseau, la protection des données, la journalisation d'audit, la chaîne d'approvisionnement et la gestion des clés dans les modèles ROS Alibaba Cloud.", + "pt": "Políticas de linha de base para identidade, exposição de rede, proteção de dados, logs de auditoria, cadeia de suprimentos e gerenciamento de chaves em modelos ROS do Alibaba Cloud." + }, + "rules": [ + "actiontrail-trail-intact-enabled", + "vpc-flow-logs-enabled", + "ram-user-mfa-check", + "ram-password-policy-check", + "ram-policy-no-statements-with-admin-access-check", + "ecs-running-instance-no-public-ip", + "ecs-security-group-risky-ports-check-with-protocol", + "ecs-security-group-not-internet-cidr-access", + "oss-bucket-server-side-encryption-enabled", + "oss-bucket-only-https-enabled", + "oss-bucket-public-read-prohibited", + "oss-bucket-public-write-prohibited", + "oss-bucket-logging-enabled", + "rds-public-connection-and-any-ip-access-check", + "rds-instance-enabled-ssl", + "rds-instance-enabled-tde-disk-encryption", + "redis-instance-no-public-ip", + "redis-instance-enabled-ssl", + "cr-repository-image-scanning-enabled", + "cr-repository-type-private", + "kms-key-rotation-enabled", + "kms-secret-rotation-enabled", + "fc-service-internet-access-disable", + "api-gateway-api-auth-required", + "api-gateway-api-internet-request-https" + ] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-best-practice-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-best-practice-pack.rego new file mode 100644 index 0000000..4837fab --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-best-practice-pack.rego @@ -0,0 +1,40 @@ +package infraguard.packs.aliyun.iac_code_best_practice + +import rego.v1 + +pack_meta := { + "id": "iac-code-best-practice", + "name": { + "en": "IaC Code Best Practice Pack", + "zh": "IaC Code 最佳实践合规包", + "ja": "IaC Code ベストプラクティスパック", + "de": "IaC Code Best Practices Paket", + "es": "Paquete de mejores prácticas de IaC Code", + "fr": "Pack de meilleures pratiques IaC Code", + "pt": "Pacote de melhores práticas do IaC Code" + }, + "description": { + "en": "Best practice checks for resource names, tags, and descriptions in Alibaba Cloud ROS templates.", + "zh": "面向 Alibaba Cloud ROS 模板的资源名称、标签和描述最佳实践检查。", + "ja": "Alibaba Cloud ROS テンプレートにおけるリソース名、タグ、説明のベストプラクティスチェック。", + "de": "Best-Practice-Prüfungen für Ressourcennamen, Tags und Beschreibungen in Alibaba Cloud ROS-Vorlagen.", + "es": "Comprobaciones de mejores prácticas para nombres, etiquetas y descripciones de recursos en plantillas ROS de Alibaba Cloud.", + "fr": "Contrôles de meilleures pratiques pour les noms, étiquettes et descriptions des ressources dans les modèles ROS Alibaba Cloud.", + "pt": "Verificações de melhores práticas para nomes, tags e descrições de recursos em templates ROS da Alibaba Cloud." + }, + "rules": [ + "ecs-instance-tags-required", + "ecs-instance-name-required", + "ecs-security-group-description-required", + "vpc-name-required", + "vswitch-name-required", + "rds-instance-tags-required", + "redis-instance-name-required", + "oss-bucket-tags-required", + "slb-loadbalancer-name-required", + "alb-loadbalancer-name-required", + "polardb-cluster-tags-required", + "sls-project-description-required", + "kms-key-description-required" + ] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-compliance-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-compliance-pack.rego new file mode 100644 index 0000000..ebd666c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-compliance-pack.rego @@ -0,0 +1,40 @@ +package infraguard.packs.aliyun.iac_code_compliance + +import rego.v1 + +pack_meta := { + "id": "iac-code-compliance", + "name": { + "en": "IaC Code Cloud Compliance Pack", + "zh": "IaC Code 云基础设施合规包", + "ja": "IaC Code クラウドコンプライアンスパック", + "de": "IaC Code Cloud-Compliance-Paket", + "es": "Paquete de Cumplimiento Cloud de IaC Code", + "fr": "Pack de Conformite Cloud IaC Code", + "pt": "Pacote de Conformidade Cloud do IaC Code", + }, + "description": { + "en": "Compliance-oriented InfraGuard policies for Alibaba Cloud ROS templates, covering audit trails, identity controls, encryption, backup, access restriction, and resilient log storage.", + "zh": "面向 Alibaba Cloud ROS 模板的合规策略组合,覆盖审计跟踪、身份控制、加密、备份、访问限制和日志冗余存储。", + "ja": "Alibaba Cloud ROS テンプレート向けのコンプライアンス重視 InfraGuard ポリシーで、監査証跡、ID 制御、暗号化、バックアップ、アクセス制限、ログ冗長保存をカバーします。", + "de": "Compliance-orientierte InfraGuard-Richtlinien fuer Alibaba Cloud ROS-Vorlagen, mit Audit-Trails, Identitaetskontrollen, Verschluesselung, Backup, Zugriffsbeschraenkung und redundantem Logspeicher.", + "es": "Politicas de InfraGuard orientadas al cumplimiento para plantillas ROS de Alibaba Cloud, con auditoria, controles de identidad, cifrado, copias de seguridad, restriccion de acceso y almacenamiento redundante de logs.", + "fr": "Politiques InfraGuard orientees conformite pour les modeles ROS Alibaba Cloud, couvrant les traces d'audit, les controles d'identite, le chiffrement, la sauvegarde, la restriction d'acces et le stockage redondant des journaux.", + "pt": "Politicas InfraGuard voltadas a conformidade para modelos ROS do Alibaba Cloud, cobrindo trilhas de auditoria, controles de identidade, criptografia, backup, restricao de acesso e armazenamento redundante de logs.", + }, + "rules": [ + "oss-bucket-server-side-encryption-enabled", + "oss-bucket-logging-enabled", + "rds-white-list-internet-ip-access-check", + "rds-instance-enabled-log-backup", + "actiontrail-trail-intact-enabled", + "ram-password-policy-check", + "ram-user-mfa-check", + "ecs-instance-deletion-protection-enabled", + "sls-project-multi-zone", + "kms-key-rotation-enabled", + "maxcompute-project-encryption-enabled", + "nas-filesystem-encrypt-type-check", + "polardb-cluster-enabled-tde", + ] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-cost-optimization-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-cost-optimization-pack.rego new file mode 100644 index 0000000..f8ea4b0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-cost-optimization-pack.rego @@ -0,0 +1,40 @@ +package infraguard.packs.aliyun.iac_code_cost_optimization + +import rego.v1 + +pack_meta := { + "id": "iac-code-cost-optimization", + "name": { + "en": "IaC Code Cost Optimization Pack", + "zh": "IaC Code 成本优化合规包", + "ja": "IaC Code コスト最適化パック", + "de": "IaC Code Kostenoptimierungspaket", + "es": "Paquete de optimización de costos de IaC Code", + "fr": "Pack d'optimisation des coûts IaC Code", + "pt": "Pacote de otimização de custos do IaC Code" + }, + "description": { + "en": "InfraGuard policies that make cost-bearing ROS choices explicit for compute, storage, database, cache, network, and log resources.", + "zh": "用于显式检查 ROS 中计算、存储、数据库、缓存、网络和日志资源成本相关配置的 InfraGuard 策略组合。", + "ja": "コンピュート、ストレージ、データベース、キャッシュ、ネットワーク、ログリソースのコストに関わる ROS 選択を明示させる InfraGuard ポリシーです。", + "de": "InfraGuard-Richtlinien, die kostenrelevante ROS-Entscheidungen für Compute-, Speicher-, Datenbank-, Cache-, Netzwerk- und Logressourcen explizit machen.", + "es": "Políticas de InfraGuard que hacen explícitas las decisiones ROS con impacto de costo para recursos de cómputo, almacenamiento, base de datos, caché, red y logs.", + "fr": "Politiques InfraGuard qui rendent explicites les choix ROS ayant un impact de coût pour les ressources de calcul, stockage, base de données, cache, réseau et journaux.", + "pt": "Políticas InfraGuard que tornam explícitas as escolhas ROS com impacto de custo para recursos de computação, armazenamento, banco de dados, cache, rede e logs." + }, + "rules": [ + "ecs-instance-charge-type-required", + "ecs-instance-bandwidth-configured", + "ecs-instance-type-required", + "ecs-disk-category-required", + "ecs-disk-size-required", + "rds-pay-type-required", + "rds-storage-type-required", + "redis-instance-class-required", + "slb-internet-charge-type-required", + "eip-bandwidth-required", + "nat-gateway-spec-required", + "oss-storage-class-required", + "logstore-ttl-required" + ] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-elasticity-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-elasticity-pack.rego new file mode 100644 index 0000000..8091ff0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-elasticity-pack.rego @@ -0,0 +1,42 @@ +package infraguard.packs.aliyun.iac_code_elasticity + +import rego.v1 + +pack_meta := { + "id": "iac-code-elasticity", + "name": { + "en": "IaC Code Elasticity Pack", + "zh": "IaC Code 弹性能力合规包", + "ja": "IaC Code 弾力性パック", + "de": "IaC Code Elastizitatspaket", + "es": "Paquete de elasticidad de IaC Code", + "fr": "Pack elasticite IaC Code", + "pt": "Pacote de elasticidade do IaC Code", + }, + "description": { + "en": "Checks Alibaba Cloud ROS resources for autoscaling limits, placement choices, launch capacity, scaling actions, load balancer health checks, serverless concurrency, and MSE capacity.", + "zh": "检查阿里云 ROS 资源的自动伸缩边界、部署候选、启动容量、伸缩动作、负载均衡健康检查、Serverless 并发和 MSE 容量配置。", + "ja": "Alibaba Cloud ROS リソースの自動スケーリング制限、配置候補、起動容量、スケーリングアクション、ロードバランサーヘルスチェック、サーバーレス同時実行、MSE 容量を確認します。", + "de": "Prueft Alibaba Cloud ROS-Ressourcen auf Autoskalierungsgrenzen, Platzierungsoptionen, Startkapazitaet, Skalierungsaktionen, Load-Balancer-Health-Checks, serverlose Parallelitaet und MSE-Kapazitaet.", + "es": "Comprueba recursos ROS de Alibaba Cloud para limites de autoescalado, opciones de ubicacion, capacidad de arranque, acciones de escalado, verificaciones de salud de balanceadores, concurrencia serverless y capacidad MSE.", + "fr": "Verifie les ressources ROS Alibaba Cloud pour les limites d'autoscaling, les choix de placement, la capacite de lancement, les actions de scaling, les controles de sante des equilibreurs, la concurrence serverless et la capacite MSE.", + "pt": "Verifica recursos ROS da Alibaba Cloud quanto a limites de autoescalonamento, opcoes de posicionamento, capacidade de lancamento, acoes de escala, verificacoes de saude de balanceadores, concorrencia serverless e capacidade MSE.", + }, + "rules": [ + "ack-cluster-node-pool-autoscaling-enabled", + "ack-cluster-node-pool-scaling-limits-required", + "ess-scaling-group-capacity-bounds-required", + "ess-scaling-group-cooldown-configured", + "ess-scaling-group-attach-multi-switch", + "ess-group-health-check", + "ess-scaling-configuration-image-check", + "ess-scaling-configuration-instance-type-candidates-required", + "ess-scaling-rule-action-configured", + "alb-all-listenter-has-server", + "alb-all-listener-health-check-enabled", + "slb-all-listener-health-check-enabled", + "fc-function-instance-concurrency-configured", + "fc-function-timeout-configured", + "mse-cluster-high-availability-configured", + ], +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-high-availability-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-high-availability-pack.rego new file mode 100644 index 0000000..509da56 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-high-availability-pack.rego @@ -0,0 +1,40 @@ +package infraguard.packs.aliyun.iac_code_high_availability + +import rego.v1 + +pack_meta := { + "id": "iac-code-high-availability", + "name": { + "en": "IaC Code High Availability Pack", + "zh": "IaC Code 高可用合规包", + "ja": "IaC Code 高可用性パック", + "de": "IaC Code Hochverfügbarkeitspaket", + "es": "Paquete de alta disponibilidad de IaC Code", + "fr": "Pack haute disponibilité IaC Code", + "pt": "Pacote de alta disponibilidade do IaC Code", + }, + "description": { + "en": "Checks Alibaba Cloud ROS resources for multi-zone placement, load balancer failover, baseline replica counts, and zone-redundant storage.", + "zh": "检查阿里云 ROS 资源的多可用区部署、负载均衡故障转移、基线副本数和同城冗余存储配置。", + "ja": "Alibaba Cloud ROS リソースのマルチゾーン配置、ロードバランサーフェイルオーバー、基準レプリカ数、ゾーン冗長ストレージを確認します。", + "de": "Prüft Alibaba Cloud ROS-Ressourcen auf Multi-Zone-Platzierung, Load-Balancer-Failover, Basis-Replikatanzahlen und zonenredundanten Speicher.", + "es": "Comprueba recursos ROS de Alibaba Cloud para ubicación multi-zona, failover de balanceadores, recuentos base de réplicas y almacenamiento redundante por zona.", + "fr": "Vérifie les ressources ROS Alibaba Cloud pour le placement multi-zone, le basculement des équilibreurs, les nombres de réplicas de base et le stockage redondant par zone.", + "pt": "Verifica recursos ROS da Alibaba Cloud quanto a posicionamento multi-zona, failover de balanceadores, contagens base de réplicas e armazenamento redundante por zona.", + }, + "rules": [ + "rds-instance-zone-required", + "rds-instance-secondary-zone-required", + "polardb-cluster-multi-zone", + "redis-instance-multi-zone", + "mongodb-instance-multi-zone", + "slb-instance-master-zone-required", + "slb-instance-multi-zone", + "alb-instance-multi-zone", + "nlb-loadbalancer-multi-zone", + "ess-scaling-group-multi-vswitch-distribution", + "ecs-instance-group-min-amount-required", + "ecs-instance-group-max-amount-required", + "oss-zrs-enabled", + ], +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-network-architecture-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-network-architecture-pack.rego new file mode 100644 index 0000000..468a9d0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-network-architecture-pack.rego @@ -0,0 +1,40 @@ +package infraguard.packs.aliyun.iac_code_network_architecture + +import rego.v1 + +pack_meta := { + "id": "iac-code-network-architecture", + "name": { + "en": "IaC Code Network Architecture Pack", + "zh": "IaC Code 网络架构合规包", + "ja": "IaC Code ネットワークアーキテクチャパック", + "de": "IaC Code Netzwerkarchitektur-Paket", + "es": "Paquete de Arquitectura de Red de IaC Code", + "fr": "Pack Architecture Réseau IaC Code", + "pt": "Pacote de Arquitetura de Rede IaC Code" + }, + "description": { + "en": "InfraGuard policies for VPC address planning, zone placement, private network exposure, and enterprise network hub attachments.", + "zh": "覆盖 VPC 地址规划、可用区落点、私网暴露控制和企业网络枢纽连接的 InfraGuard 策略组合。", + "ja": "VPC アドレス計画、ゾーン配置、プライベートネットワーク公開、エンタープライズネットワークハブ接続のための InfraGuard ポリシーです。", + "de": "InfraGuard-Richtlinien für VPC-Adressplanung, Zonenplatzierung, private Netzwerkexposition und Unternehmensnetzwerk-Hub-Anbindungen.", + "es": "Políticas de InfraGuard para planificación de direcciones VPC, ubicación por zonas, exposición de red privada y conexiones a hubs de red empresariales.", + "fr": "Politiques InfraGuard pour la planification d'adresses VPC, le placement par zone, l'exposition réseau privée et les connexions aux hubs réseau d'entreprise.", + "pt": "Políticas InfraGuard para planejamento de endereços VPC, posicionamento por zona, exposição de rede privada e conexões a hubs de rede empresariais." + }, + "rules": [ + "vpc-cidr-required", + "vswitch-cidr-required", + "vswitch-zone-required", + "security-group-vpc-required", + "security-group-enterprise-type", + "nat-gateway-vpc-required", + "eip-explicit-bandwidth-required", + "slb-address-type-intranet", + "alb-address-type-intranet", + "nlb-address-type-intranet", + "vpn-gateway-vpc-required", + "cen-instance-name-required", + "transit-router-vpc-attachment-multi-zone" + ] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-operations-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-operations-pack.rego new file mode 100644 index 0000000..ef6bde3 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-operations-pack.rego @@ -0,0 +1,40 @@ +package infraguard.packs.aliyun.iac_code_operations + +import rego.v1 + +pack_meta := { + "id": "iac-code-operations", + "name": { + "en": "IaC Code Operations Pack", + "zh": "IaC Code 可运维性合规包", + "ja": "IaC Code 運用パック", + "de": "IaC Code Betriebspaket", + "es": "Paquete de Operaciones de IaC Code", + "fr": "Pack Opérations IaC Code", + "pt": "Pacote de Operações do IaC Code" + }, + "description": { + "en": "InfraGuard policies for observability, audit logging, backup, recovery, and deletion protection in Alibaba Cloud ROS templates.", + "zh": "面向 Alibaba Cloud ROS 模板的 InfraGuard 策略,覆盖可观测、审计日志、备份恢复和删除保护。", + "ja": "Alibaba Cloud ROS テンプレート向けに、可観測性、監査ログ、バックアップ、復旧、削除保護を確認する InfraGuard ポリシーです。", + "de": "InfraGuard-Richtlinien fuer Observability, Audit-Logging, Backup, Wiederherstellung und Loeschschutz in Alibaba Cloud ROS-Templates.", + "es": "Políticas de InfraGuard para observabilidad, registros de auditoría, backup, recuperación y protección contra eliminación en plantillas ROS de Alibaba Cloud.", + "fr": "Politiques InfraGuard pour observabilite, journaux d'audit, sauvegarde, restauration et protection contre la suppression dans les modeles ROS Alibaba Cloud.", + "pt": "Políticas InfraGuard para observabilidade, logs de auditoria, backup, recuperação e proteção contra exclusão em modelos ROS do Alibaba Cloud." + }, + "rules": [ + "oss-bucket-operational-access-logging", + "sls-logstore-ttl-configured", + "sls-logstore-shard-count-configured", + "actiontrail-trail-name-required", + "ecs-disk-auto-snapshot-policy", + "rds-backup-policy-required", + "redis-backup-policy-required", + "ecs-instance-operational-deletion-protection", + "rds-instance-deletion-protection-enabled", + "polardb-cluster-delete-protection-enabled", + "fc-service-log-enable", + "fc-service-tracing-enable", + "cms-alarm-name-required" + ] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-security-pack.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-security-pack.rego new file mode 100644 index 0000000..68c9063 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/packs/iac-code-security-pack.rego @@ -0,0 +1,30 @@ +package infraguard.packs.aliyun.iac_code_security + +import rego.v1 + +pack_meta := { + "id": "iac-code-security", + "name": { + "en": "IaC Code Security Scenario Pack", + "zh": "IaC Code 安全性场景合规包", + }, + "description": { + "en": "Scenario-oriented InfraGuard policies for Security.", + "zh": "面向安全性场景的 InfraGuard 策略组合。", + }, + "rules": [ + "security-ecs-instance-no-public-ip", + "security-ecs-instance-security-group-required", + "security-ecs-instance-vpc-required", + "security-ecs-disk-encrypted", + "security-oss-bucket-private-acl", + "security-oss-bucket-encryption-configured", + "security-oss-bucket-logging-configured", + "security-rds-instance-vpc-required", + "security-rds-instance-ssl-required", + "security-rds-instance-tde-enabled", + "security-redis-instance-vpc-required", + "security-ram-user-mfa-required", + "security-api-gateway-api-auth-required" + ] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/actiontrail-trail-intact-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/actiontrail-trail-intact-enabled.rego new file mode 100644 index 0000000..fec333c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/actiontrail-trail-intact-enabled.rego @@ -0,0 +1,99 @@ +package infraguard.rules.aliyun.actiontrail_trail_intact_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "actiontrail-trail-intact-enabled", + "severity": "high", + "name": { + "en": "ActionTrail Trail Intact Enabled", + "zh": "开启操作审计全量日志跟踪", + "ja": "ActionTrail トレイルが完全に有効", + "de": "ActionTrail Trail vollständig aktiviert", + "es": "Trilha ActionTrail Intacta Habilitada", + "fr": "Piste ActionTrail Intacte Activée", + "pt": "Trilha ActionTrail Intacta Habilitada" + }, + "description": { + "en": "ActionTrail trail should be enabled and track all event types (Read and Write).", + "zh": "操作审计中存在开启状态的跟踪,且跟踪全部地域和全部事件类型。", + "ja": "ActionTrail トレイルを有効にし、すべてのイベントタイプ(読み取りと書き込み)を追跡する必要があります。", + "de": "ActionTrail Trail sollte aktiviert sein und alle Ereignistypen (Lesen und Schreiben) verfolgen.", + "es": "La trilha ActionTrail debe estar habilitada y rastrear todos los tipos de eventos (Lectura y Escritura).", + "fr": "La piste ActionTrail doit être activée et suivre tous les types d'événements (Lecture et Écriture).", + "pt": "A trilha ActionTrail deve estar habilitada e rastrear todos os tipos de eventos (Leitura e Escrita)." + }, + "reason": { + "en": "The ActionTrail trail is not enabled or does not track all event types.", + "zh": "操作审计跟踪未开启或未跟踪所有事件类型。", + "ja": "ActionTrail トレイルが有効になっていないか、すべてのイベントタイプを追跡していません。", + "de": "Der ActionTrail Trail ist nicht aktiviert oder verfolgt nicht alle Ereignistypen.", + "es": "La trilha ActionTrail no está habilitada o no rastrea todos los tipos de eventos.", + "fr": "La piste ActionTrail n'est pas activée ou ne suit pas tous les types d'événements.", + "pt": "A trilha ActionTrail não está habilitada ou não rastreia todos os tipos de eventos." + }, + "recommendation": { + "en": "Enable the trail using ALIYUN::ACTIONTRAIL::TrailLogging and set EventRW to All in ALIYUN::ACTIONTRAIL::Trail.", + "zh": "使用 ALIYUN::ACTIONTRAIL::TrailLogging 启用跟踪,并在 ALIYUN::ACTIONTRAIL::Trail 中将 EventRW 设置为 All。", + "ja": "ALIYUN::ACTIONTRAIL::TrailLogging を使用してトレイルを有効にし、ALIYUN::ACTIONTRAIL::Trail で EventRW を All に設定します。", + "de": "Aktivieren Sie den Trail mit ALIYUN::ACTIONTRAIL::TrailLogging und setzen Sie EventRW in ALIYUN::ACTIONTRAIL::Trail auf All.", + "es": "Habilite la trilha usando ALIYUN::ACTIONTRAIL::TrailLogging y establezca EventRW en All en ALIYUN::ACTIONTRAIL::Trail.", + "fr": "Activez la piste en utilisant ALIYUN::ACTIONTRAIL::TrailLogging et définissez EventRW sur All dans ALIYUN::ACTIONTRAIL::Trail.", + "pt": "Habilite a trilha usando ALIYUN::ACTIONTRAIL::TrailLogging e defina EventRW como All em ALIYUN::ACTIONTRAIL::Trail." + }, + "resource_types": ["ALIYUN::ACTIONTRAIL::Trail"] +} + +# Get all enabled trail names from TrailLogging resources +enabled_trails := {name | + some logging in helpers.resources_by_type("ALIYUN::ACTIONTRAIL::TrailLogging") + helpers.get_property(logging, "Enable", false) == true + name := helpers.get_property(logging, "Name", "") + name != "" +} + +# Check if a trail is enabled (referenced by an enabled TrailLogging) +is_trail_enabled(trail_name) if { + trail_name in enabled_trails +} + +# Check if trail tracks all events +is_track_all_events(resource) if { + helpers.get_property(resource, "EventRW", "Write") == "All" +} + +deny contains result if { + some name, resource in helpers.resources_by_types(rule_meta.resource_types) + + # Get the trail name (either property Name or resource name if not set?) + # Trail Name property is required. + trail_name := helpers.get_property(resource, "Name", "") + + # Check conditions + violation := check_violation(trail_name, resource) + violation != null + + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "EventRW"], # Approximate path + "meta": { + "severity": rule_meta.severity, + "reason": violation, + "recommendation": rule_meta.recommendation, + }, + } +} + +check_violation(trail_name, resource) := reason if { + not is_track_all_events(resource) + reason := rule_meta.reason.zh # "Not tracking all events" +} + +check_violation(trail_name, resource) := reason if { + is_track_all_events(resource) + not is_trail_enabled(trail_name) + reason := "操作审计跟踪未开启 (缺少启用的 TrailLogging)" +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-auth-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-auth-required.rego new file mode 100644 index 0000000..af61a30 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-auth-required.rego @@ -0,0 +1,60 @@ +package infraguard.rules.aliyun.api_gateway_api_auth_required + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "api-gateway-api-auth-required", + "severity": "medium", + "name": { + "en": "API Gateway API Auth Required", + "zh": "API 网关中配置 API 安全认证", + "ja": "API ゲートウェイ API 認証が必要", + "de": "API Gateway API-Authentifizierung erforderlich", + "es": "Autenticación de API del Gateway de API Requerida", + "fr": "Authentification API du Gateway API Requise", + "pt": "Autenticação de API do Gateway de API Obrigatória" + }, + "description": { + "en": "Ensures API Gateway APIs have authentication configured.", + "zh": "确保 API 网关中配置 API 安全认证为阿里云 APP 或使用指定的插件类型。", + "ja": "API ゲートウェイ API に認証が設定されていることを確認します。", + "de": "Stellt sicher, dass API Gateway APIs Authentifizierung konfiguriert haben.", + "es": "Garantiza que las APIs del Gateway de API tengan autenticación configurada.", + "fr": "Garantit que les APIs du Gateway API ont l'authentification configurée.", + "pt": "Garante que as APIs do Gateway de API tenham autenticação configurada." + }, + "reason": { + "en": "Authentication prevents unauthorized access to APIs.", + "zh": "认证可防止未授权访问 API。", + "ja": "認証により、API への不正アクセスを防ぎます。", + "de": "Authentifizierung verhindert unbefugten Zugriff auf APIs.", + "es": "La autenticación previene el acceso no autorizado a las APIs.", + "fr": "L'authentification empêche l'accès non autorisé aux APIs.", + "pt": "A autenticação impede acesso não autorizado às APIs." + }, + "recommendation": { + "en": "Enable authentication for all APIs.", + "zh": "为所有 API 启用认证。", + "ja": "すべての API で認証を有効にします。", + "de": "Aktivieren Sie Authentifizierung für alle APIs.", + "es": "Habilite autenticación para todas las APIs.", + "fr": "Activez l'authentification pour toutes les APIs.", + "pt": "Habilite autenticação para todas as APIs." + }, + "resource_types": ["ALIYUN::ApiGateway::Api"] +} + +deny contains result if { + some api_name, resource in helpers.resources_by_type("ALIYUN::ApiGateway::Api") + auth_type := helpers.get_property(resource, "AuthType", "") + + auth_type == "ANONYMOUS" + + result := { + "id": rule_meta.id, + "resource_id": api_name, + "violation_path": ["Properties", "AuthType"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-internet-request-https.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-internet-request-https.rego new file mode 100644 index 0000000..07fa04f --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/api-gateway-api-internet-request-https.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.api_gateway_api_internet_request_https + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata +rule_meta := { + "id": "api-gateway-api-internet-request-https", + "severity": "medium", + "name": { + "en": "API Gateway Internet Request HTTPS Enabled", + "zh": "API 网关公网请求开启 HTTPS", + "ja": "API ゲートウェイのインターネットリクエストで HTTPS が有効", + "de": "API Gateway Internet-Anfrage HTTPS aktiviert", + "es": "HTTPS de Solicitud de Internet del Gateway de API Habilitado", + "fr": "HTTPS de Requête Internet du Gateway API Activé", + "pt": "HTTPS de Solicitação de Internet do Gateway de API Habilitado" + }, + "description": { + "en": "Ensures that API Gateway APIs exposed to the internet use HTTPS protocol.", + "zh": "确保暴露给公网的 API 网关 API 使用 HTTPS 协议。", + "ja": "インターネットに公開された API ゲートウェイ API が HTTPS プロトコルを使用していることを確認します。", + "de": "Stellt sicher, dass API Gateway APIs, die dem Internet ausgesetzt sind, das HTTPS-Protokoll verwenden.", + "es": "Garantiza que las APIs del Gateway de API expuestas a internet usen el protocolo HTTPS.", + "fr": "Garantit que les APIs du Gateway API exposées à Internet utilisent le protocole HTTPS.", + "pt": "Garante que as APIs do Gateway de API expostas à internet usem o protocolo HTTPS." + }, + "reason": { + "en": "HTTPS ensures data confidentiality and integrity during transmission over the internet.", + "zh": "HTTPS 可确保在公网传输期间数据的机密性和完整性。", + "ja": "HTTPS により、インターネット経由での送信中にデータの機密性と整合性が確保されます。", + "de": "HTTPS gewährleistet Datenvertraulichkeit und Integrität während der Übertragung über das Internet.", + "es": "HTTPS garantiza la confidencialidad e integridad de los datos durante la transmisión por internet.", + "fr": "HTTPS assure la confidentialité et l'intégrité des données pendant la transmission sur Internet.", + "pt": "O HTTPS garante confidencialidade e integridade dos dados durante a transmissão pela internet." + }, + "recommendation": { + "en": "Configure the API Gateway API to require HTTPS for internet requests.", + "zh": "配置 API 网关 API,要求公网请求使用 HTTPS。", + "ja": "API ゲートウェイ API を設定して、インターネットリクエストに HTTPS を要求します。", + "de": "Konfigurieren Sie die API Gateway API so, dass HTTPS für Internet-Anfragen erforderlich ist.", + "es": "Configure la API del Gateway de API para requerir HTTPS para solicitudes de internet.", + "fr": "Configurez l'API du Gateway API pour exiger HTTPS pour les requêtes Internet.", + "pt": "Configure a API do Gateway de API para exigir HTTPS para solicitações de internet." + }, + "resource_types": ["ALIYUN::ApiGateway::Api"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ApiGateway::Api") + + # Conceptual check for protocol + proto := helpers.get_property(resource, "RequestConfig", {"RequestProtocol": "HTTP"}).RequestProtocol + proto == "HTTP" + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "RequestConfig", "RequestProtocol"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-image-scanning-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-image-scanning-enabled.rego new file mode 100644 index 0000000..463dc16 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-image-scanning-enabled.rego @@ -0,0 +1,63 @@ +package infraguard.rules.aliyun.cr_repository_image_scanning_enabled + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "cr-repository-image-scanning-enabled", + "severity": "high", + "name": { + "en": "CR Instance Image Scanning Enabled", + "zh": "为容器镜像实例开启安全扫描", + "ja": "CR インスタンスイメージスキャンが有効", + "de": "CR-Instanz Bild-Scanning aktiviert", + "es": "Escaneo de Imagen de Instancia CR Habilitado", + "fr": "Balayage d'Image d'Instance CR Activé", + "pt": "Varredura de Imagem de Instância CR Habilitada" + }, + "description": { + "en": "Ensures Container Registry instances have image scanning enabled for security vulnerability detection.", + "zh": "确保容器镜像实例开启了镜像安全扫描功能以检测安全漏洞。", + "ja": "コンテナレジストリインスタンスでセキュリティ脆弱性検出のためにイメージスキャンが有効になっていることを確認します。", + "de": "Stellt sicher, dass Container Registry-Instanzen Bild-Scanning für die Erkennung von Sicherheitslücken aktiviert haben.", + "es": "Garantiza que las instancias de Container Registry tengan escaneo de imágenes habilitado para la detección de vulnerabilidades de seguridad.", + "fr": "Garantit que les instances Container Registry ont le balayage d'images activé pour la détection des vulnérabilités de sécurité.", + "pt": "Garante que as instâncias do Container Registry tenham varredura de imagem habilitada para detecção de vulnerabilidades de segurança." + }, + "reason": { + "en": "Image scanning helps identify and prevent deployment of vulnerable container images.", + "zh": "镜像扫描有助于识别和防止部署有漏洞的容器镜像。", + "ja": "イメージスキャンは、脆弱なコンテナイメージの展開を識別および防止するのに役立ちます。", + "de": "Bild-Scanning hilft dabei, die Bereitstellung anfälliger Container-Images zu identifizieren und zu verhindern.", + "es": "El escaneo de imágenes ayuda a identificar y prevenir el despliegue de imágenes de contenedor vulnerables.", + "fr": "Le balayage d'images aide à identifier et empêcher le déploiement d'images de conteneurs vulnérables.", + "pt": "A varredura de imagem ajuda a identificar e prevenir a implantação de imagens de contêiner vulneráveis." + }, + "recommendation": { + "en": "Enable image scanning for the Container Registry instance.", + "zh": "为容器镜像实例启用镜像扫描功能。", + "ja": "コンテナレジストリインスタンスのイメージスキャンを有効にします。", + "de": "Aktivieren Sie Bild-Scanning für die Container Registry-Instanz.", + "es": "Habilite el escaneo de imágenes para la instancia de Container Registry.", + "fr": "Activez le balayage d'images pour l'instance Container Registry.", + "pt": "Habilite a varredura de imagem para a instância do Container Registry." + }, + "resource_types": ["ALIYUN::CR::Instance"] +} + +is_compliant(resource) if { + # Check ImageScanner property + image_scanner := helpers.get_property(resource, "ImageScanner", "") + count(image_scanner) > 0 +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::CR::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ImageScanner"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-type-private.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-type-private.rego new file mode 100644 index 0000000..a63c2e3 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/cr-repository-type-private.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.cr_repository_type_private + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "cr-repository-type-private", + "severity": "high", + "name": { + "en": "CR Repository Type Private", + "zh": "容器镜像服务镜像仓库类型为私有", + "ja": "CR リポジトリタイプがプライベート", + "de": "CR-Repository-Typ privat", + "es": "Tipo de Repositorio CR Privado", + "fr": "Type de Dépôt CR Privé", + "pt": "Tipo de Repositório CR Privado" + }, + "description": { + "en": "Ensures that CR repositories are set to PRIVATE.", + "zh": "确保容器镜像仓库类型设置为私有。", + "ja": "CR リポジトリが PRIVATE に設定されていることを確認します。", + "de": "Stellt sicher, dass CR-Repositories auf PRIVATE gesetzt sind.", + "es": "Garantiza que los repositorios CR estén configurados como PRIVADOS.", + "fr": "Garantit que les dépôts CR sont définis sur PRIVÉ.", + "pt": "Garante que os repositórios CR estejam definidos como PRIVADO." + }, + "reason": { + "en": "Public repositories can be accessed by anyone, which may lead to exposure of sensitive code or data.", + "zh": "公开仓库可以被任何人访问,可能导致敏感代码或数据泄露。", + "ja": "パブリックリポジトリは誰でもアクセスでき、機密コードやデータの露出につながる可能性があります。", + "de": "Öffentliche Repositories können von jedem abgerufen werden, was zur Offenlegung sensibler Codes oder Daten führen kann.", + "es": "Los repositorios públicos pueden ser accedidos por cualquiera, lo que puede llevar a la exposición de código o datos sensibles.", + "fr": "Les dépôts publics peuvent être accessibles par n'importe qui, ce qui peut entraîner l'exposition de code ou de données sensibles.", + "pt": "Repositórios públicos podem ser acessados por qualquer pessoa, o que pode levar à exposição de código ou dados sensíveis." + }, + "recommendation": { + "en": "Set the RepoType to 'PRIVATE' for the CR repository.", + "zh": "将容器镜像仓库的 RepoType 设置为 'PRIVATE'。", + "ja": "CR リポジトリの RepoType を 'PRIVATE' に設定します。", + "de": "Setzen Sie den RepoType für das CR-Repository auf 'PRIVATE'.", + "es": "Establezca el RepoType en 'PRIVADO' para el repositorio CR.", + "fr": "Définissez le RepoType sur 'PRIVÉ' pour le dépôt CR.", + "pt": "Defina o RepoType como 'PRIVADO' para o repositório CR." + }, + "resource_types": ["ALIYUN::CR::Repository"] +} + +is_compliant(resource) if { + helpers.get_property(resource, "RepoType", "PRIVATE") == "PRIVATE" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::CR::Repository") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "RepoType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-running-instance-no-public-ip.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-running-instance-no-public-ip.rego new file mode 100644 index 0000000..2bfa20a --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-running-instance-no-public-ip.rego @@ -0,0 +1,67 @@ +package infraguard.rules.aliyun.ecs_running_instance_no_public_ip + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ecs-running-instance-no-public-ip", + "severity": "high", + "name": { + "en": "ECS Instance No Public IP", + "zh": "ECS 实例不分配公网 IP", + "ja": "ECS インスタンスにパブリック IP がない", + "de": "ECS-Instanz Keine öffentliche IP", + "es": "Instancia ECS Sin IP Pública", + "fr": "Instance ECS Sans IP Publique", + "pt": "Instância ECS Sem IP Público" + }, + "description": { + "en": "ECS instances should not have a public IP address to reduce direct internet exposure.", + "zh": "ECS 实例不应分配公网 IP,以减少直接暴露在互联网上的风险。", + "ja": "ECS インスタンスは、直接的なインターネットへの露出を減らすためにパブリック IP アドレスを持つべきではありません。", + "de": "ECS-Instanzen sollten keine öffentliche IP-Adresse haben, um die direkte Internetexposition zu reduzieren.", + "es": "Las instancias ECS no deben tener una dirección IP pública para reducir la exposición directa a Internet.", + "fr": "Les instances ECS ne doivent pas avoir d'adresse IP publique pour réduire l'exposition directe à Internet.", + "pt": "As instâncias ECS não devem ter um endereço IP público para reduzir a exposição direta à Internet." + }, + "reason": { + "en": "Public IP addresses allow direct access from the internet, increasing the attack surface.", + "zh": "分配公网 IP 会使实例直接暴露在互联网上,增加了攻击面。", + "ja": "パブリック IP アドレスはインターネットからの直接アクセスを許可し、攻撃面を増加させます。", + "de": "Öffentliche IP-Adressen ermöglichen direkten Zugriff aus dem Internet und erhöhen die Angriffsfläche.", + "es": "Las direcciones IP públicas permiten acceso directo desde Internet, aumentando la superficie de ataque.", + "fr": "Les adresses IP publiques permettent un accès direct depuis Internet, augmentant la surface d'attaque.", + "pt": "Endereços IP públicos permitem acesso direto da Internet, aumentando a superfície de ataque." + }, + "recommendation": { + "en": "Remove public IP assignment by setting AllocatePublicIP to false or using a NAT gateway for egress.", + "zh": "通过将 AllocatePublicIP 设置为 false 或使用 NAT 网关来取消分配公网 IP。", + "ja": "AllocatePublicIP を false に設定するか、エグレスに NAT ゲートウェイを使用してパブリック IP の割り当てを削除します。", + "de": "Entfernen Sie die öffentliche IP-Zuweisung, indem Sie AllocatePublicIP auf false setzen oder ein NAT-Gateway für den Ausgang verwenden.", + "es": "Elimine la asignación de IP pública estableciendo AllocatePublicIP en false o usando una puerta de enlace NAT para la salida.", + "fr": "Supprimez l'attribution d'IP publique en définissant AllocatePublicIP sur false ou en utilisant une passerelle NAT pour la sortie.", + "pt": "Remova a atribuição de IP público definindo AllocatePublicIP como false ou usando um gateway NAT para saída." + }, + "resource_types": ["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"] +} + +# Check if the instance has a public IP allocated +has_public_ip(resource) if { + helpers.get_property(resource, "AllocatePublicIP", false) == true +} + +deny contains result if { + some name, resource in helpers.resources_by_types(rule_meta.resource_types) + has_public_ip(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AllocatePublicIP"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-not-internet-cidr-access.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-not-internet-cidr-access.rego new file mode 100644 index 0000000..dd0fc69 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-not-internet-cidr-access.rego @@ -0,0 +1,118 @@ +package infraguard.rules.aliyun.ecs_security_group_not_internet_cidr_access + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata with i18n support +rule_meta := { + "id": "ecs-security-group-not-internet-cidr-access", + "severity": "high", + "name": { + "en": "Security Group Ingress Source IP Not Include Public IP", + "zh": "安全组入网设置允许的来源 IP 不包含公网 IP", + "ja": "セキュリティグループイングレスのソース IP にパブリック IP が含まれていない", + "de": "Sicherheitsgruppe Ingress-Quell-IP enthält keine öffentliche IP", + "es": "IP de Origen de Ingress de Grupo de Seguridad No Incluye IP Pública", + "fr": "IP Source d'Ingress du Groupe de Sécurité N'Inclut Pas d'IP Publique", + "pt": "IP de Origem de Ingresso de Grupo de Segurança Não Inclui IP Público" + }, + "description": { + "en": "Security group ingress rules with accept policy should not have source IP containing public internet IPs.", + "zh": "安全组入网方向授权策略为允许的来源 IP 地址段不包含公网 IP,视为合规。", + "ja": "許可ポリシーを持つセキュリティグループのイングレスルールは、パブリックインターネット IP を含むソース IP を持つべきではありません。", + "de": "Sicherheitsgruppen-Ingress-Regeln mit Accept-Richtlinie sollten keine Quell-IP enthalten, die öffentliche Internet-IPs enthält.", + "es": "Las reglas de ingreso del grupo de seguridad con política de aceptación no deben tener IP de origen que contenga IPs públicas de internet.", + "fr": "Les règles d'ingress du groupe de sécurité avec politique d'acceptation ne doivent pas avoir d'IP source contenant des IPs Internet publiques.", + "pt": "As regras de ingresso do grupo de segurança com política de aceitação não devem ter IP de origem contendo IPs públicos da internet." + }, + "reason": { + "en": "The security group has an ingress rule that allows access from public internet IP addresses, which may expose the resources to external attacks.", + "zh": "安全组有一条入网规则允许从公网 IP 地址访问,可能将资源暴露给外部攻击。", + "ja": "セキュリティグループにパブリックインターネット IP アドレスからのアクセスを許可するイングレスルールがあり、リソースが外部攻撃にさらされる可能性があります。", + "de": "Die Sicherheitsgruppe hat eine Ingress-Regel, die Zugriff von öffentlichen Internet-IP-Adressen erlaubt, was die Ressourcen externen Angriffen aussetzen kann.", + "es": "El grupo de seguridad tiene una regla de ingreso que permite el acceso desde direcciones IP públicas de internet, lo que puede exponer los recursos a ataques externos.", + "fr": "Le groupe de sécurité a une règle d'ingress qui autorise l'accès depuis des adresses IP Internet publiques, ce qui peut exposer les ressources à des attaques externes.", + "pt": "O grupo de segurança tem uma regra de ingresso que permite acesso de endereços IP públicos da internet, o que pode expor os recursos a ataques externos." + }, + "recommendation": { + "en": "Restrict ingress source IP to private network ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) unless public internet access is explicitly required.", + "zh": "将入网来源 IP 限制为私有网络范围(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16),除非确实需要公网访问。", + "ja": "パブリックインターネットアクセスが明示的に必要な場合を除き、イングレスソース IP をプライベートネットワーク範囲(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)に制限します。", + "de": "Beschränken Sie die Ingress-Quell-IP auf private Netzwerkbereiche (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), es sei denn, öffentlicher Internetzugriff ist ausdrücklich erforderlich.", + "es": "Restrinja la IP de origen de ingreso a rangos de red privada (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) a menos que se requiera explícitamente acceso público a internet.", + "fr": "Restreignez l'IP source d'ingress aux plages de réseau privé (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) sauf si l'accès Internet public est explicitement requis.", + "pt": "Restrinja o IP de origem de ingresso a intervalos de rede privada (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), a menos que o acesso público à internet seja explicitamente necessário." + }, + "resource_types": ["ALIYUN::ECS::SecurityGroup", "ALIYUN::ECS::SecurityGroupIngress", "ALIYUN::ECS::SecurityGroupIngresses"] +} + +# Check if a rule allows access from internet CIDR +is_internet_source_rule(rule) if { + # Source CIDR is a public internet IP + cidr := rule.SourceCidrIp + cidr != "" + helpers.is_internet_cidr(cidr) + + # Policy is accept (default) + object.get(rule, "Policy", "accept") == "accept" +} + +# Check SecurityGroup resource for ingress rules +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroup") + some i, rule in resource.Properties.SecurityGroupIngress + is_internet_source_rule(rule) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SecurityGroupIngress", format_int(i, 10), "SourceCidrIp"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +# Check SecurityGroupIngress resource +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroupIngress") + props := resource.Properties + ingress_rule := { + "SourceCidrIp": object.get(props, "SourceCidrIp", ""), + "Policy": object.get(props, "Policy", "accept"), + } + is_internet_source_rule(ingress_rule) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SourceCidrIp"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +# Check SecurityGroupIngresses resource +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroupIngresses") + some i, perm in resource.Properties.Permissions + ingress_rule := { + "SourceCidrIp": object.get(perm, "SourceCidrIp", ""), + "Policy": object.get(perm, "Policy", "accept"), + } + is_internet_source_rule(ingress_rule) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Permissions", format_int(i, 10), "SourceCidrIp"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-risky-ports-check-with-protocol.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-risky-ports-check-with-protocol.rego new file mode 100644 index 0000000..6d20ebc --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ecs-security-group-risky-ports-check-with-protocol.rego @@ -0,0 +1,150 @@ +package infraguard.rules.aliyun.ecs_security_group_risky_ports_check_with_protocol + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata with i18n support +rule_meta := { + "id": "ecs-security-group-risky-ports-check-with-protocol", + "severity": "high", + "name": { + "en": "Security Group Risky Ports Check with Protocol", + "zh": "安全组指定协议不允许对全部网段开启风险端口", + "ja": "プロトコル付きセキュリティグループのリスクポートチェック", + "de": "Sicherheitsgruppe riskante Ports-Prüfung mit Protokoll", + "es": "Verificación de Puertos de Riesgo del Grupo de Seguridad con Protocolo", + "fr": "Vérification des Ports à Risque du Groupe de Sécurité avec Protocole", + "pt": "Verificação de Portas de Risco do Grupo de Segurança com Protocolo" + }, + "description": { + "en": "When security group ingress source is set to 0.0.0.0/0, the port range should not include risky ports (22, 3389) for specified protocols (TCP/UDP), to reduce the risk of brute force attacks.", + "zh": "当安全组入网网段设置为 0.0.0.0/0 时,指定协议的端口范围不包含指定风险端口,降低服务器登录密码被暴力破解风险,视为合规。默认检测风险端口为 22、3389。", + "ja": "セキュリティグループのイングレスソースが 0.0.0.0/0 に設定されている場合、ブルートフォース攻撃のリスクを低減するために、指定されたプロトコル(TCP/UDP)のポート範囲にリスクポート(22、3389)を含めるべきではありません。", + "de": "Wenn die Sicherheitsgruppen-Eingangsquelle auf 0.0.0.0/0 gesetzt ist, sollte der Portbereich keine riskanten Ports (22, 3389) für angegebene Protokolle (TCP/UDP) enthalten, um das Risiko von Brute-Force-Angriffen zu reduzieren.", + "es": "Cuando la fuente de ingreso del grupo de seguridad se establece en 0.0.0.0/0, el rango de puertos no debe incluir puertos de riesgo (22, 3389) para protocolos especificados (TCP/UDP), para reducir el riesgo de ataques de fuerza bruta.", + "fr": "Lorsque la source d'ingress du groupe de sécurité est définie sur 0.0.0.0/0, la plage de ports ne doit pas inclure les ports à risque (22, 3389) pour les protocoles spécifiés (TCP/UDP), afin de réduire le risque d'attaques par force brute.", + "pt": "Quando a origem de entrada do grupo de segurança é definida como 0.0.0.0/0, o intervalo de portas não deve incluir portas de risco (22, 3389) para protocolos especificados (TCP/UDP), para reduzir o risco de ataques de força bruta." + }, + "reason": { + "en": "The security group allows access to risky ports (SSH:22, RDP:3389) from all sources (0.0.0.0/0), which increases the risk of brute force password attacks.", + "zh": "安全组允许从所有来源(0.0.0.0/0)访问风险端口(SSH:22、RDP:3389),增加了暴力破解密码的风险。", + "ja": "セキュリティグループがすべてのソース(0.0.0.0/0)からのリスクポート(SSH:22、RDP:3389)へのアクセスを許可しているため、ブルートフォースパスワード攻撃のリスクが増加します。", + "de": "Die Sicherheitsgruppe erlaubt Zugriff auf riskante Ports (SSH:22, RDP:3389) von allen Quellen (0.0.0.0/0), was das Risiko von Brute-Force-Passwortangriffen erhöht.", + "es": "El grupo de seguridad permite acceso a puertos de riesgo (SSH:22, RDP:3389) desde todas las fuentes (0.0.0.0/0), lo que aumenta el riesgo de ataques de fuerza bruta en contraseñas.", + "fr": "Le groupe de sécurité autorise l'accès aux ports à risque (SSH:22, RDP:3389) depuis toutes les sources (0.0.0.0/0), ce qui augmente le risque d'attaques par force brute sur les mots de passe.", + "pt": "O grupo de segurança permite acesso a portas de risco (SSH:22, RDP:3389) de todas as fontes (0.0.0.0/0), o que aumenta o risco de ataques de força bruta em senhas." + }, + "recommendation": { + "en": "Restrict access to ports 22 (SSH) and 3389 (RDP) by limiting the source CIDR to specific trusted IP ranges instead of 0.0.0.0/0.", + "zh": "限制对端口 22(SSH)和 3389(RDP)的访问,将来源 CIDR 限制为特定的可信 IP 范围,而不是 0.0.0.0/0。", + "ja": "ソース CIDR を 0.0.0.0/0 ではなく、特定の信頼できる IP 範囲に制限することで、ポート 22(SSH)と 3389(RDP)へのアクセスを制限します。", + "de": "Beschränken Sie den Zugriff auf Ports 22 (SSH) und 3389 (RDP), indem Sie das Quell-CIDR auf spezifische vertrauenswürdige IP-Bereiche anstelle von 0.0.0.0/0 beschränken.", + "es": "Restrinja el acceso a los puertos 22 (SSH) y 3389 (RDP) limitando el CIDR de origen a rangos de IP confiables específicos en lugar de 0.0.0.0/0.", + "fr": "Restreignez l'accès aux ports 22 (SSH) et 3389 (RDP) en limitant le CIDR source à des plages d'IP de confiance spécifiques au lieu de 0.0.0.0/0.", + "pt": "Restrinja o acesso às portas 22 (SSH) e 3389 (RDP) limitando o CIDR de origem a intervalos de IP confiáveis específicos em vez de 0.0.0.0/0." + }, + "resource_types": ["ALIYUN::ECS::SecurityGroup", "ALIYUN::ECS::SecurityGroupIngress", "ALIYUN::ECS::SecurityGroupIngresses"] +} + +# Risky ports that should not be exposed to all sources +risky_ports := [22, 3389] + +# Protocols to check (TCP and UDP are relevant for SSH and RDP) +risky_protocols := ["tcp", "udp"] + +# Check if a rule exposes risky ports from public sources +is_risky_public_rule(rule) if { + # Source is 0.0.0.0/0 (all IPv4) + rule.SourceCidrIp == "0.0.0.0/0" + + # Protocol is TCP, UDP, or ALL + lower(rule.IpProtocol) in risky_protocols + + # Policy is accept (default) + object.get(rule, "Policy", "accept") == "accept" + + # Check if any risky port is in the range + some port in risky_ports + helpers.port_in_range(port, rule.PortRange) +} + +is_risky_public_rule(rule) if { + # Source is ::/0 (all IPv6) + rule.Ipv6SourceCidrIp == "::/0" + + # Protocol is TCP, UDP, or ALL + lower(rule.IpProtocol) in risky_protocols + + # Policy is accept (default) + object.get(rule, "Policy", "accept") == "accept" + + # Check if any risky port is in the range + some port in risky_ports + helpers.port_in_range(port, rule.PortRange) +} + +# Check SecurityGroup resource for ingress rules +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroup") + some i, rule in resource.Properties.SecurityGroupIngress + is_risky_public_rule(rule) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SecurityGroupIngress", format_int(i, 10)], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +# Check SecurityGroupIngress resource +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroupIngress") + props := resource.Properties + ingress_rule := { + "IpProtocol": props.IpProtocol, + "PortRange": props.PortRange, + "SourceCidrIp": object.get(props, "SourceCidrIp", ""), + "Ipv6SourceCidrIp": object.get(props, "Ipv6SourceCidrIp", ""), + "Policy": object.get(props, "Policy", "accept"), + } + is_risky_public_rule(ingress_rule) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +# Check SecurityGroupIngresses resource +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::SecurityGroupIngresses") + some i, perm in resource.Properties.Permissions + ingress_rule := { + "IpProtocol": perm.IpProtocol, + "PortRange": perm.PortRange, + "SourceCidrIp": object.get(perm, "SourceCidrIp", ""), + "Ipv6SourceCidrIp": object.get(perm, "Ipv6SourceCidrIp", ""), + "Policy": object.get(perm, "Policy", "accept"), + } + is_risky_public_rule(ingress_rule) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Permissions", format_int(i, 10)], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/fc-service-internet-access-disable.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/fc-service-internet-access-disable.rego new file mode 100644 index 0000000..68cfdb1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/fc-service-internet-access-disable.rego @@ -0,0 +1,63 @@ +package infraguard.rules.aliyun.fc_service_internet_access_disable + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata +rule_meta := { + "id": "fc-service-internet-access-disable", + "severity": "medium", + "name": { + "en": "FC Service Internet Access Disabled", + "zh": "FC 服务禁用公网访问", + "ja": "FC サービスインターネットアクセスが無効", + "de": "FC-Service Internetzugriff deaktiviert", + "es": "Acceso a Internet del Servicio FC Deshabilitado", + "fr": "Accès Internet du Service FC Désactivé", + "pt": "Acesso à Internet do Serviço FC Desabilitado" + }, + "description": { + "en": "Ensures that the Function Compute service has internet access disabled when it should only access internal resources.", + "zh": "确保函数计算服务在仅需访问内网资源时已禁用公网访问。", + "ja": "関数計算サービスが内部リソースにのみアクセスする必要がある場合に、インターネットアクセスが無効になっていることを確認します。", + "de": "Stellt sicher, dass der Function Compute-Service Internetzugriff deaktiviert hat, wenn er nur auf interne Ressourcen zugreifen sollte.", + "es": "Garantiza que el servicio Function Compute tenga acceso a Internet deshabilitado cuando solo deba acceder a recursos internos.", + "fr": "Garantit que le service Function Compute a l'accès Internet désactivé lorsqu'il ne doit accéder qu'aux ressources internes.", + "pt": "Garante que o serviço Function Compute tenha acesso à Internet desabilitado quando deve acessar apenas recursos internos." + }, + "reason": { + "en": "Disabling internet access for FC services reduces the attack surface and potential for data exfiltration.", + "zh": "为 FC 服务禁用公网访问可减少攻击面和潜在的数据泄露风险。", + "ja": "FC サービスのインターネットアクセスを無効にすることで、攻撃面とデータ漏洩の可能性を減らします。", + "de": "Das Deaktivieren des Internetzugriffs für FC-Services reduziert die Angriffsfläche und das Potenzial für Datenexfiltration.", + "es": "Deshabilitar el acceso a Internet para los servicios FC reduce la superficie de ataque y el potencial de exfiltración de datos.", + "fr": "Désactiver l'accès Internet pour les services FC réduit la surface d'attaque et le potentiel d'exfiltration de données.", + "pt": "Desabilitar o acesso à Internet para serviços FC reduz a superfície de ataque e o potencial de exfiltração de dados." + }, + "recommendation": { + "en": "Disable internet access for the Function Compute service.", + "zh": "为函数计算服务禁用公网访问。", + "ja": "関数計算サービスのインターネットアクセスを無効にします。", + "de": "Deaktivieren Sie den Internetzugriff für den Function Compute-Service.", + "es": "Deshabilite el acceso a Internet para el servicio Function Compute.", + "fr": "Désactivez l'accès Internet pour le service Function Compute.", + "pt": "Desabilite o acesso à Internet para o serviço Function Compute." + }, + "resource_types": ["ALIYUN::FC::Service"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::FC::Service") + helpers.get_property(resource, "InternetAccess", true) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InternetAccess"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-key-rotation-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-key-rotation-enabled.rego new file mode 100644 index 0000000..8e92ee8 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-key-rotation-enabled.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.kms_key_rotation_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "kms-key-rotation-enabled", + "severity": "medium", + "name": { + "en": "KMS key automatic rotation enabled", + "zh": "密钥管理服务设置主密钥自动轮转", + "ja": "KMS キーの自動ローテーションが有効", + "de": "KMS-Schlüssel automatische Rotation aktiviert", + "es": "Rotación automática de clave KMS habilitada", + "fr": "Rotation automatique de clé KMS activée", + "pt": "Rotação automática de chave KMS habilitada" + }, + "description": { + "en": "KMS user master key has automatic rotation enabled, considered compliant. Service keys and externally imported keys are not applicable.", + "zh": "对密钥管理服务中的用户主密钥设置自动轮转,视为合规。如果是服务密钥,视为不适用。如果来源是用户自带密钥,视为不适用。", + "ja": "KMS ユーザーマスターキーで自動ローテーションが有効になっている場合、準拠と見なされます。サービスキーと外部からインポートされたキーは適用されません。", + "de": "KMS-Benutzer-Hauptschlüssel hat automatische Rotation aktiviert, wird als konform betrachtet. Dienstschlüssel und extern importierte Schlüssel sind nicht anwendbar.", + "es": "La clave maestra de usuario KMS tiene rotación automática habilitada, considerada conforme. Las claves de servicio y las claves importadas externamente no son aplicables.", + "fr": "La clé maître utilisateur KMS a la rotation automatique activée, considérée comme conforme. Les clés de service et les clés importées externement ne sont pas applicables.", + "pt": "Chave mestra de usuário KMS tem rotação automática habilitada, considerada conforme. Chaves de serviço e chaves importadas externamente não são aplicáveis." + }, + "reason": { + "en": "KMS key does not have automatic rotation enabled", + "zh": "KMS 主密钥未开启自动轮转", + "ja": "KMS キーで自動ローテーションが有効になっていません", + "de": "KMS-Schlüssel hat keine automatische Rotation aktiviert", + "es": "La clave KMS no tiene rotación automática habilitada", + "fr": "La clé KMS n'a pas la rotation automatique activée", + "pt": "Chave KMS não tem rotação automática habilitada" + }, + "recommendation": { + "en": "Enable automatic rotation for KMS key to enhance security by regularly rotating encryption keys", + "zh": "为 KMS 主密钥启用自动轮转以通过定期轮换加密密钥来增强安全性", + "ja": "暗号化キーを定期的にローテーションしてセキュリティを強化するために、KMS キーで自動ローテーションを有効にします", + "de": "Aktivieren Sie die automatische Rotation für KMS-Schlüssel, um die Sicherheit durch regelmäßige Rotation von Verschlüsselungsschlüsseln zu verbessern", + "es": "Habilite la rotación automática para la clave KMS para mejorar la seguridad rotando claves de cifrado regularmente", + "fr": "Activez la rotation automatique pour la clé KMS pour améliorer la sécurité en faisant tourner régulièrement les clés de chiffrement", + "pt": "Habilite rotação automática para chave KMS para melhorar a segurança rotacionando chaves de criptografia regularmente" + }, + "resource_types": ["ALIYUN::KMS::Key"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::KMS::Key") + + # Check if EnableAutomaticRotation is enabled + rotation_enabled := helpers.get_property(resource, "EnableAutomaticRotation", false) + not helpers.is_true(rotation_enabled) + + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-secret-rotation-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-secret-rotation-enabled.rego new file mode 100644 index 0000000..46bd29f --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/kms-secret-rotation-enabled.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.kms_secret_rotation_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "kms-secret-rotation-enabled", + "severity": "medium", + "name": { + "en": "KMS secret automatic rotation enabled", + "zh": "密钥管理服务设置凭据自动轮转", + "ja": "KMS シークレットの自動ローテーションが有効", + "de": "KMS-Geheimnis automatische Rotation aktiviert", + "es": "Rotación automática de secreto KMS habilitada", + "fr": "Rotation automatique de secret KMS activée", + "pt": "Rotação automática de segredo KMS habilitada" + }, + "description": { + "en": "KMS secret has automatic rotation enabled, considered compliant. Generic secrets are not applicable.", + "zh": "密钥管理服务中的凭据设置自动轮转,视为合规。如果密钥类型为普通密钥,视为不适用。", + "ja": "KMS シークレットで自動ローテーションが有効になっている場合、準拠と見なされます。汎用シークレットは適用されません。", + "de": "KMS-Geheimnis hat automatische Rotation aktiviert, wird als konform betrachtet. Generische Geheimnisse sind nicht anwendbar.", + "es": "El secreto KMS tiene rotación automática habilitada, considerado conforme. Los secretos genéricos no son aplicables.", + "fr": "Le secret KMS a la rotation automatique activée, considéré comme conforme. Les secrets génériques ne sont pas applicables.", + "pt": "Segredo KMS tem rotação automática habilitada, considerado conforme. Segredos genéricos não são aplicáveis." + }, + "reason": { + "en": "KMS secret does not have automatic rotation enabled", + "zh": "KMS 凭据未开启自动轮转", + "ja": "KMS シークレットで自動ローテーションが有効になっていません", + "de": "KMS-Geheimnis hat keine automatische Rotation aktiviert", + "es": "El secreto KMS no tiene rotación automática habilitada", + "fr": "Le secret KMS n'a pas la rotation automatique activée", + "pt": "Segredo KMS não tem rotação automática habilitada" + }, + "recommendation": { + "en": "Enable automatic rotation for KMS secret to enhance security by regularly rotating credentials", + "zh": "为 KMS 凭据启用自动轮转以通过定期轮换凭据来增强安全性", + "ja": "認証情報を定期的にローテーションしてセキュリティを強化するために、KMS シークレットで自動ローテーションを有効にします", + "de": "Aktivieren Sie die automatische Rotation für KMS-Geheimnisse, um die Sicherheit durch regelmäßige Rotation von Anmeldeinformationen zu verbessern", + "es": "Habilite la rotación automática para el secreto KMS para mejorar la seguridad rotando credenciales regularmente", + "fr": "Activez la rotation automatique pour le secret KMS pour améliorer la sécurité en faisant tourner régulièrement les identifiants", + "pt": "Habilite rotação automática para segredo KMS para melhorar a segurança rotacionando credenciais regularmente" + }, + "resource_types": ["ALIYUN::KMS::Secret"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::KMS::Secret") + + # Check if EnableAutomaticRotation is enabled + rotation_enabled := helpers.get_property(resource, "EnableAutomaticRotation", false) + not helpers.is_true(rotation_enabled) + + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-logging-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-logging-enabled.rego new file mode 100644 index 0000000..3df34e5 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-logging-enabled.rego @@ -0,0 +1,68 @@ +package infraguard.rules.aliyun.oss_bucket_logging_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-logging-enabled", + "severity": "medium", + "name": { + "en": "OSS Bucket Logging Enabled", + "zh": "OSS 存储空间开启日志转存", + "ja": "OSS バケットのログ記録が有効", + "de": "OSS-Bucket Protokollierung aktiviert", + "es": "Registro de Logs de Bucket OSS Habilitado", + "fr": "Journalisation de Bucket OSS Activée", + "pt": "Registro de Logs de Bucket OSS Habilitado" + }, + "description": { + "en": "OSS buckets should have logging enabled to track access and operations. Logging helps with security auditing, troubleshooting, and compliance requirements.", + "zh": "OSS 存储空间应开启日志转存以跟踪访问和操作。日志记录有助于安全审计、故障排查和合规要求。", + "ja": "OSS バケットは、アクセスと操作を追跡するためにログ記録を有効にする必要があります。ログ記録は、セキュリティ監査、トラブルシューティング、コンプライアンス要件に役立ちます。", + "de": "OSS-Buckets sollten Protokollierung aktiviert haben, um Zugriffe und Vorgänge zu verfolgen. Die Protokollierung hilft bei Sicherheitsaudits, Fehlerbehebung und Compliance-Anforderungen.", + "es": "Los buckets OSS deben tener registro de logs habilitado para rastrear acceso y operaciones. El registro de logs ayuda en la auditoría de seguridad, solución de problemas y requisitos de conformidad.", + "fr": "Les buckets OSS doivent avoir la journalisation activée pour suivre les accès et les opérations. La journalisation aide à l'audit de sécurité, au dépannage et aux exigences de conformité.", + "pt": "Buckets OSS devem ter registro de logs habilitado para rastrear acesso e operações. O registro de logs ajuda na auditoria de segurança, solução de problemas e requisitos de conformidade." + }, + "reason": { + "en": "The OSS bucket does not have logging enabled, which makes it difficult to track access and operations for security and compliance purposes.", + "zh": "OSS 存储空间未开启日志转存,难以跟踪访问和操作以满足安全和合规要求。", + "ja": "OSS バケットでログ記録が有効になっていないため、セキュリティとコンプライアンスの目的でアクセスと操作を追跡することが困難です。", + "de": "Der OSS-Bucket hat keine Protokollierung aktiviert, was es schwierig macht, Zugriffe und Vorgänge für Sicherheits- und Compliance-Zwecke zu verfolgen.", + "es": "El bucket OSS no tiene registro de logs habilitado, lo que dificulta rastrear acceso y operaciones para fines de seguridad y conformidad.", + "fr": "Le bucket OSS n'a pas la journalisation activée, ce qui rend difficile le suivi des accès et des opérations à des fins de sécurité et de conformité.", + "pt": "O bucket OSS não tem registro de logs habilitado, o que dificulta rastrear acesso e operações para fins de segurança e conformidade." + }, + "recommendation": { + "en": "Enable logging for the OSS bucket by configuring the LoggingConfiguration property with TargetBucket and optionally TargetPrefix.", + "zh": "通过配置 LoggingConfiguration 属性并设置 TargetBucket 和可选的 TargetPrefix,为 OSS 存储空间启用日志转存。", + "ja": "TargetBucket とオプションで TargetPrefix を使用して LoggingConfiguration プロパティを設定することで、OSS バケットのログ記録を有効にします。", + "de": "Aktivieren Sie die Protokollierung für den OSS-Bucket, indem Sie die LoggingConfiguration-Eigenschaft mit TargetBucket und optional TargetPrefix konfigurieren.", + "es": "Habilite el registro de logs para el bucket OSS configurando la propiedad LoggingConfiguration con TargetBucket y opcionalmente TargetPrefix.", + "fr": "Activez la journalisation pour le bucket OSS en configurant la propriété LoggingConfiguration avec TargetBucket et éventuellement TargetPrefix.", + "pt": "Habilite registro de logs para o bucket OSS configurando a propriedade LoggingConfiguration com TargetBucket e opcionalmente TargetPrefix." + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not has_logging_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoggingConfiguration"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +has_logging_enabled(resource) if { + helpers.has_property(resource, "LoggingConfiguration") + logging_config := resource.Properties.LoggingConfiguration + logging_config.TargetBucket != null +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-only-https-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-only-https-enabled.rego new file mode 100644 index 0000000..f1d593e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-only-https-enabled.rego @@ -0,0 +1,98 @@ +package infraguard.rules.aliyun.oss_bucket_only_https_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-only-https-enabled", + "severity": "high", + "name": { + "en": "OSS Bucket Only HTTPS Enabled", + "zh": "OSS 存储桶开启仅允许 HTTPS 访问", + "ja": "OSS バケットで HTTPS のみが有効", + "de": "OSS-Bucket nur HTTPS aktiviert", + "es": "Solo HTTPS de Bucket OSS Habilitado", + "fr": "Seul HTTPS de Bucket OSS Activé", + "pt": "Apenas HTTPS de Bucket OSS Habilitado" + }, + "description": { + "en": "OSS bucket should have a policy that denies non-HTTPS requests to ensure data transport security.", + "zh": "OSS 存储桶应配置仅允许 HTTPS 访问的策略,以确保数据传输安全。", + "ja": "OSS バケットは、データ転送のセキュリティを確保するために、非 HTTPS リクエストを拒否するポリシーを持つ必要があります。", + "de": "OSS-Bucket sollte eine Richtlinie haben, die Nicht-HTTPS-Anfragen ablehnt, um die Datentransportsicherheit zu gewährleisten.", + "es": "El bucket OSS debe tener una política que niegue las solicitudes que no sean HTTPS para garantizar la seguridad del transporte de datos.", + "fr": "Le bucket OSS doit avoir une politique qui refuse les requêtes non-HTTPS pour assurer la sécurité du transport des données.", + "pt": "O bucket OSS deve ter uma política que negue solicitações não HTTPS para garantir a segurança do transporte de dados." + }, + "reason": { + "en": "The OSS bucket allows non-HTTPS requests, which may lead to data interception or tampering during transport.", + "zh": "OSS 存储桶允许非 HTTPS 请求,可能导致数据在传输过程中被窃听或篡改。", + "ja": "OSS バケットが非 HTTPS リクエストを許可しているため、転送中にデータが傍受または改ざんされる可能性があります。", + "de": "Der OSS-Bucket erlaubt Nicht-HTTPS-Anfragen, was zu Datenabfangen oder Manipulation während des Transports führen kann.", + "es": "El bucket OSS permite solicitudes que no sean HTTPS, lo que puede llevar a la interceptación o manipulación de datos durante el transporte.", + "fr": "Le bucket OSS autorise les requêtes non-HTTPS, ce qui peut entraîner une interception ou une falsification des données pendant le transport.", + "pt": "O bucket OSS permite solicitações não HTTPS, o que pode levar à interceptação ou adulteração de dados durante o transporte." + }, + "recommendation": { + "en": "Configure a bucket policy that denies requests where 'acs:SecureTransport' is false.", + "zh": "配置存储桶策略,拒绝 'acs:SecureTransport' 为 false 的请求。", + "ja": "'acs:SecureTransport' が false のリクエストを拒否するバケットポリシーを設定します。", + "de": "Konfigurieren Sie eine Bucket-Richtlinie, die Anfragen ablehnt, bei denen 'acs:SecureTransport' false ist.", + "es": "Configure una política de bucket que niegue las solicitudes donde 'acs:SecureTransport' es false.", + "fr": "Configurez une politique de bucket qui refuse les requêtes où 'acs:SecureTransport' est false.", + "pt": "Configure uma política de bucket que negue solicitações onde 'acs:SecureTransport' é false." + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +# Check if the bucket has a policy that enforces HTTPS +is_only_https_enabled(resource) if { + policy := helpers.get_property(resource, "Policy", {}) + statements := object.get(policy, "Statement", []) + some statement in statements + statement.Effect == "Deny" + + # Check for SecureTransport condition + condition := object.get(statement, "Condition", {}) + bool_cond := object.get(condition, "Bool", {}) + secure_transport := object.get(bool_cond, "acs:SecureTransport", null) + has_false_value(secure_transport) +} + +has_false_value(val) if { + val == "false" +} + +has_false_value(val) if { + val == false +} + +has_false_value(val) if { + is_array(val) + some item in val + item_is_false(item) +} + +item_is_false(v) if { + v == "false" +} + +item_is_false(v) if { + v == false +} + +deny contains result if { + some name, resource in helpers.resources_by_types(rule_meta.resource_types) + not is_only_https_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Policy"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-read-prohibited.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-read-prohibited.rego new file mode 100644 index 0000000..9a45fd1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-read-prohibited.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.oss_bucket_public_read_prohibited + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-public-read-prohibited", + "severity": "high", + "name": { + "en": "OSS Bucket Public Read Prohibited", + "zh": "OSS 存储空间 ACL 不开启公共读", + "ja": "OSS バケットのパブリック読み取りが禁止", + "de": "OSS-Bucket öffentliches Lesen verboten", + "es": "Lectura Pública de Bucket OSS Prohibida", + "fr": "Lecture Publique de Bucket OSS Interdite", + "pt": "Leitura Pública de Bucket OSS Proibida" + }, + "description": { + "en": "OSS buckets should not allow public read access unless specifically required. Public read access allows anyone to access and download objects in the bucket.", + "zh": "除非特别需要,OSS 存储空间不应允许公共读取访问。公共读取访问允许任何人访问和下载存储空间中的对象。", + "ja": "特に必要な場合を除き、OSS バケットはパブリック読み取りアクセスを許可すべきではありません。パブリック読み取りアクセスにより、誰でもバケット内のオブジェクトにアクセスしてダウンロードできます。", + "de": "OSS-Buckets sollten keinen öffentlichen Lesezugriff zulassen, es sei denn, dies ist ausdrücklich erforderlich. Öffentlicher Lesezugriff ermöglicht es jedem, auf Objekte im Bucket zuzugreifen und sie herunterzuladen.", + "es": "Los buckets OSS no deben permitir acceso de lectura público a menos que sea específicamente necesario. El acceso de lectura público permite a cualquiera acceder y descargar objetos en el bucket.", + "fr": "Les buckets OSS ne doivent pas autoriser l'accès en lecture public sauf si cela est spécifiquement requis. L'accès en lecture public permet à quiconque d'accéder et de télécharger des objets dans le bucket.", + "pt": "Buckets OSS não devem permitir acesso de leitura público, a menos que especificamente necessário. O acesso de leitura público permite que qualquer pessoa acesse e baixe objetos no bucket." + }, + "reason": { + "en": "The OSS bucket has public read access enabled, which may expose sensitive data to unauthorized access.", + "zh": "OSS 存储空间启用了公共读取访问,可能导致敏感数据暴露给未授权访问。", + "ja": "OSS バケットでパブリック読み取りアクセスが有効になっているため、機密データが不正アクセスにさらされる可能性があります。", + "de": "Der OSS-Bucket hat öffentlichen Lesezugriff aktiviert, was sensible Daten unbefugtem Zugriff aussetzen kann.", + "es": "El bucket OSS tiene habilitado el acceso de lectura público, lo que puede exponer datos sensibles a acceso no autorizado.", + "fr": "Le bucket OSS a l'accès en lecture public activé, ce qui peut exposer des données sensibles à un accès non autorisé.", + "pt": "O bucket OSS tem acesso de leitura público habilitado, o que pode expor dados sensíveis a acesso não autorizado." + }, + "recommendation": { + "en": "Change the bucket ACL to private by setting the AccessControl property to 'private'.", + "zh": "通过将 AccessControl 属性设置为'private',将存储空间 ACL 更改为私有。", + "ja": "AccessControl プロパティを 'private' に設定して、バケット ACL をプライベートに変更します。", + "de": "Ändern Sie die Bucket-ACL auf privat, indem Sie die AccessControl-Eigenschaft auf 'private' setzen.", + "es": "Cambie el ACL del bucket a privado estableciendo la propiedad AccessControl en 'private'.", + "fr": "Modifiez l'ACL du bucket en privé en définissant la propriété AccessControl sur 'private'.", + "pt": "Altere o ACL do bucket para privado definindo a propriedade AccessControl como 'private'." + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + is_public_read(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AccessControl"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_public_read(resource) if { + resource.Properties.AccessControl in ["public-read", "public-read-write"] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-write-prohibited.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-write-prohibited.rego new file mode 100644 index 0000000..9547232 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-public-write-prohibited.rego @@ -0,0 +1,66 @@ +package infraguard.rules.aliyun.oss_bucket_public_write_prohibited + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-public-write-prohibited", + "severity": "high", + "name": { + "en": "OSS Bucket Public Write Prohibited", + "zh": "OSS 存储空间 ACL 不开启公共读写", + "ja": "OSS バケットのパブリック書き込みが禁止", + "de": "OSS-Bucket öffentliches Schreiben verboten", + "es": "Escritura Pública de Bucket OSS Prohibida", + "fr": "Écriture Publique de Bucket OSS Interdite", + "pt": "Escrita Pública de Bucket OSS Proibida" + }, + "description": { + "en": "OSS buckets should not allow public write access. Public write access allows anyone to upload, modify, or delete objects in the bucket, which poses significant security risks.", + "zh": "OSS 存储空间不应允许公共写入访问。公共写入访问允许任何人上传、修改或删除存储空间中的对象,这会带来重大安全风险。", + "ja": "OSS バケットはパブリック書き込みアクセスを許可すべきではありません。パブリック書き込みアクセスにより、誰でもバケット内のオブジェクトをアップロード、変更、または削除でき、重大なセキュリティリスクをもたらします。", + "de": "OSS-Buckets sollten keinen öffentlichen Schreibzugriff zulassen. Öffentlicher Schreibzugriff ermöglicht es jedem, Objekte im Bucket hochzuladen, zu ändern oder zu löschen, was erhebliche Sicherheitsrisiken birgt.", + "es": "Los buckets OSS no deben permitir acceso de escritura público. El acceso de escritura público permite a cualquiera cargar, modificar o eliminar objetos en el bucket, lo que plantea riesgos de seguridad significativos.", + "fr": "Les buckets OSS ne doivent pas autoriser l'accès en écriture public. L'accès en écriture public permet à quiconque de télécharger, modifier ou supprimer des objets dans le bucket, ce qui pose des risques de sécurité importants.", + "pt": "Buckets OSS não devem permitir acesso de escrita público. O acesso de escrita público permite que qualquer pessoa faça upload, modifique ou exclua objetos no bucket, o que representa riscos significativos de segurança." + }, + "reason": { + "en": "The OSS bucket has public write access enabled (public-read-write ACL), which allows unauthorized users to modify or delete data.", + "zh": "OSS 存储空间启用了公共写入访问(public-read-write ACL),允许未授权用户修改或删除数据。", + "ja": "OSS バケットでパブリック書き込みアクセスが有効になっている(public-read-write ACL)ため、不正なユーザーがデータを変更または削除できます。", + "de": "Der OSS-Bucket hat öffentlichen Schreibzugriff aktiviert (public-read-write ACL), was unbefugten Benutzern ermöglicht, Daten zu ändern oder zu löschen.", + "es": "El bucket OSS tiene habilitado el acceso de escritura público (ACL public-read-write), lo que permite a usuarios no autorizados modificar o eliminar datos.", + "fr": "Le bucket OSS a l'accès en écriture public activé (ACL public-read-write), ce qui permet aux utilisateurs non autorisés de modifier ou supprimer des données.", + "pt": "O bucket OSS tem acesso de escrita público habilitado (ACL public-read-write), o que permite que usuários não autorizados modifiquem ou excluam dados." + }, + "recommendation": { + "en": "Change the bucket ACL to private or public-read by setting the AccessControl property to 'private' or 'public-read'.", + "zh": "通过将 AccessControl 属性设置为'private'或'public-read',将存储空间 ACL 更改为私有或公共读。", + "ja": "AccessControl プロパティを 'private' または 'public-read' に設定して、バケット ACL をプライベートまたはパブリック読み取りに変更します。", + "de": "Ändern Sie die Bucket-ACL auf privat oder öffentlich-lesen, indem Sie die AccessControl-Eigenschaft auf 'private' oder 'public-read' setzen.", + "es": "Cambie el ACL del bucket a privado o lectura pública estableciendo la propiedad AccessControl en 'private' o 'public-read'.", + "fr": "Modifiez l'ACL du bucket en privé ou lecture publique en définissant la propriété AccessControl sur 'private' ou 'public-read'.", + "pt": "Altere o ACL do bucket para privado ou leitura pública definindo a propriedade AccessControl como 'private' ou 'public-read'." + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + is_public_write(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AccessControl"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_public_write(resource) if { + resource.Properties.AccessControl == "public-read-write" +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-server-side-encryption-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-server-side-encryption-enabled.rego new file mode 100644 index 0000000..a5ab22c --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/oss-bucket-server-side-encryption-enabled.rego @@ -0,0 +1,68 @@ +package infraguard.rules.aliyun.oss_bucket_server_side_encryption_enabled + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "oss-bucket-server-side-encryption-enabled", + "severity": "high", + "name": { + "en": "OSS Bucket Server-Side Encryption Enabled", + "zh": "OSS 存储空间开启服务端加密", + "ja": "OSS バケットのサーバー側暗号化が有効", + "de": "OSS-Bucket-Serverseitige-Verschlüsselung aktiviert", + "es": "Cifrado del Lado del Servidor de Bucket OSS Habilitado", + "fr": "Chiffrement Côté Serveur de Bucket OSS Activé", + "pt": "Criptografia do Lado do Servidor de Bucket OSS Habilitada" + }, + "description": { + "en": "OSS buckets should have server-side encryption enabled to protect data at rest. Server-side encryption uses KMS or AES256 to encrypt data stored in OSS.", + "zh": "OSS 存储空间应开启服务端加密以保护静态数据。服务端加密使用 KMS 或 AES256 对存储在 OSS 中的数据进行加密。", + "ja": "OSS バケットは、保存データを保護するためにサーバー側暗号化を有効にする必要があります。サーバー側暗号化は KMS または AES256 を使用して OSS に保存されたデータを暗号化します。", + "de": "OSS-Buckets sollten serverseitige Verschlüsselung aktiviert haben, um ruhende Daten zu schützen. Die serverseitige Verschlüsselung verwendet KMS oder AES256, um in OSS gespeicherte Daten zu verschlüsseln.", + "es": "Los buckets OSS deben tener cifrado del lado del servidor habilitado para proteger los datos en reposo. El cifrado del lado del servidor usa KMS o AES256 para cifrar datos almacenados en OSS.", + "fr": "Les buckets OSS doivent avoir le chiffrement côté serveur activé pour protéger les données au repos. Le chiffrement côté serveur utilise KMS ou AES256 pour chiffrer les données stockées dans OSS.", + "pt": "Buckets OSS devem ter criptografia do lado do servidor habilitada para proteger dados em repouso. A criptografia do lado do servidor usa KMS ou AES256 para criptografar dados armazenados no OSS." + }, + "reason": { + "en": "The OSS bucket does not have server-side encryption enabled, which may expose sensitive data to unauthorized access.", + "zh": "OSS 存储空间未开启服务端加密,可能导致敏感数据暴露给未授权访问。", + "ja": "OSS バケットでサーバー側暗号化が有効になっていないため、機密データが不正アクセスにさらされる可能性があります。", + "de": "Der OSS-Bucket hat keine serverseitige Verschlüsselung aktiviert, was sensible Daten unbefugtem Zugriff aussetzen kann.", + "es": "El bucket OSS no tiene cifrado del lado del servidor habilitado, lo que puede exponer datos sensibles a acceso no autorizado.", + "fr": "Le bucket OSS n'a pas le chiffrement côté serveur activé, ce qui peut exposer des données sensibles à un accès non autorisé.", + "pt": "O bucket OSS não tem criptografia do lado do servidor habilitada, o que pode expor dados sensíveis a acesso não autorizado." + }, + "recommendation": { + "en": "Enable server-side encryption for the OSS bucket by configuring the ServerSideEncryptionConfiguration property with SSEAlgorithm set to KMS, AES256, or SM4.", + "zh": "通过配置 ServerSideEncryptionConfiguration 属性并将 SSEAlgorithm 设置为 KMS、AES256 或 SM4,为 OSS 存储空间启用服务端加密。", + "ja": "SSEAlgorithm を KMS、AES256、または SM4 に設定して ServerSideEncryptionConfiguration プロパティを設定することで、OSS バケットのサーバー側暗号化を有効にします。", + "de": "Aktivieren Sie die serverseitige Verschlüsselung für den OSS-Bucket, indem Sie die ServerSideEncryptionConfiguration-Eigenschaft mit SSEAlgorithm auf KMS, AES256 oder SM4 konfigurieren.", + "es": "Habilite el cifrado del lado del servidor para el bucket OSS configurando la propiedad ServerSideEncryptionConfiguration con SSEAlgorithm establecido en KMS, AES256 o SM4.", + "fr": "Activez le chiffrement côté serveur pour le bucket OSS en configurant la propriété ServerSideEncryptionConfiguration avec SSEAlgorithm défini sur KMS, AES256 ou SM4.", + "pt": "Habilite criptografia do lado do servidor para o bucket OSS configurando a propriedade ServerSideEncryptionConfiguration com SSEAlgorithm definido como KMS, AES256 ou SM4." + }, + "resource_types": ["ALIYUN::OSS::Bucket"] +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not has_server_side_encryption(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ServerSideEncryptionConfiguration"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +has_server_side_encryption(resource) if { + helpers.has_property(resource, "ServerSideEncryptionConfiguration") + sse_config := resource.Properties.ServerSideEncryptionConfiguration + sse_config.SSEAlgorithm in ["KMS", "AES256", "SM4"] +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-password-policy-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-password-policy-check.rego new file mode 100644 index 0000000..4e25ff1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-password-policy-check.rego @@ -0,0 +1,68 @@ +package infraguard.rules.aliyun.ram_password_policy_check + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata +rule_meta := { + "id": "ram-password-policy-check", + "severity": "medium", + "name": { + "en": "RAM Password Policy Check", + "zh": "RAM 密码策略检测", + "ja": "RAM パスワードポリシーチェック", + "de": "RAM-Passwortrichtlinien-Prüfung", + "es": "Verificación de Política de Contraseña RAM", + "fr": "Vérification de la Politique de Mot de Passe RAM", + "pt": "Verificação de Política de Senha RAM" + }, + "description": { + "en": "Ensures that the RAM password policy meets the specified security requirements.", + "zh": "确保 RAM 密码策略符合指定的安全要求。", + "ja": "RAM パスワードポリシーが指定されたセキュリティ要件を満たしていることを確認します。", + "de": "Stellt sicher, dass die RAM-Passwortrichtlinie die festgelegten Sicherheitsanforderungen erfüllt.", + "es": "Garantiza que la política de contraseña RAM cumpla con los requisitos de seguridad especificados.", + "fr": "Garantit que la politique de mot de passe RAM répond aux exigences de sécurité spécifiées.", + "pt": "Garante que a política de senha RAM atenda aos requisitos de segurança especificados." + }, + "reason": { + "en": "Strong password policies help prevent unauthorized access to accounts.", + "zh": "强密码策略有助于防止对账号的未经授权访问。", + "ja": "強力なパスワードポリシーは、アカウントへの不正アクセスを防ぐのに役立ちます。", + "de": "Starke Passwortrichtlinien helfen, unbefugten Zugriff auf Konten zu verhindern.", + "es": "Las políticas de contraseña fuertes ayudan a prevenir el acceso no autorizado a las cuentas.", + "fr": "Des politiques de mot de passe fortes aident à prévenir l'accès non autorisé aux comptes.", + "pt": "Políticas de senha fortes ajudam a prevenir acesso não autorizado a contas." + }, + "recommendation": { + "en": "Configure a strong RAM password policy including length, character types, and rotation.", + "zh": "配置强 RAM 密码策略,包括长度、字符类型和定期轮换。", + "ja": "長さ、文字タイプ、ローテーションを含む強力な RAM パスワードポリシーを設定します。", + "de": "Konfigurieren Sie eine starke RAM-Passwortrichtlinie, einschließlich Länge, Zeichentypen und Rotation.", + "es": "Configure una política de contraseña RAM fuerte que incluya longitud, tipos de caracteres y rotación.", + "fr": "Configurez une politique de mot de passe RAM forte incluant la longueur, les types de caractères et la rotation.", + "pt": "Configure uma política de senha RAM forte incluindo comprimento, tipos de caracteres e rotação." + }, + "resource_types": ["ALIYUN::RAM::PasswordPolicy"] +} + +# This rule typically checks RAM::PasswordPolicy resources +# Since a ROS template might not have this, we check it if it exists. +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RAM::PasswordPolicy") + + # Logic to check properties like MinimumPasswordLength + props := resource.Properties + not props.MinimumPasswordLength >= 8 + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MinimumPasswordLength"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-policy-no-statements-with-admin-access-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-policy-no-statements-with-admin-access-check.rego new file mode 100644 index 0000000..d1a9184 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-policy-no-statements-with-admin-access-check.rego @@ -0,0 +1,78 @@ +package infraguard.rules.aliyun.ram_policy_no_statements_with_admin_access_check + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "ram-policy-no-statements-with-admin-access-check", + "severity": "high", + "name": { + "en": "RAM Policy No Admin Access", + "zh": "禁止 RAM 策略包含管理员权限", + "ja": "RAM ポリシーに管理者アクセスなし", + "de": "RAM-Richtlinie kein Admin-Zugriff", + "es": "Política RAM Sin Acceso de Administrador", + "fr": "Politique RAM Sans Accès Administrateur", + "pt": "Política RAM Sem Acesso de Administrador" + }, + "description": { + "en": "Ensures custom RAM policies do not grant full AdministratorAccess.", + "zh": "确保自定义 RAM 策略未授予完全的管理员权限(AdministratorAccess)。", + "ja": "カスタム RAM ポリシーが完全な AdministratorAccess を付与していないことを確認します。", + "de": "Stellt sicher, dass benutzerdefinierte RAM-Richtlinien keinen vollständigen AdministratorAccess gewähren.", + "es": "Garantiza que las políticas RAM personalizadas no otorguen acceso completo de administrador.", + "fr": "Garantit que les politiques RAM personnalisées n'accordent pas un accès administrateur complet.", + "pt": "Garante que políticas RAM personalizadas não concedam acesso completo de administrador." + }, + "reason": { + "en": "Granting excessive permissions increases the impact of a compromised account.", + "zh": "授予过高权限会增加账号被盗后的危害。", + "ja": "過剰な権限を付与すると、侵害されたアカウントの影響が増大します。", + "de": "Das Gewähren übermäßiger Berechtigungen erhöht die Auswirkungen eines kompromittierten Kontos.", + "es": "Otorgar permisos excesivos aumenta el impacto de una cuenta comprometida.", + "fr": "Accorder des permissions excessives augmente l'impact d'un compte compromis.", + "pt": "Conceder permissões excessivas aumenta o impacto de uma conta comprometida." + }, + "recommendation": { + "en": "Follow the principle of least privilege. Do not use '*' for both Action and Resource in the same statement.", + "zh": "遵循最小权限原则。不要在同一条语句中对 Action 和 Resource 同时使用 '*'。", + "ja": "最小権限の原則に従います。同じステートメントで Action と Resource の両方に '*' を使用しないでください。", + "de": "Befolgen Sie das Prinzip der geringsten Berechtigung. Verwenden Sie nicht '*' für sowohl Action als auch Resource in derselben Anweisung.", + "es": "Siga el principio de menor privilegio. No use '*' para tanto Action como Resource en la misma declaración.", + "fr": "Suivez le principe du moindre privilège. N'utilisez pas '*' pour Action et Resource dans la même déclaration.", + "pt": "Siga o princípio do menor privilégio. Não use '*' para Action e Resource na mesma declaração." + }, + "resource_types": ["ALIYUN::RAM::ManagedPolicy"] +} + +is_compliant(resource) if { + doc := helpers.get_property(resource, "PolicyDocument", {}) + statements := object.get(doc, "Statement", []) + not has_admin_statement(statements) +} + +has_admin_statement(statements) if { + some statement in statements + statement.Effect == "Allow" + is_all(statement.Action) + is_all(statement.Resource) +} + +is_all("*") := true + +is_all(a) if { + is_array(a) + some item in a + item == "*" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RAM::ManagedPolicy") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "PolicyDocument"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-user-mfa-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-user-mfa-check.rego new file mode 100644 index 0000000..89ac9a8 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/ram-user-mfa-check.rego @@ -0,0 +1,72 @@ +package infraguard.rules.aliyun.ram_user_mfa_check + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "ram-user-mfa-check", + "severity": "high", + "name": { + "en": "RAM User MFA Enabled", + "zh": "RAM 用户开启 MFA", + "ja": "RAM ユーザーで MFA が有効", + "de": "RAM-Benutzer MFA aktiviert", + "es": "MFA de Usuario RAM Habilitado", + "fr": "MFA Utilisateur RAM Activé", + "pt": "MFA de Usuário RAM Habilitado" + }, + "description": { + "en": "RAM users with console access should have multi-factor authentication (MFA) enabled.", + "zh": "检测 RAM 用户是否开通 MFA 二次验证登录,开通视为合规。", + "ja": "コンソールアクセスを持つ RAM ユーザーは、多要素認証(MFA)を有効にする必要があります。", + "de": "RAM-Benutzer mit Konsolenzugriff sollten Multi-Faktor-Authentifizierung (MFA) aktiviert haben.", + "es": "Los usuarios RAM con acceso a la consola deben tener habilitada la autenticación multifactor (MFA).", + "fr": "Les utilisateurs RAM avec accès à la console doivent avoir l'authentification multifacteur (MFA) activée.", + "pt": "Usuários RAM com acesso ao console devem ter autenticação multifator (MFA) habilitada." + }, + "reason": { + "en": "RAM users without MFA are vulnerable to password compromise, posing a significant security risk.", + "zh": "RAM 用户未开启 MFA,一旦密码泄露,账号将面临极大的安全风险。", + "ja": "MFA がない RAM ユーザーはパスワードの侵害に対して脆弱で、重大なセキュリティリスクをもたらします。", + "de": "RAM-Benutzer ohne MFA sind anfällig für Passwortkompromittierung und stellen ein erhebliches Sicherheitsrisiko dar.", + "es": "Los usuarios RAM sin MFA son vulnerables al compromiso de contraseñas, lo que plantea un riesgo de seguridad significativo.", + "fr": "Les utilisateurs RAM sans MFA sont vulnérables au compromis de mot de passe, ce qui pose un risque de sécurité important.", + "pt": "Usuários RAM sem MFA são vulneráveis a comprometimento de senha, representando um risco significativo de segurança." + }, + "recommendation": { + "en": "Enable MFA for the RAM user by setting LoginProfile.MFABindRequired to true.", + "zh": "通过将 LoginProfile.MFABindRequired 设置为 true 为 RAM 用户强制开启 MFA。", + "ja": "LoginProfile.MFABindRequired を true に設定して、RAM ユーザーで MFA を有効にします。", + "de": "Aktivieren Sie MFA für den RAM-Benutzer, indem Sie LoginProfile.MFABindRequired auf true setzen.", + "es": "Habilite MFA para el usuario RAM estableciendo LoginProfile.MFABindRequired en true.", + "fr": "Activez MFA pour l'utilisateur RAM en définissant LoginProfile.MFABindRequired sur true.", + "pt": "Habilite MFA para o usuário RAM definindo LoginProfile.MFABindRequired como true." + }, + "resource_types": ["ALIYUN::RAM::User"] +} + +# Check if MFA is required for login +is_mfa_enabled(resource) if { + login_profile := helpers.get_property(resource, "LoginProfile", {}) + mfa := object.get(login_profile, "MFABindRequired", false) + helpers.is_true(mfa) +} + +deny contains result if { + some name, resource in helpers.resources_by_types(rule_meta.resource_types) + + # Only check users who have console access (LoginProfile exists) + helpers.has_property(resource, "LoginProfile") + not is_mfa_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoginProfile", "MFABindRequired"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-ssl.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-ssl.rego new file mode 100644 index 0000000..2c34f0e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-ssl.rego @@ -0,0 +1,62 @@ +package infraguard.rules.aliyun.rds_instance_enabled_ssl + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "rds-instance-enabled-ssl", + "severity": "medium", + "name": { + "en": "RDS Instance SSL Enabled", + "zh": "RDS 实例开启 SSL 加密", + "ja": "RDS インスタンスで SSL が有効", + "de": "RDS-Instanz SSL aktiviert", + "es": "SSL de Instancia RDS Habilitado", + "fr": "SSL d'Instance RDS Activé", + "pt": "SSL de Instância RDS Habilitado" + }, + "description": { + "en": "Ensures RDS instances have SSL encryption enabled.", + "zh": "确保 RDS 实例开启了 SSL 加密。", + "ja": "RDS インスタンスで SSL 暗号化が有効になっていることを確認します。", + "de": "Stellt sicher, dass RDS-Instanzen SSL-Verschlüsselung aktiviert haben.", + "es": "Garantiza que las instancias RDS tengan cifrado SSL habilitado.", + "fr": "Garantit que les instances RDS ont le chiffrement SSL activé.", + "pt": "Garante que as instâncias RDS tenham criptografia SSL habilitada." + }, + "reason": { + "en": "SSL encryption protects data in transit from eavesdropping and tampering.", + "zh": "SSL 加密可保护传输中的数据免受窃听和篡改。", + "ja": "SSL 暗号化により、送信中のデータが盗聴や改ざんから保護されます。", + "de": "SSL-Verschlüsselung schützt Daten während der Übertragung vor Abhören und Manipulation.", + "es": "El cifrado SSL protege los datos en tránsito contra interceptación y manipulación.", + "fr": "Le chiffrement SSL protège les données en transit contre l'écoute et la falsification.", + "pt": "A criptografia SSL protege dados em trânsito contra interceptação e adulteração." + }, + "recommendation": { + "en": "Enable SSL for the RDS instance.", + "zh": "为 RDS 实例开启 SSL 加密。", + "ja": "RDS インスタンスで SSL を有効にします。", + "de": "Aktivieren Sie SSL für die RDS-Instanz.", + "es": "Habilite SSL para la instancia RDS.", + "fr": "Activez SSL pour l'instance RDS.", + "pt": "Habilite SSL para a instância RDS." + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +is_compliant(resource) if { + ssl := helpers.get_property(resource, "SSLSetting", "Disabled") + ssl != "Disabled" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SSLSetting"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-tde-disk-encryption.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-tde-disk-encryption.rego new file mode 100644 index 0000000..ec19ee0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-instance-enabled-tde-disk-encryption.rego @@ -0,0 +1,76 @@ +package infraguard.rules.aliyun.rds_instance_enabled_tde_disk_encryption + +import rego.v1 + +import data.infraguard.helpers + +# Rule metadata with i18n support +rule_meta := { + "id": "rds-instance-enabled-tde-disk-encryption", + "severity": "medium", + "name": { + "en": "RDS Instance Enabled TDE or Disk Encryption", + "zh": "RDS 实例开启 TDE 或者数据盘加密", + "ja": "RDS インスタンス TDE またはディスク暗号化が有効", + "de": "RDS-Instanz TDE oder Festplattenverschlüsselung aktiviert", + "es": "Instancia RDS TDE o Cifrado de Disco Habilitado", + "fr": "Instance RDS TDE ou Chiffrement de Disque Activé", + "pt": "Instância RDS TDE ou Criptografia de Disco Habilitada" + }, + "description": { + "en": "RDS instance should have TDE (Transparent Data Encryption) or disk encryption enabled.", + "zh": "RDS 实例开启 TDE 或者数据盘加密,视为合规。", + "ja": "RDS インスタンスで TDE(透過的データ暗号化)またはディスク暗号化を有効にする必要があります。", + "de": "RDS-Instanz sollte TDE (Transparent Data Encryption) oder Festplattenverschlüsselung aktiviert haben.", + "es": "La instancia RDS debe tener TDE (Cifrado Transparente de Datos) o cifrado de disco habilitado.", + "fr": "L'instance RDS doit avoir TDE (Chiffrement Transparent des Données) ou le chiffrement de disque activé.", + "pt": "A instância RDS deve ter TDE (Criptografia Transparente de Dados) ou criptografia de disco habilitada." + }, + "reason": { + "en": "RDS instance does not have TDE or disk encryption enabled, which may expose data to security risks.", + "zh": "RDS 实例未开启 TDE 或数据盘加密,可能导致数据面临安全风险。", + "ja": "RDS インスタンスで TDE またはディスク暗号化が有効になっていないため、データがセキュリティリスクにさらされる可能性があります。", + "de": "RDS-Instanz hat keine TDE oder Festplattenverschlüsselung aktiviert, was Daten Sicherheitsrisiken aussetzen kann.", + "es": "La instancia RDS no tiene TDE o cifrado de disco habilitado, lo que puede exponer los datos a riesgos de seguridad.", + "fr": "L'instance RDS n'a pas TDE ou le chiffrement de disque activé, ce qui peut exposer les données à des risques de sécurité.", + "pt": "A instância RDS não tem TDE ou criptografia de disco habilitada, o que pode expor os dados a riscos de segurança." + }, + "recommendation": { + "en": "Enable TDE by configuring EncryptionKey or use encrypted storage types (cloud_essd, cloud_essd2, cloud_essd3) for the RDS instance.", + "zh": "通过配置 EncryptionKey 开启 TDE,或为 RDS 实例使用加密存储类型(cloud_essd、cloud_essd2、cloud_essd3)。", + "ja": "EncryptionKey を設定して TDE を有効にするか、RDS インスタンスに暗号化ストレージタイプ(cloud_essd、cloud_essd2、cloud_essd3)を使用します。", + "de": "Aktivieren Sie TDE, indem Sie EncryptionKey konfigurieren oder verwenden Sie verschlüsselte Speichertypen (cloud_essd, cloud_essd2, cloud_essd3) für die RDS-Instanz.", + "es": "Habilite TDE configurando EncryptionKey o use tipos de almacenamiento cifrados (cloud_essd, cloud_essd2, cloud_essd3) para la instancia RDS.", + "fr": "Activez TDE en configurant EncryptionKey ou utilisez des types de stockage chiffrés (cloud_essd, cloud_essd2, cloud_essd3) pour l'instance RDS.", + "pt": "Habilite TDE configurando EncryptionKey ou use tipos de armazenamento criptografados (cloud_essd, cloud_essd2, cloud_essd3) para a instância RDS." + }, + "resource_types": ["ALIYUN::RDS::DBInstance", "ALIYUN::RDS::PrepayDBInstance"] +} + +# Encrypted storage types +encrypted_storage_types := ["cloud_essd", "cloud_essd2", "cloud_essd3"] + +# Check if encryption is enabled (TDE via EncryptionKey or encrypted storage type) +is_encryption_enabled(resource) if { + resource.Properties.EncryptionKey != null +} + +is_encryption_enabled(resource) if { + resource.Properties.DBInstanceStorageType in encrypted_storage_types +} + +# Generate deny for non-compliant RDS instance resources +deny contains result if { + some name, resource in helpers.resources_by_types(rule_meta.resource_types) + not is_encryption_enabled(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-public-connection-and-any-ip-access-check.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-public-connection-and-any-ip-access-check.rego new file mode 100644 index 0000000..d8a4d59 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/rds-public-connection-and-any-ip-access-check.rego @@ -0,0 +1,80 @@ +package infraguard.rules.aliyun.rds_public_connection_and_any_ip_access_check + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "rds-public-connection-and-any-ip-access-check", + "severity": "high", + "name": { + "en": "RDS Public Connection and Any IP Access Check", + "zh": "开启公网 IP 的 RDS 实例白名单未对所有来源开放", + "ja": "RDS のパブリック接続および任意の IP アクセスチェック", + "de": "RDS öffentliche Verbindung und beliebige IP-Zugriff-Prüfung", + "es": "Verificación de Conexión Pública y Acceso de Cualquier IP de RDS", + "fr": "Vérification de Connexion Publique et d'Accès de N'importe Quelle IP RDS", + "pt": "Verificação de Conexão Pública e Acesso de Qualquer IP RDS" + }, + "description": { + "en": "Ensures that RDS instances with public connections do not have a whitelist open to all IPs.", + "zh": "确保开启公网 IP 的 RDS 实例白名单未设置为对所有来源 IP 开放。", + "ja": "パブリック接続を持つ RDS インスタンスがすべての IP に開放されたホワイトリストを持っていないことを確認します。", + "de": "Stellt sicher, dass RDS-Instanzen mit öffentlichen Verbindungen keine Whitelist haben, die für alle IPs geöffnet ist.", + "es": "Garantiza que las instancias RDS con conexiones públicas no tengan una lista blanca abierta a todas las IPs.", + "fr": "Garantit que les instances RDS avec connexions publiques n'ont pas de liste blanche ouverte à toutes les IPs.", + "pt": "Garante que instâncias RDS com conexões públicas não tenham uma lista branca aberta para todos os IPs." + }, + "reason": { + "en": "An open whitelist combined with a public connection exposes the database to the internet, creating a high security risk.", + "zh": "公网连接配合开放白名单会将数据库暴露在互联网上,造成极高的安全风险。", + "ja": "オープンホワイトリストとパブリック接続の組み合わせにより、データベースがインターネットに公開され、高いセキュリティリスクが生じます。", + "de": "Eine offene Whitelist in Kombination mit einer öffentlichen Verbindung setzt die Datenbank dem Internet aus und schafft ein hohes Sicherheitsrisiko.", + "es": "Una lista blanca abierta combinada con una conexión pública expone la base de datos a internet, creando un alto riesgo de seguridad.", + "fr": "Une liste blanche ouverte combinée à une connexion publique expose la base de données à Internet, créant un risque de sécurité élevé.", + "pt": "Uma lista branca aberta combinada com uma conexão pública expõe o banco de dados à internet, criando um alto risco de segurança." + }, + "recommendation": { + "en": "Disable public connection or restrict the IP whitelist for the RDS instance.", + "zh": "禁用 RDS 实例的公网连接或限制 IP 白名单。", + "ja": "RDS インスタンスのパブリック接続を無効にするか、IP ホワイトリストを制限します。", + "de": "Deaktivieren Sie die öffentliche Verbindung oder beschränken Sie die IP-Whitelist für die RDS-Instanz.", + "es": "Deshabilite la conexión pública o restrinja la lista blanca de IP para la instancia RDS.", + "fr": "Désactivez la connexion publique ou restreignez la liste blanche IP pour l'instance RDS.", + "pt": "Desabilite a conexão pública ou restrinja a lista branca de IP para a instância RDS." + }, + "resource_types": ["ALIYUN::RDS::DBInstance"] +} + +is_compliant(resource) if { + # If public connection is not enabled, it's compliant + not helpers.is_true(helpers.get_property(resource, "AllocatePublicConnection", false)) +} + +is_compliant(resource) if { + # If public connection is enabled, check the whitelist + helpers.is_true(helpers.get_property(resource, "AllocatePublicConnection", false)) + whitelist_str := helpers.get_property(resource, "SecurityIPList", "") + whitelist := split(whitelist_str, ",") + not has_open_cidr(whitelist) +} + +has_open_cidr(whitelist) if { + some cidr in whitelist + helpers.is_public_cidr(trim_space(cidr)) +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SecurityIPList"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-enabled-ssl.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-enabled-ssl.rego new file mode 100644 index 0000000..63d7c85 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-enabled-ssl.rego @@ -0,0 +1,62 @@ +package infraguard.rules.aliyun.redis_instance_enabled_ssl + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "redis-instance-enabled-ssl", + "severity": "medium", + "name": { + "en": "Redis Instance SSL Enabled", + "zh": "Redis 实例开启 SSL 加密", + "ja": "Redis インスタンスで SSL が有効", + "de": "Redis-Instanz SSL aktiviert", + "es": "SSL de Instancia Redis Habilitado", + "fr": "SSL d'Instance Redis Activé", + "pt": "SSL de Instância Redis Habilitado" + }, + "description": { + "en": "Ensures Redis instances have SSL encryption enabled.", + "zh": "确保 Redis 实例开启了 SSL 加密。", + "ja": "Redis インスタンスで SSL 暗号化が有効になっていることを確認します。", + "de": "Stellt sicher, dass Redis-Instanzen SSL-Verschlüsselung aktiviert haben.", + "es": "Garantiza que las instancias Redis tengan cifrado SSL habilitado.", + "fr": "Garantit que les instances Redis ont le chiffrement SSL activé.", + "pt": "Garante que as instâncias Redis tenham criptografia SSL habilitada." + }, + "reason": { + "en": "SSL encryption protects Redis data in transit from being intercepted.", + "zh": "SSL 加密保护传输中的 Redis 数据不被截获。", + "ja": "SSL 暗号化により、送信中の Redis データが傍受から保護されます。", + "de": "SSL-Verschlüsselung schützt Redis-Daten während der Übertragung vor Abfangen.", + "es": "El cifrado SSL protege los datos Redis en tránsito contra interceptación.", + "fr": "Le chiffrement SSL protège les données Redis en transit contre l'interception.", + "pt": "A criptografia SSL protege dados Redis em trânsito contra interceptação." + }, + "recommendation": { + "en": "Enable SSL for the Redis instance.", + "zh": "为 Redis 实例开启 SSL 加密。", + "ja": "Redis インスタンスで SSL を有効にします。", + "de": "Aktivieren Sie SSL für die Redis-Instanz.", + "es": "Habilite SSL para la instancia Redis.", + "fr": "Activez SSL pour l'instance Redis.", + "pt": "Habilite SSL para a instância Redis." + }, + "resource_types": ["ALIYUN::REDIS::Instance"] +} + +is_compliant(resource) if { + ssl := helpers.get_property(resource, "SSLEnabled", "Disable") + ssl == "Enable" +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::REDIS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SSLEnabled"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-no-public-ip.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-no-public-ip.rego new file mode 100644 index 0000000..bffbfbc --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/redis-instance-no-public-ip.rego @@ -0,0 +1,63 @@ +package infraguard.rules.aliyun.redis_instance_no_public_ip + +import rego.v1 + +import data.infraguard.helpers + +rule_meta := { + "id": "redis-instance-no-public-ip", + "severity": "high", + "name": { + "en": "Redis Instance No Public IP", + "zh": "Redis 实例未设置公网 IP", + "ja": "Redis インスタンスにパブリック IP なし", + "de": "Redis-Instanz ohne öffentliche IP", + "es": "Instancia Redis Sin IP Pública", + "fr": "Instance Redis Sans IP Publique", + "pt": "Instância Redis Sem IP Público" + }, + "description": { + "en": "Ensures Redis instance does not have public IP assigned.", + "zh": "确保 Redis 实例未设置公网 IP。", + "ja": "Redis インスタンスにパブリック IP が割り当てられていないことを確認します。", + "de": "Stellt sicher, dass der Redis-Instanz keine öffentliche IP zugewiesen ist.", + "es": "Garantiza que la instancia Redis no tenga una IP pública asignada.", + "fr": "Garantit que l'instance Redis n'a pas d'IP publique assignée.", + "pt": "Garante que a instância Redis não tenha IP público atribuído." + }, + "reason": { + "en": "Public IP exposes Redis instance to internet attacks.", + "zh": "公网 IP 使 Redis 实例暴露于互联网攻击。", + "ja": "パブリック IP により、Redis インスタンスがインターネット攻撃にさらされます。", + "de": "Öffentliche IP setzt die Redis-Instanz Internetangriffen aus.", + "es": "La IP pública expone la instancia Redis a ataques de internet.", + "fr": "L'IP publique expose l'instance Redis aux attaques Internet.", + "pt": "O IP público expõe a instância Redis a ataques da internet." + }, + "recommendation": { + "en": "Remove public IP from the Redis instance.", + "zh": "移除 Redis 实例的公网 IP。", + "ja": "Redis インスタンスからパブリック IP を削除します。", + "de": "Entfernen Sie die öffentliche IP von der Redis-Instanz.", + "es": "Elimine la IP pública de la instancia Redis.", + "fr": "Supprimez l'IP publique de l'instance Redis.", + "pt": "Remova o IP público da instância Redis." + }, + "resource_types": ["ALIYUN::REDIS::Instance"] +} + +is_compliant(resource) if { + connections := helpers.get_property(resource, "Connections", {}) + object.get(connections, "PublicConnection", null) == null +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::REDIS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Connections", "PublicConnection"], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/vpc-flow-logs-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/vpc-flow-logs-enabled.rego new file mode 100644 index 0000000..ef08b07 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/rules/ros/vpc-flow-logs-enabled.rego @@ -0,0 +1,63 @@ +package infraguard.rules.aliyun.vpc_flow_logs_enabled + +import data.infraguard.helpers +import rego.v1 + +rule_meta := { + "id": "vpc-flow-logs-enabled", + "severity": "medium", + "name": { + "en": "VPC Flow Logs Enabled", + "zh": "VPC 开启流日志", + "ja": "VPC フローログが有効", + "de": "VPC-Flussprotokolle aktiviert", + "es": "Registros de Flujo VPC Habilitados", + "fr": "Journaux de Flux VPC Activés", + "pt": "Logs de Fluxo VPC Habilitados" + }, + "description": { + "en": "Ensures VPC flow logs are enabled for monitoring network traffic.", + "zh": "确保 VPC 开启了流日志,以便监控网络流量。", + "ja": "ネットワークトラフィックを監視するために VPC フローログが有効になっていることを確認します。", + "de": "Stellt sicher, dass VPC-Flussprotokolle für die Überwachung des Netzwerkverkehrs aktiviert sind.", + "es": "Garantiza que los registros de flujo VPC estén habilitados para monitorear el tráfico de red.", + "fr": "Garantit que les journaux de flux VPC sont activés pour surveiller le trafic réseau.", + "pt": "Garante que os logs de fluxo VPC estejam habilitados para monitorar tráfego de rede." + }, + "reason": { + "en": "Flow logs provide visibility into network traffic patterns and help in security auditing.", + "zh": "流日志提供了网络流量模式的可见性,有助于安全审计。", + "ja": "フローログはネットワークトラフィックパターンの可視性を提供し、セキュリティ監査に役立ちます。", + "de": "Flussprotokolle bieten Einblicke in Netzwerkverkehrsmuster und helfen bei Sicherheitsaudits.", + "es": "Los registros de flujo proporcionan visibilidad sobre los patrones de tráfico de red y ayudan en la auditoría de seguridad.", + "fr": "Les journaux de flux fournissent une visibilité sur les modèles de trafic réseau et aident à l'audit de sécurité.", + "pt": "Logs de fluxo fornecem visibilidade sobre padrões de tráfego de rede e ajudam na auditoria de segurança." + }, + "recommendation": { + "en": "Add ALIYUN::VPC::FlowLog resource to enable flow logs for the VPC.", + "zh": "添加 ALIYUN::VPC::FlowLog 资源以为 VPC 开启流日志。", + "ja": "ALIYUN::VPC::FlowLog リソースを追加して、VPC のフローログを有効にします。", + "de": "Fügen Sie die ALIYUN::VPC::FlowLog-Ressource hinzu, um Flussprotokolle für das VPC zu aktivieren.", + "es": "Agregue el recurso ALIYUN::VPC::FlowLog para habilitar los registros de flujo para el VPC.", + "fr": "Ajoutez la ressource ALIYUN::VPC::FlowLog pour activer les journaux de flux pour le VPC.", + "pt": "Adicione o recurso ALIYUN::VPC::FlowLog para habilitar logs de fluxo para o VPC." + }, + "resource_types": ["ALIYUN::ECS::VPC"] +} + +# Cross-resource check: is there a FlowLog resource for this VPC? +has_flow_log(vpc_id) if { + some name, res in helpers.resources_by_type("ALIYUN::VPC::FlowLog") + helpers.is_referencing(helpers.get_property(res, "ResourceId", ""), vpc_id) +} + +deny contains result if { + some vpc_id, resource in helpers.resources_by_type("ALIYUN::ECS::VPC") + not has_flow_log(vpc_id) + result := { + "id": rule_meta.id, + "resource_id": vpc_id, + "violation_path": [], + "meta": {"severity": rule_meta.severity, "reason": rule_meta.reason, "recommendation": rule_meta.recommendation}, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-api-gateway-api-auth-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-api-gateway-api-auth-required.rego new file mode 100644 index 0000000..7f11acb --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-api-gateway-api-auth-required.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_api_gateway_api_auth_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-api-gateway-api-auth-required", + "severity": "high", + "name": { + "en": "API Gateway API must configure authentication", + "zh": "API 网关 API 必须配置认证", + }, + "description": { + "en": "Checks API Gateway API must configure authentication", + "zh": "检查API 网关 API 必须配置认证", + }, + "reason": { + "en": "API Gateway API must configure authentication is not satisfied.", + "zh": "API 网关 API 必须配置认证未满足。", + }, + "recommendation": { + "en": "Configure AuthType on ALIYUN::ApiGateway::Api to satisfy the policy.", + "zh": "请在 ALIYUN::ApiGateway::Api 上配置 AuthType 以满足策略。", + }, + "resource_types": ["ALIYUN::ApiGateway::Api"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ApiGateway::Api") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AuthType"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "AuthType") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-disk-encrypted.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-disk-encrypted.rego new file mode 100644 index 0000000..03d9726 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-disk-encrypted.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_ecs_disk_encrypted + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-ecs-disk-encrypted", + "severity": "high", + "name": { + "en": "ECS disk must enable encryption", + "zh": "ECS 云盘必须启用加密", + }, + "description": { + "en": "Checks ECS disk must enable encryption", + "zh": "检查ECS 云盘必须启用加密", + }, + "reason": { + "en": "ECS disk must enable encryption is not satisfied.", + "zh": "ECS 云盘必须启用加密未满足。", + }, + "recommendation": { + "en": "Configure Encrypted on ALIYUN::ECS::Disk to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Disk 上配置 Encrypted 以满足策略。", + }, + "resource_types": ["ALIYUN::ECS::Disk"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Disk") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "Encrypted"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "Encrypted", false) == true +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-no-public-ip.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-no-public-ip.rego new file mode 100644 index 0000000..23cb0bc --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-no-public-ip.rego @@ -0,0 +1,100 @@ +package infraguard.rules.aliyun.security_ecs_instance_no_public_ip + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-ecs-instance-no-public-ip", + "severity": "high", + "name": { + "en": "ECS instance must not allocate public IP", + "zh": "ECS 实例禁止分配公网 IP", + }, + "description": { + "en": "Checks ECS public exposure through direct public IP, outbound bandwidth, or EIP association.", + "zh": "检查 ECS 是否通过公网 IP、出网带宽或 EIP 绑定暴露公网。", + }, + "reason": { + "en": "ECS instance is exposed to the public network.", + "zh": "ECS 实例存在公网暴露路径。", + }, + "recommendation": { + "en": "Disable public IP allocation, set internet outbound bandwidth to 0, and avoid direct EIP association.", + "zh": "关闭公网 IP 分配,将公网出带宽设为 0,并避免直接绑定 EIP。", + }, + "resource_types": ["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"], +} + +allocates_public_ip(resource) if { + helpers.get_property(resource, "AllocatePublicIP", false) == true +} + +has_internet_bandwidth(resource) if { + helpers.has_property(resource, "InternetMaxBandwidthOut") + resource.Properties.InternetMaxBandwidthOut > 0 +} + +deny contains result if { + some name, resource in helpers.resources_by_types(["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"]) + allocates_public_ip(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AllocatePublicIP"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +deny contains result if { + some name, resource in helpers.resources_by_types(["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"]) + has_internet_bandwidth(resource) + not allocates_public_ip(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "InternetMaxBandwidthOut"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +deny contains result if { + some name, resource in helpers.resources_by_types(["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"]) + some _, eip_resource in helpers.resources_by_type("ALIYUN::VPC::EIPAssociation") + instance_id := helpers.get_property(eip_resource, "InstanceId", "") + helpers.is_referencing(instance_id, name) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +deny contains result if { + some name, resource in helpers.resources_by_types(["ALIYUN::ECS::Instance", "ALIYUN::ECS::InstanceGroup"]) + some _, eip_resource in helpers.resources_by_type("ALIYUN::VPC::EIPAssociation") + instance_id := helpers.get_property(eip_resource, "InstanceId", "") + helpers.is_get_att_referencing(instance_id, name) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-security-group-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-security-group-required.rego new file mode 100644 index 0000000..16fae2e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-security-group-required.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_ecs_instance_security_group_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-ecs-instance-security-group-required", + "severity": "high", + "name": { + "en": "ECS instance must attach a security group", + "zh": "ECS 实例必须绑定安全组", + }, + "description": { + "en": "Checks ECS instance must attach a security group", + "zh": "检查ECS 实例必须绑定安全组", + }, + "reason": { + "en": "ECS instance must attach a security group is not satisfied.", + "zh": "ECS 实例必须绑定安全组未满足。", + }, + "recommendation": { + "en": "Configure SecurityGroupId on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 SecurityGroupId 以满足策略。", + }, + "resource_types": ["ALIYUN::ECS::Instance"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SecurityGroupId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "SecurityGroupId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-vpc-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-vpc-required.rego new file mode 100644 index 0000000..fb882d0 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ecs-instance-vpc-required.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_ecs_instance_vpc_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-ecs-instance-vpc-required", + "severity": "high", + "name": { + "en": "ECS instance must run in VPC", + "zh": "ECS 实例必须部署在 VPC 内", + }, + "description": { + "en": "Checks ECS instance must run in VPC", + "zh": "检查ECS 实例必须部署在 VPC 内", + }, + "reason": { + "en": "ECS instance must run in VPC is not satisfied.", + "zh": "ECS 实例必须部署在 VPC 内未满足。", + }, + "recommendation": { + "en": "Configure VpcId on ALIYUN::ECS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::ECS::Instance 上配置 VpcId 以满足策略。", + }, + "resource_types": ["ALIYUN::ECS::Instance"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::ECS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VpcId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VpcId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-encryption-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-encryption-configured.rego new file mode 100644 index 0000000..8da19f1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-encryption-configured.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_oss_bucket_encryption_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-oss-bucket-encryption-configured", + "severity": "high", + "name": { + "en": "OSS bucket must configure server-side encryption", + "zh": "OSS Bucket 必须配置服务端加密", + }, + "description": { + "en": "Checks OSS bucket must configure server-side encryption", + "zh": "检查OSS Bucket 必须配置服务端加密", + }, + "reason": { + "en": "OSS bucket must configure server-side encryption is not satisfied.", + "zh": "OSS Bucket 必须配置服务端加密未满足。", + }, + "recommendation": { + "en": "Configure ServerSideEncryptionConfiguration on ALIYUN::OSS::Bucket to satisfy the policy.", + "zh": "请在 ALIYUN::OSS::Bucket 上配置 ServerSideEncryptionConfiguration 以满足策略。", + }, + "resource_types": ["ALIYUN::OSS::Bucket"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "ServerSideEncryptionConfiguration"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "ServerSideEncryptionConfiguration") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-logging-configured.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-logging-configured.rego new file mode 100644 index 0000000..afead0f --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-logging-configured.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_oss_bucket_logging_configured + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-oss-bucket-logging-configured", + "severity": "medium", + "name": { + "en": "OSS bucket must configure access logging", + "zh": "OSS Bucket 必须配置访问日志", + }, + "description": { + "en": "Checks OSS bucket must configure access logging", + "zh": "检查OSS Bucket 必须配置访问日志", + }, + "reason": { + "en": "OSS bucket must configure access logging is not satisfied.", + "zh": "OSS Bucket 必须配置访问日志未满足。", + }, + "recommendation": { + "en": "Configure LoggingConfiguration on ALIYUN::OSS::Bucket to satisfy the policy.", + "zh": "请在 ALIYUN::OSS::Bucket 上配置 LoggingConfiguration 以满足策略。", + }, + "resource_types": ["ALIYUN::OSS::Bucket"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "LoggingConfiguration"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "LoggingConfiguration") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-private-acl.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-private-acl.rego new file mode 100644 index 0000000..8aab488 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-oss-bucket-private-acl.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_oss_bucket_private_acl + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-oss-bucket-private-acl", + "severity": "high", + "name": { + "en": "OSS bucket ACL must be private", + "zh": "OSS Bucket ACL 必须为私有", + }, + "description": { + "en": "Checks OSS bucket ACL must be private", + "zh": "检查OSS Bucket ACL 必须为私有", + }, + "reason": { + "en": "OSS bucket ACL must be private is not satisfied.", + "zh": "OSS Bucket ACL 必须为私有未满足。", + }, + "recommendation": { + "en": "Configure AccessControl on ALIYUN::OSS::Bucket to satisfy the policy.", + "zh": "请在 ALIYUN::OSS::Bucket 上配置 AccessControl 以满足策略。", + }, + "resource_types": ["ALIYUN::OSS::Bucket"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::OSS::Bucket") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "AccessControl"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "AccessControl", "") == "private" +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ram-user-mfa-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ram-user-mfa-required.rego new file mode 100644 index 0000000..276c569 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-ram-user-mfa-required.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_ram_user_mfa_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-ram-user-mfa-required", + "severity": "high", + "name": { + "en": "RAM user must require MFA", + "zh": "RAM 用户必须要求 MFA", + }, + "description": { + "en": "Checks RAM user must require MFA", + "zh": "检查RAM 用户必须要求 MFA", + }, + "reason": { + "en": "RAM user must require MFA is not satisfied.", + "zh": "RAM 用户必须要求 MFA未满足。", + }, + "recommendation": { + "en": "Configure MFABindRequired on ALIYUN::RAM::User to satisfy the policy.", + "zh": "请在 ALIYUN::RAM::User 上配置 MFABindRequired 以满足策略。", + }, + "resource_types": ["ALIYUN::RAM::User"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RAM::User") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "MFABindRequired"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "MFABindRequired", false) == true +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-ssl-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-ssl-required.rego new file mode 100644 index 0000000..4547f2e --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-ssl-required.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_rds_instance_ssl_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-rds-instance-ssl-required", + "severity": "high", + "name": { + "en": "RDS instance must configure SSL", + "zh": "RDS 实例必须配置 SSL", + }, + "description": { + "en": "Checks RDS instance must configure SSL", + "zh": "检查RDS 实例必须配置 SSL", + }, + "reason": { + "en": "RDS instance must configure SSL is not satisfied.", + "zh": "RDS 实例必须配置 SSL未满足。", + }, + "recommendation": { + "en": "Configure SSLSetting on ALIYUN::RDS::DBInstance to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::DBInstance 上配置 SSLSetting 以满足策略。", + }, + "resource_types": ["ALIYUN::RDS::DBInstance"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "SSLSetting"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "SSLSetting") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-tde-enabled.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-tde-enabled.rego new file mode 100644 index 0000000..7ac9b37 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-tde-enabled.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_rds_instance_tde_enabled + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-rds-instance-tde-enabled", + "severity": "high", + "name": { + "en": "RDS instance must enable TDE", + "zh": "RDS 实例必须启用 TDE", + }, + "description": { + "en": "Checks RDS instance must enable TDE", + "zh": "检查RDS 实例必须启用 TDE", + }, + "reason": { + "en": "RDS instance must enable TDE is not satisfied.", + "zh": "RDS 实例必须启用 TDE未满足。", + }, + "recommendation": { + "en": "Configure TDEStatus on ALIYUN::RDS::DBInstance to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::DBInstance 上配置 TDEStatus 以满足策略。", + }, + "resource_types": ["ALIYUN::RDS::DBInstance"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "TDEStatus"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "TDEStatus", "") == "Enabled" +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-vpc-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-vpc-required.rego new file mode 100644 index 0000000..d7afc22 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-rds-instance-vpc-required.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_rds_instance_vpc_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-rds-instance-vpc-required", + "severity": "high", + "name": { + "en": "RDS instance must run in VPC", + "zh": "RDS 实例必须部署在 VPC 内", + }, + "description": { + "en": "Checks RDS instance must run in VPC", + "zh": "检查RDS 实例必须部署在 VPC 内", + }, + "reason": { + "en": "RDS instance must run in VPC is not satisfied.", + "zh": "RDS 实例必须部署在 VPC 内未满足。", + }, + "recommendation": { + "en": "Configure VpcId on ALIYUN::RDS::DBInstance to satisfy the policy.", + "zh": "请在 ALIYUN::RDS::DBInstance 上配置 VpcId 以满足策略。", + }, + "resource_types": ["ALIYUN::RDS::DBInstance"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::RDS::DBInstance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VpcId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VpcId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-redis-instance-vpc-required.rego b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-redis-instance-vpc-required.rego new file mode 100644 index 0000000..8d0211d --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policies/security/security-redis-instance-vpc-required.rego @@ -0,0 +1,45 @@ +package infraguard.rules.aliyun.security_redis_instance_vpc_required + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "security-redis-instance-vpc-required", + "severity": "high", + "name": { + "en": "Redis instance must run in VPC", + "zh": "Redis 实例必须部署在 VPC 内", + }, + "description": { + "en": "Checks Redis instance must run in VPC", + "zh": "检查Redis 实例必须部署在 VPC 内", + }, + "reason": { + "en": "Redis instance must run in VPC is not satisfied.", + "zh": "Redis 实例必须部署在 VPC 内未满足。", + }, + "recommendation": { + "en": "Configure VpcId on ALIYUN::REDIS::Instance to satisfy the policy.", + "zh": "请在 ALIYUN::REDIS::Instance 上配置 VpcId 以满足策略。", + }, + "resource_types": ["ALIYUN::REDIS::Instance"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::REDIS::Instance") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", "VpcId"], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.has_property(resource, "VpcId") +} diff --git a/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policy-generation.md b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policy-generation.md new file mode 100644 index 0000000..bf11ad1 --- /dev/null +++ b/src/iac_code/skills/bundled/iac_aliyun/references/infraguard-policy-generation.md @@ -0,0 +1,190 @@ +# InfraGuard 合规策略生成 + +本文件定义 IaC Code 的 InfraGuard 策略生成能力。`SKILL.md` 只保留入口说明,详细策略生成规则、策略资产目录和 Rego 写法以本文为准。 + +## 能力目标 + +- 当用户要求“生成合规策略”“写 InfraGuard 规则”“用 Rego 检查模板”“策略校验”等时,生成 InfraGuard 可运行的 Rego 策略。 +- 支持按多维度生成或组合策略,包括:安全性、高可用、成本优化、合规性、最佳实践、可运维性、网络架构、弹性能力。 +- IaC Code 需要生成 100+ 个 InfraGuard 策略,覆盖 8 个场景,作为面向不同用户需求的通用合规策略资产。 +- 已生成的策略资产位于 [references/infraguard-policies/](infraguard-policies/),按场景目录组织。 +- 每个场景都提供一个 InfraGuard pack,位于 [references/infraguard-policies/packs/](infraguard-policies/packs/),用于按场景快速组合 13 条规则。 + +## 策略资产选择 + +- 需要快速落地:从已生成策略资产中选择匹配策略。 +- 需要按场景执行:优先选择对应的 `iac-code-` pack。 +- 需要组织专属约束:在通用策略基础上生成或改写自定义 Rego 规则。 +- 需要覆盖多个治理目标:组合多个场景下的策略,并补充缺失规则。 + +## 策略维度 + +- **安全性**:公网暴露、弱访问控制、未启用加密、未启用审计、敏感参数未隐藏、RAM 权限过宽。 +- **高可用**:多可用区、多个后端、多节点、主备或集群架构、关键服务避免单点。 +- **成本优化**:实例规格边界、闲置资源、带宽上限、预付费到期、快照/日志保留周期。 +- **合规性**:MLPS、ISO 27001、PCI-DSS、SOC 2、NIST 800-53 等合规包或组织控制项。 +- **最佳实践**:阿里云 Well-Architected、安全组、备份、资源保护、平台安全等最佳实践。 +- **可运维性**:日志、监控、审计、追踪、备份、删除保护、自动快照、告警所需配置。 +- **网络架构**:VPC 内网化、公网入口收敛、ACL、安全组、负载均衡、多地域/多可用区连接。 +- **弹性能力**:ESS 弹性伸缩、多交换机、自动扩缩容、负载均衡绑定、容量与规格约束。 + +## 生成流程 + +1. 识别目标 IaC 类型: + - **ROS**:检查 ROS YAML/JSON 模板,资源类型形如 `ALIYUN::ECS::Instance`。 + - **Terraform**:检查 Terraform alicloud provider 配置,资源类型形如 `alicloud_instance`。 + - InfraGuard 官方当前主要支持 Alibaba Cloud ROS 模板。用户未指定时,默认生成 ROS 规则。 + - 若请求同时覆盖 ROS 和 Terraform,分别生成两个 `.rego` 文件,不要混写在同一个 package 中。 +2. 根据自然语言提炼:策略维度、规则 ID、严重级别、适用资源类型、违规条件、修复建议、违规路径。 +3. 优先复用官方 InfraGuard 规则风格: + - `package` 使用 `infraguard.rules.aliyun.`。 + - `rule_meta.id` 使用不带场景前缀的 kebab-case,例如 `ecs-running-instance-no-public-ip`。 + - `rule_meta` 使用官方字段:`id`、`severity`、`name`、`description`、`reason`、`recommendation`、`resource_types`。 + - `name`、`description`、`reason`、`recommendation` 尽量提供 `en`、`zh`、`ja`、`de`、`es`、`fr`、`pt` 七种语言,至少不要低于官方同类规则的语言覆盖。 + - 不添加 InfraGuard 官方没有使用的自定义 metadata 字段,例如 `dimension`。 +4. 将策略写入 `.rego` 文件,文件名使用 kebab-case,例如 `ecs-running-instance-no-public-ip.rego`。 +5. 如本地存在 `infraguard` 命令,生成后运行 `infraguard policy validate <策略文件>` 校验;失败时修复并重试。 +6. 若 `infraguard` 命令不存在,告知用户可用该命令验证,不要阻塞生成。 + +## ROS Rego 结构 + +```rego +package infraguard.rules.aliyun. + +import rego.v1 +import data.infraguard.helpers + +rule_meta := { + "id": "", + "severity": "high", + "name": { + "en": "", + "zh": "<中文名称>", + "ja": "", + "de": "", + "es": "", + "fr": "", + "pt": "" + }, + "description": { + "en": "", + "zh": "<检查内容>", + "ja": "", + "de": "", + "es": "", + "fr": "", + "pt": "" + }, + "reason": { + "en": "", + "zh": "<违规原因>", + "ja": "", + "de": "", + "es": "", + "fr": "", + "pt": "" + }, + "recommendation": { + "en": "", + "zh": "<修复建议>", + "ja": "", + "de": "", + "es": "", + "fr": "", + "pt": "" + }, + "resource_types": ["ALIYUN::::"], +} + +deny contains result if { + some name, resource in helpers.resources_by_type("ALIYUN::::") + not is_compliant(resource) + result := { + "id": rule_meta.id, + "resource_id": name, + "violation_path": ["Properties", ""], + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(resource) if { + helpers.get_property(resource, "", "") == "" +} +``` + +## Terraform Rego 结构 + +```rego +package infraguard.rules.terraform. + +import rego.v1 +import data.infraguard.helpers.terraform as tf + +rule_meta := { + "id": "", + "severity": "high", + "name": {"en": "", "zh": "<中文名称>"}, + "description": {"en": "", "zh": "<检查内容>"}, + "reason": {"en": "", "zh": "<违规原因>"}, + "recommendation": {"en": "", "zh": "<修复建议>"}, + "resource_types": ["alicloud_"], + "iac_type": "terraform", +} + +deny contains result if { + some name, resource in tf.resources_by_type("alicloud_") + value := tf.get_attribute(resource, "", "") + not tf.is_unknown(value) + not is_compliant(value) + result := { + "id": rule_meta.id, + "resource_id": sprintf("alicloud_.%s", [name]), + "meta": { + "severity": rule_meta.severity, + "reason": rule_meta.reason, + "recommendation": rule_meta.recommendation, + }, + } +} + +is_compliant(value) if { + value == "" +} +``` + +## 规则要求 + +- `package` 使用下划线,不使用连字符;`rule_meta.id` 和文件名使用 kebab-case。 +- `rule_meta` 至少包含 `id`、`severity`、`name`、`description`、`reason`、`recommendation`、`resource_types`;Terraform 规则额外包含 `"iac_type": "terraform"`。 +- `severity` 只使用 `high`、`medium`、`low`。 +- `deny contains result if` 的 `result` 必须包含 `id`、`resource_id`、`meta`;ROS 规则尽量包含 `violation_path`。 +- ROS 规则优先使用 `helpers.resources_by_type`、`helpers.resources_by_types`、`helpers.has_property`、`helpers.get_property`、`helpers.is_true`、`helpers.is_false`、`helpers.is_public_cidr`、`helpers.is_referencing`、`helpers.is_get_att_referencing`。 +- Terraform 规则优先使用 `tf.resources_by_type`、`tf.get_attribute`、`tf.is_unknown`;遇到静态无法确定的属性时跳过,不要把 `""` 当作违规。 +- 对涉及 `Ref`、`Fn::GetAtt`、列表、标签、安全组规则、白名单、CIDR、端口范围的检查,使用 helper 或显式处理多种写法,不要只覆盖一个字面量路径。 +- 不要编造 InfraGuard 不支持的命令;策略验证使用 `infraguard policy validate `,扫描模板使用 `infraguard scan