Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add kyverno-json policies for AWS-S3 #108

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions terraform-best-practices/aws/s3/disable-s3-acl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
The Access Control List (ACL) by default is disabled for an S3 Bucket. However, if you'd like to disable the ACL while creating an S3 Bucket from a Terraform file, there are three options that you can provide to the `object_ownership` field in your Terraform file.

**ACLs disabled**:
- *Bucket owner enforced (default)* – ACLs are disabled, and the bucket owner automatically owns and has full control over every object in the bucket. ACLs no longer affect permissions to data in the S3 bucket. The bucket uses policies to define access control.

**ACLs enabled**:
- *Bucket owner preferred* – The bucket owner owns and has full control over new objects that other accounts write to the bucket with the bucket-owner-full-control canned ACL.

- *Object writer* – The AWS account that uploads an object owns the object, has full control over it, and can grant other users access to it through ACLs.

You can read more information about [Controlling ownership of objects and disabling ACLs for your bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html?icmpid=docs_amazons3_console).

In order to test this policy, use the following commands:

1. Initialise Terraform in your working directory
```
terraform init
```

2. Create a binary of your terraform plan
```
terraform plan -out tfplan.binary
```

3. Convert the executable binary into JSON Payload
```
terraform show -json tfplan.binary | jq > payload.json
```
4. Test the policy using `kyverno-json` command
```
kyverno-json scan --payload payload.json --policy policy.yaml
```
Since you've set the `object_ownership` field to `BucketOwnerEnforced` in *s3-disable.tf* file, the policy will give you Passing checks. If you try to change the value of `object_ownership` to either `BucketOwnerPreferred` or `ObjectWriter` the policy will give you failing checks.

In case you'd like to test this policy for a failing scneario, try to set the payload to `./aws/disable-s3-acl/policy-test/bad-payload.json` and run the `kyverno-json scan` command again.
27 changes: 27 additions & 0 deletions terraform-best-practices/aws/s3/disable-s3-acl/disable-s3-acl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apiVersion: json.kyverno.io/v1alpha1
kind: ValidatingPolicy
metadata:
name: disable-s3-access-control-list
annotations:
policies.kyverno.io/title: Disable S3 Access Control List
policies.kyverno.io/category: AWS S3 Security Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
S3 Object Ownership is an Amazon S3 bucket-level setting that
you can use to control ownership of objects uploaded to your bucket
and to disable or enable ACLs. By default, Object Ownership is set to
the Bucket owner enforced setting and all ACLs are disabled.
When ACLs are disabled, the bucket owner owns all the objects in the bucket
and manages access to data exclusively using access management policies.
spec:
rules:
- name: disable-s3-access-control-list
match:
any:
- (planned_values.root_module.resources[?type=='aws_s3_bucket_ownership_controls' || type=='aws_s3_bucket'] | length(@) > `0`): true
assert:
all:
- message: Access Control List(ACL) should be disabled for an S3 Bucket
check:
~.(planned_values.root_module.resources[?type=='aws_s3_bucket_ownership_controls'].values.rule[]):
object_ownership: BucketOwnerEnforced
222 changes: 222 additions & 0 deletions terraform-best-practices/aws/s3/disable-s3-acl/test/bad-payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
{
"format_version": "1.2",
"terraform_version": "1.6.6",
"planned_values": {
"root_module": {
"resources": [
{
"address": "aws_s3_bucket.example",
"mode": "managed",
"type": "aws_s3_bucket",
"name": "example",
"provider_name": "registry.terraform.io/hashicorp/aws",
"schema_version": 0,
"values": {
"bucket": "test-bucket-demo-19012003",
"force_destroy": false,
"tags": null,
"timeouts": null
},
"sensitive_values": {
"cors_rule": [],
"grant": [],
"lifecycle_rule": [],
"logging": [],
"object_lock_configuration": [],
"replication_configuration": [],
"server_side_encryption_configuration": [],
"tags_all": {},
"versioning": [],
"website": []
}
},
{
"address": "aws_s3_bucket_ownership_controls.example",
"mode": "managed",
"type": "aws_s3_bucket_ownership_controls",
"name": "example",
"provider_name": "registry.terraform.io/hashicorp/aws",
"schema_version": 0,
"values": {
"rule": [
{
"object_ownership": "ObjectWriter"
}
]
},
"sensitive_values": {
"rule": [
{}
]
}
}
]
}
},
"resource_changes": [
{
"address": "aws_s3_bucket.example",
"mode": "managed",
"type": "aws_s3_bucket",
"name": "example",
"provider_name": "registry.terraform.io/hashicorp/aws",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"bucket": "test-bucket-demo-19012003",
"force_destroy": false,
"tags": null,
"timeouts": null
},
"after_unknown": {
"acceleration_status": true,
"acl": true,
"arn": true,
"bucket_domain_name": true,
"bucket_prefix": true,
"bucket_regional_domain_name": true,
"cors_rule": true,
"grant": true,
"hosted_zone_id": true,
"id": true,
"lifecycle_rule": true,
"logging": true,
"object_lock_configuration": true,
"object_lock_enabled": true,
"policy": true,
"region": true,
"replication_configuration": true,
"request_payer": true,
"server_side_encryption_configuration": true,
"tags_all": true,
"versioning": true,
"website": true,
"website_domain": true,
"website_endpoint": true
},
"before_sensitive": false,
"after_sensitive": {
"cors_rule": [],
"grant": [],
"lifecycle_rule": [],
"logging": [],
"object_lock_configuration": [],
"replication_configuration": [],
"server_side_encryption_configuration": [],
"tags_all": {},
"versioning": [],
"website": []
}
}
},
{
"address": "aws_s3_bucket_ownership_controls.example",
"mode": "managed",
"type": "aws_s3_bucket_ownership_controls",
"name": "example",
"provider_name": "registry.terraform.io/hashicorp/aws",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"rule": [
{
"object_ownership": "ObjectWriter"
}
]
},
"after_unknown": {
"bucket": true,
"id": true,
"rule": [
{}
]
},
"before_sensitive": false,
"after_sensitive": {
"rule": [
{}
]
}
}
}
],
"configuration": {
"provider_config": {
"aws": {
"name": "aws",
"full_name": "registry.terraform.io/hashicorp/aws",
"version_constraint": "~> 4.16",
"expressions": {
"access_key": {
"constant_value": "ASIA4JFRUINQKAVMFJ7T"
},
"region": {
"constant_value": "us-west-2"
},
"secret_key": {
"constant_value": "uxBT1k1aAgnKzy7NImgwdi7qV6dXDSwAYnJWF/aX"
},
"token": {
"constant_value": "IQoJb3JpZ2luX2VjEEUaCXVzLWVhc3QtMiJHMEUCIAICuzfK4ZNXCHP0EBkv8ALykBK4hyEx2NYKvS042jaEAiEA4FyWjJhlfKhG0TE/Pq4ncnbyXNvnLxjjKvDdWF/pdiUqlwMI7v//////////ARADGgw4NDQzMzM1OTc1MzYiDIKBtCpjoZwAp7xp8CrrAoYMvkPMq0StJ88kQUWSscOSDrbeNulBAMp06U3GtCJkG0S/FNtWWB12QnL0Xq68oqU58bmWn7IRHVQba4L+NzVjSaacpAXld7rrdl0NqfUAyTxQFDMMvg6vQATaK4luZDcMJnkYMoKcFXsMVORy2/l030uimnAJK3fPvGzhx7Imhd81sc5f4CXNrIKZBckthb/8UiSZqeW4uBqgGHR4oi5PCiARl8t8tHVw7+wnOemTO5+wyGnz/ymtAfDfEzObS1sZhasenH80eJ5pQn6y42RPtied6QkRgWaMID/WcWDRsxmTPRxecMqazpwXv9QvoVR1uUqxR1JUi/UW+aAmiFKKOUTQ0F/18XOm0Qg9aQ58rdj50qyZAtcAuTIw+jhkaZmZUk7ilr3NiUKmzihbkPtc6uIHAcptwAdwecy3ToaSBNA9jGbGSzHUgP8MUDqWzH60C6CqFeI+6BxL/5BtGZ/Iw2eYP6Jz2H+WITC37qmtBjqmAeYz9W8WtP0+Qwupx9tAQx0/JTeSN9Kx2HvjNMZRAo8U2ir3aOqHL1EdwNpNJjI70j/a+TvJIh3ePc+zCJQGX5j8eWhW6ZTo97/xCmOnQ+lffAANa9+kcpXBrceWuKmiUWMHwYpoLaw0S8RkrTRt6H1W+HFR857h1TRLzKOj4PrD7x3mkBeeyPQzbW+xpc4Oq8Yy6r0Py7BnU+pO+CrT26pgTUQP6mc="
}
}
}
},
"root_module": {
"resources": [
{
"address": "aws_s3_bucket.example",
"mode": "managed",
"type": "aws_s3_bucket",
"name": "example",
"provider_config_key": "aws",
"expressions": {
"bucket": {
"constant_value": "test-bucket-demo-19012003"
}
},
"schema_version": 0
},
{
"address": "aws_s3_bucket_ownership_controls.example",
"mode": "managed",
"type": "aws_s3_bucket_ownership_controls",
"name": "example",
"provider_config_key": "aws",
"expressions": {
"bucket": {
"references": [
"aws_s3_bucket.example.id",
"aws_s3_bucket.example"
]
},
"rule": [
{
"object_ownership": {
"constant_value": "ObjectWriter"
}
}
]
},
"schema_version": 0
}
]
}
},
"relevant_attributes": [
{
"resource": "aws_s3_bucket.example",
"attribute": [
"id"
]
}
],
"timestamp": "2024-01-19T13:21:17Z",
"errored": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}

required_version = ">= 1.2.0"
}

provider "aws" {
region = "us-west-2"
}

resource "aws_s3_bucket" "example" {
bucket = "test-bucket-demo-19012003"
}

resource "aws_s3_bucket_ownership_controls" "example" {
bucket = aws_s3_bucket.example.id
rule {
object_ownership = "ObjectWriter"
}
}

Loading
Loading