How to reassign resource ownership before someone’s last day
Summary
The objective of this article is to provide a strategy to catch resource ownership going stale the moment it happens, The post How to reassign resource ownership before someone’s last day appeared first on The New Stack .
Original Text
The objective of this article is to provide a strategy to catch resource ownership going stale the moment it happens, whether someone left the company or just changed teams, instead of finding out during the next security review.
“Last day” doesn’t have to mean the last day at the company; more often, it’s the last day something was that person’s responsibility. But infrastructure ownership changes don’t get the same attention and fanfare as role changes.
“‘Last day’ doesn’t have to mean the last day at the company; more often, it’s the last day something was that person’s responsibility.”
Marcus ran platform engineering for two years, then got promoted into a data platform position. HR updated his title. IT updated his badge access. The forty-one environments still tagged owner: marcus.reyes@company.com? Nobody touched those, because it’s barely anyone’s job to update infrastructure ownership when someone leaves, let alone when they get promoted. Eight months later, an approval request for one of those environments shows up in Marcus’s queue. He approves it, even though he hasn’t touched the project in almost a year, because it would take longer to understand and reject the request than to click Approve.
This isn’t a story of carelessness. It’s about how little attention the infrastructure side gets after a promotion, lateral move, or even departure. You don’t need a whole new reorg process to fix it. All that’s needed is a query, a policy, and one more step in whatever process exists for moving someone off a team.
1 – The query that flags an owner who’s gone quiet
A good way to keep owner tags accurate is to map their emails to their IAM usernames. Cross-reference owner tags against AWS’s aws_iam_user_last_accessed_details table to find credentials that have gone quiet, which is a reliable indicator that something has changed and a tag update might be called for:
SELECT r.resource_id, r.owner, MAX(la.last_authenticated) AS owner_last_active FROM ( SELECT resource_id, tags ->> 'owner' AS owner FROM aws_ec2_instances WHERE tags ->> 'owner' IS NOT NULL ) r JOIN aws_iam_user_last_accessed_details la ON la.user_name = split_part(r.owner, '@', 1) GROUP BY r.resource_id, r.owner HAVING MAX(la.last_authenticated) < now() - interval '90 days' ORDER BY owner_last_active;
Entra ID keeps the same kind of ledger under a different name, and without the extra translation step. userPrincipalName in Entra ID is already the credential, so a VM’s owner tag joins straight to the identity that logged in, no splitting required:
SELECT r.resource_id, r.owner, MAX(s.created_date_time) AS owner_last_active FROM ( SELECT resource_id, tags ->> 'owner' AS owner FROM azure_compute_virtual_machines WHERE tags ->> 'owner' IS NOT NULL ) r JOIN entraid_auditlogs_signins s ON s.user_principal_name = r.owner GROUP BY r.resource_id, r.owner HAVING MAX(s.created_date_time) < now() - interval '90 days' ORDER BY owner_last_active;
GCP breaks the pattern. Not through any fault of its own: AWS and Entra ID both log when a credential was last used to touch something, and GCP’s IAM layer keeps no equivalent record. The closest signal lives one layer up, in whichever directory issued the identity in the first place, which for most GCP orgs means Google Workspace’s own login record for the person behind the label:
“Ninety days of silence from someone responsible for a resource isn’t definitive proof they moved, but it’s the kind of sign worth fifteen minutes of someone’s time instead of eight months of nobody’s.”
SELECT r.resource_id, r.owner, MAX(w.last_login_time) AS owner_last_active FROM ( SELECT resource_id, labels ->> 'owner' AS owner FROM gcp_compute_instances WHERE labels ->> 'owner' IS NOT NULL ) r JOIN googleworkspace_users w ON w.primary_email = r.owner GROUP BY r.resource_id, r.owner HAVING MAX(w.last_login_time) < now() - interval '90 days' ORDER BY owner_last_active;
Ninety days of silence from someone responsible for a resource isn’t definitive proof they moved, whichever cloud is asking the question, but it’s the kind of sign worth fifteen minutes of someone’s time instead of eight months of nobody’s.
2 – The policy that prevents orphaned environments
Queries catch what’s already stale. If you want to stop the next handoff from slipping through the cracks, an unenforced tag won’t be enough. Ownership belongs in whatever role-based access system already governs the resource, as an actual role assignment rather than a label: a cloud IAM binding, a Kubernetes RoleBinding, a custom role in an IaC orchestration platform, anything a policy engine can actually see instead of a string someone typed into a tags field. The check itself is a handful of lines of Rego, run wherever policy already gets evaluated:
package ownership # METADATA # title: require an active owner # description: A resource can't lose its last assigned Owner without a replacement. deny[format(rego.metadata.rule())] { count(input.resource.roles.owner) == 0 } format(meta) := meta.description
Wiring this in looks different depending on what’s already running the policy. A homegrown Terraform pipeline needs an OPA server bolted onto the CI job, a place to store the role bindings the policy reads from, and someone to keep both in sync as the org chart changes. A platform like env zero skips that part: Custom Roles already cascade across org, project, and environment, so the policy runs against role assignments the platform was already tracking, on the same schedule it already runs drift checks. Evaluated there, or anywhere else it’s wired in, removing someone’s Owner role during an off-boarding or a transfer without assigning a replacement fails immediately, instead of someone stepping in months later.
3 – The step every transfer checklist is missing
Teams already have a process for moving someone off a project, whether it’s an offboarding checklist or a one-line Slack message to IT. How many of them ask what that person still owns? Before revoking access, run the query from Section 1 against their name, and route whatever it finds to their manager or the team lead for reassignment. Reassign first, then revoke. Don’t leave it for someone to hopefully notice later.
Why this keeps happening
Attrition gets all the attention because people leaving feels final. Internal moves don’t get anywhere near the scrutiny, even though they’re arguably more common: almost a third of roles got filled internally in 2024, up from the previous year. No off-boarding checklist was triggered because nobody left; but now someone is no longer the right owner, even if they still technically have access.
“Reassign first, then revoke. Don’t leave it for someone to hopefully notice later.”
This is the same problem our last piece covered from the discovery side. That article focused on ensuring every resource has an owner in the first place. This one is about what happens when owners change roles, which happens more often than someone’s last day at the company.
Org charts will keep changing. Ownership needs to keep up.
None of this will change the frequency of reorgs. In fact, internal moves are typically a good thing. What needs to change is whether ownership updates keep up with team reassignments, instead of staying stapled to an old job for the next year and waiting to be noticed. A resource doesn’t care who used to own it; it just needs to know who owns it now.
The post How to reassign resource ownership before someone’s last day appeared first on The New Stack.
Lotu Radar provides attributed news summaries and links to the original publisher. Full reporting and copyright remain with the source.