Build1 publisher3 min readPublished
A plan-time Rego gate and an inventory sweep disagree about where the owner tag lives
The New Stack's three-pillar recipe for cloud resource ownership pairs a CloudQuery inventory query with an env0 admission policy and a creation-time audit record. Two of them look for the owner in different places.
The Engineer · Build desk

What happened
- A single UNION ALL query over CloudQuery's synced inventory tables lists every EC2 instance, GCP compute instance and Azure VM whose owner tag or label key is absent.
- The sample audit entry records the requester, the approver, approval ticket ENV-4471, a stated purpose and a timestamp at the moment the resource is created.
- The article grounds the problem in attrition, citing US private-sector voluntary turnover of 22 to 25% a year and a hundred-person org losing twenty-odd people annually.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- contradiction One recipe carries two definitions of the owner field, so on GCP a resource can satisfy the inventory query and still be rejected by the admission policy.
- constraint The gate only sees changes that arrive as env0 plans, so console provisioning and any pipeline outside env0 stay governed by the sweep and its sync interval.
- exposure An owner value naming an individual decays at the departure rate the article cites, so cost reviews three years out inherit pointers to people no longer on the payroll.
- decision Anyone copying this has to pick what goes in the owner value, and only the role mailbox and the ticket reference still resolve once the requester has gone.
`tags ->> 'owner' IS NULL` tests whether a key exists [3]. A resource tagged `owner=""` returns an empty string, and an empty string is not NULL, so it passes the sweep. So does `owner=priya`, three years after Priya's laptop went back to IT [11]. The query is still worth running: a short recurring list beats reconstructing provenance from Slack when a cost review flags an instance nobody remembers provisioning [9].
The two controls read different fields. In the inventory query, GCP is read through `labels ->> 'owner'` while the AWS and Azure tables are read through `tags ->> 'owner'` [3]. The Rego rule tests one path, `resource.change.after.tags.owner` [5]. It does not read `labels` at all [12]. On a GCP plan carrying the label the query wants, the rule's `not` clause succeeds and the plan is denied, which fails a resource the sweep would count as compliant.
Coverage differs as well. env0 evaluates Open Policy Agent rules against every plan before it applies [4]. A resource created in a provider console, or by a pipeline that does not run through env0, produces no plan and never meets the rule [13]. The sweep is the backstop for those, and the sync interval sets how long one runs unowned before anyone sees it. For the recipe to transfer, every team touching the account has to provision through env0 plans, and every provider has to keep the owner at the top level of a `tags` map.
The New Stack piece frames all of this as three pillars: "Good resource governance has three pillars: continuously synced inventory, policy that blocks resources without tagged owners, and an audit trail that survives every reorg" [1]. The third pillar is the well-made part. Its sample entry records `requested_by: [email protected]`, `approved_by: [email protected]`, `approval_ref: ENV-4471` and a stated purpose of "load test environment, Q3 capacity planning" [6], and env0 keeps that record attached to the resource for as long as the resource exists [7]. A tag records who owns a thing today, not who asked, why, or who signed off [10]. One of those three identity fields names an individual; the other two name a role mailbox and a ticket [15].
The article puts US private-sector voluntary turnover at 22 to 25% a year, so a hundred-person org loses twenty-odd people annually [8]. Hold the rate flat and 0.78 cubed is 0.475, 0.75 cubed is 0.422, so 42% to 48% of today's staff are still there in three years, assuming departures are independent of who provisioned what [14]. An `owner` value naming a person has about that chance of resolving to someone reachable. The field in the sample record that still answers the shutdown question at that age is ENV-4471 [6].
What to watch
- Whether env0 publishes an owner policy example that reads a labels path as well as tags.owner, which would close the GCP gap in this recipe.
- Whether the audit record outlives the resource it is attached to, since a destroy-and-recreate cycle ends the record's stated retention.
- Whether CloudQuery documents a per-provider sync interval, because that interval is the detection latency for anything provisioned outside a plan.