chore(aws): enhance metadata for workspaces service (#9483)

Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
This commit is contained in:
Rubén De la Torre Vico
2025-12-26 13:31:55 +01:00
committed by GitHub
parent 9f4b5e01cf
commit e3027190de
3 changed files with 43 additions and 26 deletions

View File

@@ -29,6 +29,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- Update AWS Security Hub service metadata to new format [(#9409)](https://github.com/prowler-cloud/prowler/pull/9409)
- Update AWS SES service metadata to new format [(#9411)](https://github.com/prowler-cloud/prowler/pull/9411)
- Update AWS SSM Incidents service metadata to new format [(#9431)](https://github.com/prowler-cloud/prowler/pull/9431)
- Update AWS WorkSpaces service metadata to new format [(#9483)](https://github.com/prowler-cloud/prowler/pull/9483)
---

View File

@@ -1,27 +1,35 @@
{
"Provider": "aws",
"CheckID": "workspaces_volume_encryption_enabled",
"CheckTitle": "Ensure that your Amazon WorkSpaces storage volumes are encrypted in order to meet security and compliance requirements",
"CheckType": [],
"CheckTitle": "Amazon WorkSpaces workspace root and user volumes are encrypted",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices",
"Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices",
"Effects/Data Exposure"
],
"ServiceName": "workspaces",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:workspaces:region:account-id:workspace",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "AwsWorkSpacesWorkspace",
"ResourceType": "AwsEc2Volume",
"ResourceGroup": "compute",
"Description": "Ensure that your Amazon WorkSpaces storage volumes are encrypted in order to meet security and compliance requirements",
"Risk": "If the value listed in the Volume Encryption column is Disabled the selected AWS WorkSpaces instance volumes (root and user volumes) are not encrypted. Therefore your data-at-rest is not protected from unauthorized access and does not meet the compliance requirements regarding data encryption.",
"RelatedUrl": "https://docs.aws.amazon.com/workspaces/latest/adminguide/encrypt-workspaces.html",
"Description": "**Amazon WorkSpaces** evaluates **encryption at rest** on each workspace's EBS volumes. It checks whether the **root** and **user** volumes are encrypted with a KMS key and identifies workspaces where either volume is unencrypted.",
"Risk": "Unencrypted volumes allow offline access to files, cached credentials, and profile data from snapshots or underlying storage, harming **confidentiality**. Storage-level access can enable data tampering, impacting **integrity**, and facilitate token reuse for lateral movement.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://docs.aws.amazon.com/workspaces/latest/adminguide/encrypt-workspaces.html",
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/WorkSpaces/storage-encryption.html"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-workspace-root-volumes-are-encrypted#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/WorkSpaces/storage-encryption.html",
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-workspace-root-volumes-are-encrypted#terraform"
"NativeIaC": "```yaml\n# CloudFormation: create a WorkSpace with both volumes encrypted\nResources:\n ExampleWorkspace:\n Type: AWS::WorkSpaces::Workspace\n Properties:\n BundleId: <example_bundle_id>\n DirectoryId: <example_directory_id>\n UserName: <example_user_name>\n RootVolumeEncryptionEnabled: true # Critical: encrypts the root volume to pass the check\n UserVolumeEncryptionEnabled: true # Critical: encrypts the user volume to pass the check\n```",
"Other": "1. In the AWS Console, go to WorkSpaces > WorkSpaces and click Launch WorkSpaces\n2. Select the directory and user, proceed to the WorkSpaces Configuration step\n3. Under Encryption, enable Root volume and User volume\n4. Keep the default AWS managed key (aws/workspaces) or select a CMK if required\n5. Launch the WorkSpace, then migrate the user and terminate the unencrypted WorkSpace\n6. Verify the Volume Encryption column shows Enabled for both volumes",
"Terraform": "```hcl\n# Terraform: create a WorkSpace with both volumes encrypted\nresource \"aws_workspaces_workspace\" \"example\" {\n bundle_id = \"<example_bundle_id>\"\n directory_id = \"<example_directory_id>\"\n user_name = \"<example_user_name>\"\n\n root_volume_encryption_enabled = true # Critical: encrypts the root volume\n user_volume_encryption_enabled = true # Critical: encrypts the user volume\n}\n```"
},
"Recommendation": {
"Text": "WorkSpaces is integrated with the AWS Key Management Service (AWS KMS). This enables you to encrypt storage volumes of WorkSpaces using AWS KMS Key. When you launch a WorkSpace you can encrypt the root volume (for Microsoft Windows - the C drive, for Linux - /) and the user volume (for Windows - the D drive, for Linux - /home). Doing so ensures that the data stored at rest - disk I/O to the volume - and snapshots created from the volumes are all encrypted",
"Url": "https://docs.aws.amazon.com/workspaces/latest/adminguide/encrypt-workspaces.html"
"Text": "Enable KMS-backed encryption for both **root** and **user** volumes on all WorkSpaces. Prefer **customer-managed keys**, enforce **least privilege** on key use, and enable rotation. Embed encryption into provisioning templates and policies to block unencrypted launches. *Keep required keys enabled for rebuilds and restores*.",
"Url": "https://hub.prowler.com/check/workspaces_volume_encryption_enabled"
}
},
"Categories": [

View File

@@ -1,30 +1,38 @@
{
"Provider": "aws",
"CheckID": "workspaces_vpc_2private_1public_subnets_nat",
"CheckTitle": "Ensure that the Workspaces VPC are deployed following the best practices using 1 public subnet and 2 private subnets with a NAT Gateway attached",
"CheckType": [],
"CheckTitle": "Workspace is in a private subnet and its VPC has at least 1 public subnet, 2 private subnets, and a NAT Gateway",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices/Network Reachability"
],
"ServiceName": "workspaces",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:workspaces:region:account-id:workspace",
"Severity": "medium",
"ResourceType": "AwsWorkSpacesWorkspace",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "Other",
"ResourceGroup": "compute",
"Description": "Ensure that the Workspaces VPC are deployed following the best practices using 1 public subnet and 2 private subnets with a NAT Gateway attached",
"Risk": "Proper network segmentation is a key security best practice. Workspaces VPC should be deployed using 1 public subnet and 2 private subnets with a NAT Gateway attached",
"RelatedUrl": "https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces-vpc.html",
"Description": "Amazon WorkSpaces reside in a VPC that includes **2 private subnets** and **1 public subnet**, with the WorkSpace launched in a **private subnet** and the VPC providing **NAT Gateway** egress.",
"Risk": "Placing WorkSpaces in public subnets or lacking a NAT Gateway exposes desktops to direct Internet reachability, enabling credential attacks and session hijacking, harming **confidentiality** and **integrity**. Without controlled egress, updates and directory connectivity can fail, impacting **availability** and pushing teams to unsafe workarounds.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces-vpc.html"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
"NativeIaC": "```yaml\n# Minimal VPC setup: 1 public subnet, 2 private subnets, and a NAT Gateway\nResources:\n VPC:\n Type: AWS::EC2::VPC\n Properties:\n CidrBlock: 10.0.0.0/16\n\n IGW:\n Type: AWS::EC2::InternetGateway\n\n AttachIGW:\n Type: AWS::EC2::VPCGatewayAttachment\n Properties:\n VpcId: !Ref VPC\n InternetGatewayId: !Ref IGW\n\n PublicSubnet:\n Type: AWS::EC2::Subnet\n Properties:\n VpcId: !Ref VPC\n CidrBlock: 10.0.0.0/24\n\n PrivateSubnetA:\n Type: AWS::EC2::Subnet\n Properties:\n VpcId: !Ref VPC\n CidrBlock: 10.0.1.0/24 # PRIVATE SUBNET 1 (required)\n\n PrivateSubnetB:\n Type: AWS::EC2::Subnet\n Properties:\n VpcId: !Ref VPC\n CidrBlock: 10.0.2.0/24 # PRIVATE SUBNET 2 (required)\n\n NatEip:\n Type: AWS::EC2::EIP\n Properties:\n Domain: vpc\n\n NatGw:\n Type: AWS::EC2::NatGateway\n Properties:\n AllocationId: !GetAtt NatEip.AllocationId # CRITICAL: NAT for private subnets' egress\n SubnetId: !Ref PublicSubnet # CRITICAL: NAT must be in a public subnet\n\n PublicRt:\n Type: AWS::EC2::RouteTable\n Properties:\n VpcId: !Ref VPC\n\n PublicDefaultRoute:\n Type: AWS::EC2::Route\n Properties:\n RouteTableId: !Ref PublicRt\n DestinationCidrBlock: 0.0.0.0/0\n GatewayId: !Ref IGW # CRITICAL: makes this a PUBLIC subnet\n\n AssocPublic:\n Type: AWS::EC2::SubnetRouteTableAssociation\n Properties:\n SubnetId: !Ref PublicSubnet\n RouteTableId: !Ref PublicRt\n\n PrivateRt:\n Type: AWS::EC2::RouteTable\n Properties:\n VpcId: !Ref VPC\n\n PrivateDefaultRoute:\n Type: AWS::EC2::Route\n Properties:\n RouteTableId: !Ref PrivateRt\n DestinationCidrBlock: 0.0.0.0/0\n NatGatewayId: !Ref NatGw # CRITICAL: private subnets use NAT for internet\n\n AssocPrivateA:\n Type: AWS::EC2::SubnetRouteTableAssociation\n Properties:\n SubnetId: !Ref PrivateSubnetA\n RouteTableId: !Ref PrivateRt # CRITICAL: Workspace subnet must associate to private RT\n\n AssocPrivateB:\n Type: AWS::EC2::SubnetRouteTableAssociation\n Properties:\n SubnetId: !Ref PrivateSubnetB\n RouteTableId: !Ref PrivateRt # CRITICAL: Ensures at least 2 private subnets\n```",
"Other": "1. In the AWS Console, go to VPC > Internet gateways and ensure an Internet Gateway is attached to the VPC.\n2. Go to VPC > Subnets and ensure the VPC has at least one subnet to use as PUBLIC and two subnets to use as PRIVATE (preferably in different AZs). Create missing subnets if needed.\n3. Go to VPC > NAT Gateways and Create NAT gateway in the PUBLIC subnet, allocating an Elastic IP.\n4. Go to VPC > Route tables:\n - For the PUBLIC subnet's route table: add or ensure a 0.0.0.0/0 route targets the Internet Gateway (this marks it public).\n - For the PRIVATE subnets' route table(s): add or ensure a 0.0.0.0/0 route targets the NAT Gateway and remove any 0.0.0.0/0 route to an Internet Gateway. This makes them private with egress via NAT.\n5. Ensure the WorkSpace's subnet is one of the PRIVATE subnets by associating its subnet to the private route table (Routes: 0.0.0.0/0 -> NAT Gateway).\n6. Verify: the VPC now has >=1 public subnet, >=2 private subnets, at least one NAT Gateway, and the WorkSpace's subnet is private.",
"Terraform": "```hcl\n# Minimal VPC: 1 public subnet, 2 private subnets, and a NAT Gateway\nresource \"aws_vpc\" \"main\" {\n cidr_block = \"10.0.0.0/16\"\n}\n\nresource \"aws_internet_gateway\" \"main\" {\n vpc_id = aws_vpc.main.id\n}\n\nresource \"aws_subnet\" \"public\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.0.0/24\"\n}\n\nresource \"aws_subnet\" \"private_a\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.1.0/24\" # PRIVATE SUBNET 1 (required)\n}\n\nresource \"aws_subnet\" \"private_b\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.2.0/24\" # PRIVATE SUBNET 2 (required)\n}\n\nresource \"aws_eip\" \"nat\" {\n domain = \"vpc\"\n}\n\nresource \"aws_nat_gateway\" \"nat\" {\n allocation_id = aws_eip.nat.id # CRITICAL: NAT for private subnets' egress\n subnet_id = aws_subnet.public.id # CRITICAL: NAT must be in a public subnet\n}\n\nresource \"aws_route_table\" \"public\" {\n vpc_id = aws_vpc.main.id\n route { # CRITICAL: makes this a PUBLIC subnet\n cidr_block = \"0.0.0.0/0\"\n gateway_id = aws_internet_gateway.main.id\n }\n}\n\nresource \"aws_route_table_association\" \"public\" {\n subnet_id = aws_subnet.public.id\n route_table_id = aws_route_table.public.id\n}\n\nresource \"aws_route_table\" \"private\" {\n vpc_id = aws_vpc.main.id\n route { # CRITICAL: private subnets use NAT for internet\n cidr_block = \"0.0.0.0/0\"\n nat_gateway_id = aws_nat_gateway.nat.id\n }\n}\n\nresource \"aws_route_table_association\" \"private_a\" {\n subnet_id = aws_subnet.private_a.id # CRITICAL: Workspace subnet must associate to private RT\n route_table_id = aws_route_table.private.id\n}\n\nresource \"aws_route_table_association\" \"private_b\" {\n subnet_id = aws_subnet.private_b.id\n route_table_id = aws_route_table.private.id # CRITICAL: Ensures at least 2 private subnets\n}\n```"
},
"Recommendation": {
"Text": "Follow the documentation and deploy Workspaces VPC using 1 public subnet and 2 private subnets with a NAT Gateway attached",
"Url": "https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces-vpc.html"
"Text": "Launch WorkSpaces in **private subnets** and design the VPC with **one public** and **two private subnets**. Provide outbound access via a **NAT Gateway** and restrict inbound exposure per **network segmentation** and **least privilege**. Distribute subnets across AZs and avoid assigning public IPs to WorkSpaces for **defense in depth**.",
"Url": "https://hub.prowler.com/check/workspaces_vpc_2private_1public_subnets_nat"
}
},
"Categories": [],
"Categories": [
"trust-boundaries",
"internet-exposed"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""