CSPM with Cloud Custodian
Keeping customer-modified blueprints compliant to a bank's security posture across AWS, Azure, and GCP, with Cloud Custodian (c7n) policies I deployed and managed through middleware.
LetsBloom shipped secure blueprints, but a blueprint is only compliant until a customer changes it. I used Cloud Custodian to keep them compliant afterward: policy-as-code that continuously checks each customer's cloud against the bank's security posture and remediates the drift. I built the middleware that deployed and managed those policies across the marketplace.
Compliant on day one, drifting by day ninety
The moment a customer team relaxes a security-group rule or turns off a bucket's public-access block, their environment has drifted from the posture the bank requires. Cloud Security Posture Management (CSPM) is the discipline of finding that drift and, ideally, fixing it, continuously.
Cloud Custodian, or c7n, is an open-source policy-as-code engine for cloud governance, security, and cost. You write rules in YAML; c7n evaluates your cloud against them and can remediate what fails. I built the middleware that packaged, deployed, and managed these policies across the blueprints, landing zones, and marketplace tools, so each customer's environment kept matching the bank's posture no matter what they changed.
A policy is four things
A c7n policy is refreshingly small. It names a resource, filters down to the ones that matter, and takes actions on them, with a mode that decides when it runs. The part that matters most is that the actions can remediate, not just report. Finding a public bucket is useful; turning the block back on automatically is the point.
Every policy is the same four parts. Click one to see what it does, and it lights up in the YAML.
policies: - name: s3-block-public-access resource: aws.s3 mode: type: cloudtrail events: [PutBucketAcl, CreateBucket] filters: - type: check-public-block BlockPublicAcls: false actions: - type: set-public-block BlockPublicAcls: true - type: notify to: [security@bank]The cloud resource the policy governs. aws.s3 targets S3 buckets; every provider namespaces its resources (aws., azure., gcp.).
One language, every cloud
The reason c7n scales to a whole estate is that it is one declarative language across providers. The same policy shape governs aws.s3, azure.vm, and gcp.instance; only the resource name and a few keys change. Compare that to the alternative, bespoke imperative SDK code per cloud, and the appeal is obvious.
We ran it on AWS, Azure, and GCP. c7n has since added Kubernetes support, but that was not there when I built this.
The same question, "which instances does sam own," on each provider. On the left, c7n. On the right, the SDK code it replaces.
policies:
- name: my-instances
resource: aws.ec2
filters:
- type: value
key: "tag:owner"
value: "sam"import boto3
client = boto3.client('ec2')
custom_filter = [{
'Name': 'tag:owner',
'Values': ['sam']}]
response = client.describe_instances(
Filters=custom_filter)One declarative policy, provider-agnostic but for the resource name, instead of bespoke imperative code per cloud. That is why it scales to a whole estate.
How it runs: from a scan to real-time, across the org
A policy is only as good as when it runs. c7n can run on demand for an audit, on a schedule to catch drift continuously, or event-driven off CloudTrail so it remediates the instant something changes. To apply a posture to an entire organization rather than one account, c7n-org fans a whole policy set across every account, subscription, or project in parallel. c7n-guardian does the same idea for GuardDuty, wiring up threat detection org-wide.
# accounts.yml: the estate c7n-org fans a policy set across.
accounts:
- name: customer-a-prod
account_id: "111111111111"
role: arn:aws:iam::111111111111:role/c7n
- name: customer-b-prod
account_id: "222222222222"
role: arn:aws:iam::222222222222:role/c7n
# Run the whole bank-posture policy set across every account, in parallel:
# c7n-org run -c accounts.yml -u posture.yml -s out
# c7n-org report -c accounts.yml -u posture.yml -s outThe same policy can run on demand, on a schedule, on an event, or across a whole organization. Click one.
- The policy fires the instant a matching API call happens, for example the moment a bucket is made public.
- This is near-real-time remediation: the window of non-compliance is seconds, not a scan interval.
The middleware I built
The policies were the easy part. The work was the middleware around them: a system that took the bank's posture as a set of c7n policies, deployed them into each customer's cloud with the right roles and execution modes, ran them across the estate with c7n-org, and surfaced the results. That is what turned c7n from a CLI you run by hand into a managed CSPM service baked into the LetsBloom platform.
Why CSPM as code
Posture management done by hand is a losing race: no team can watch every resource in every account across three clouds. Expressed as code, the posture becomes something you version, test, apply everywhere, and enforce continuously, and with event-driven remediation, something that corrects itself faster than a person would even notice. For a platform whose promise to a bank is 'this stays secure,' that is the only way the promise holds.