First I'd like to link my previous work on this subject: https://review.openstack.org/#/q/topic:bp/tenant-delete,n,z As Armando said very nicely in today's drivers meeting, it was 'ahead of its time'. Although that effort was abandoned, we can learn a few things from it. First, on the practical level, here's the code that actually deleted resources: https://review.openstack.org/#/c/92600/5/neutron/services/identity/project_deleted.py If you scroll all the way down you can see (Roughly) the correct order in which we would delete resources. One thing to note is shared resources: If the tenant being deleted has a shared network with ports on it from other tenants, you wouldn't be able to delete that network. You should fail gracefully and skip it, and continue to delete other resources (The code doesn't currently do that). The more interesting discussion is about the high level approach taken by that patch series, and that is: 1) Listen on the RPC bus for keystone tenant deletion messages (Back when I worked on it, those were actually not emitted by default, you had to configure Keystone to do that. I don't know if this has changed since) 2) In case neutron-server(s) was/were not up when that notification was sent, provide a CLI script that invokes the (Same) tenant-deletion code. 3) The same script would optionally reach out to Keystone, and write a list of resources that existed in Neutron that were owned by tenants that no longer exist according to Keystone. The script could also take such a list (Persisted to a file) and actually delete those resources. Persisting this information to files is useful for ops for auditing reasons, and for integrating with billing systems for example. There's alternatives to the approach taken by that patch series: 1) One such alternative is to offer a script (os-purge, already mentioned in this bug) that would contain all code by all projects that offer tenant-deletion code. 2) All projects will offer an API that accepts a tenant-id and deletes all resources that belong to that tenant. Ops would have to create a small script that accepts a tenant-id, then calls nova project-purge , neutron project-purge , etc. We could of course modify os-purge to use each project's project-purge as those are implemented (i.e. os-purge would call neutron project-purge instead of implementing that logic on its own). Side note: *aaS and other Neutron stadium projects that maintain resources are an interesting problem. Would they introduce their code to the main Neutron repo, or would Neutron offer pluggability to project-purge? Ultimately both 1 and 2 are simpler than my patch series and I would advise against listening on the RPC bus. It's a nice idea in theory but it's too complicated because you need to write the sync code anyway. One advantage to the 2nd approach over the 1st is that each project is more likely to maintain higher quality and up to date code over having it out of repo. I propose an alteration on the 2nd approach. Call it approach 2'. I'm afraid that until someone (John?) proposes a cross-project spec and follows up on the discussion, we might find ourselves in a position where we're the first to merge a new API for this, an API that we'd have to commit to, and other projects wouldn't follow suit. Fast forward a year and you'll see yet another blog post bashing OpenStack consistency '3 out of X OpenStack projects delete their resources when a tenant is deleted. Swift and Neutron offer to do this via the API, although their clients of course do this using a different syntax: swift tenant-delete , neutron project-purge , Nova offers a CLI tool that does the same, and other projects don't bother'. (By the way the unified OpenStack CLI client is sounding pretty good right now). I'd like to *try* to get it right. Thus I propose that the assignee goes ahead with writing the code, and exposing this code via a CLI tool (More on this in a bit). In parallel the assignee would file a cross-project spec, and if that effort succeeds Neutron would offer an API, reusing the same code already merged, with other projects at least in agreement to follow. Looking at what needs to be done, you'd need to implement essentially a function that accepts a tenant_id and deletes anything owned by that tenant. This can be *implemented internally* via either the plugin layer or the API layer. This is explained via some pseudo code: def purge_project(tenant_id): core_plugin.delete_routers(tenant_id=tenant_id) Or: def purge_project(tenant_id): neutron_client.delete_routers(tenant_id=tenant_id) (Or even just use the normal user's context [Not admin] and delete everything that user has access to, i.e. not filter on tenant_id). The first option probably makes more sense, just because you don't need to go through the API layer to do this (But this isn't a very strong argument IMO, it'd be nice to have, but not required). However, the advantage of the second option is that you could write that code once, and then expose it either via a CLI tool or a new API verb without modifying the implementation. Summary: 1) File a cross-project spec. 2) Write the code, expose it via CLI, not API. 3) If 1 succeeds (I hope and think it will with enough persistence) expose the already merged code via the API (This should be trivial).