Skip to content
Notifications
Clear all

TIL: You can create custom compliance checks with a bit of JSON.

3 Posts
3 Users
0 Reactions
0 Views
(@ethans)
Estimable Member
Joined: 2 weeks ago
Posts: 82
Topic starter   [#23558]

Just found this while poking around the compliance dashboard. You can actually build your own custom checks without needing to wait for Trend to add them. It’s not super obvious, but the engine can ingest a simple JSON schema.

Basically, you define a rule with a condition and the resource types to evaluate. Used it to flag any S3 buckets in our accounts that still have public write ACLs enabled, beyond the standard checks. The structure is pretty straightforward once you see an example.

Here’s the gist of what I used for the S3 check:
`{"version":"1.0","rules":[{"ruleId":"CustomS3PublicWrite","category":"CUSTOM","resourceTypes":["AWS::S3::Bucket"],"description":"Checks for bucket ACL allowing public write","parameters":{"acls":"public-write"},"condition":"resource.aws.s3.bucket.acls CONTAINS "public-write""}]}`

Saved it as a .json file and uploaded it under Compliance > Custom Checks. Ran a scan and it popped right into the report. Opens up a lot of possibilities for team-specific policies.



   
Quote
(@davek)
Estimable Member
Joined: 2 weeks ago
Posts: 112
 

That's a solid find. The JSON schema approach is indeed the primary extension point for most cloud compliance tools, though the exact property names tend to be vendor-specific. One important nuance with custom S3 checks is that they often only evaluate the bucket ACLs, not the bucket policies. A bucket with a restrictive ACL but a permissive policy granting `s3:PutObject` to `"*"` would still be a public write risk. Your condition would need to also join against the policy document, if the engine's data model exposes it.

Also, be mindful of the `version` field. They sometimes increment it for breaking changes in the rule language, and an older schema might be silently ignored after an update. It's good to test after any major platform upgrade.

Have you experimented with any checks for other services, like unencrypted RDS instances or Security Groups with overly broad ingress? The pattern is usually similar, just changing the `resourceTypes` and the condition's property path.


CPU cycles matter


   
ReplyQuote
(@infra_architect_rebel_alt)
Reputable Member
Joined: 3 months ago
Posts: 238
 

You're absolutely right about the policy vs. ACL blind spot, and it's a classic example of why these "easy" custom checks can create a false sense of security. The data model is everything. I've seen engines where the policy document is a separate, lazily-evaluated resource type, so you'd need a rule that joins `AWS::S3::Bucket` to `AWS::S3::BucketPolicy` and then parses the JSON. That gets messy fast.

Your point on the `version` field is crucial too. I've been burned by that after a "seamless" vendor update where all our custom rules just stopped firing without a peep. The changelog buried the breaking change in a footnote about "rule syntax 2.0." Now I treat any custom rule as a temporary workaround and push to get it implemented natively by the vendor, even if it takes a ticket and six months of waiting. The maintenance burden isn't worth it for anything mission-critical.

As for checks on other services, RDS encryption is usually a simple property flag, but Security Groups are a nightmare in these systems. The condition language often can't handle evaluating the CIDR ranges in ingress rules effectively. You end up with a rule that flags any rule with a `0.0.0.0/0` source, but misses the functionally equivalent but slightly less broad `10.0.0.0/8` that some misguided soul thinks is "more secure."


keep it simple


   
ReplyQuote