Instead of focusing on how many layers of admins you have, consider a set of table structures. One contains users. One contains named groups that have users or groups as members. One table contains permissions. And one table associates permissions with groups.
- superlizard - admin over all
- Eric - Lives in Canada, is a North America admin. There is no Canada group.
- John - Lives in Minnesota, USA, is USA admin
- Bill - Lives in Minnesota, USA, is Minnesota admin
- Cindy - Lives in Minnesota, USA, is regular user
- Frank - Lives in California in USA, is regular user, but there is no California group.
- USA (@Minnesota, Frank) - all residents of USA
- North_America(Eric, @USA) - all residents of North America. Can create subgroups for countries.
- SuperAdmins (superlizard) - Can administrate anything in the system.
- USA_Admins(John) - administrators of USA accounts. Can create subgroups for states.
- Minnesota(John, Bill, Cindy) all residents of Minnesota
- MN_Admins(Bill) - administrators of MN accounts. Cannot create subgroups.
- GroupAdmin can add/delete/update users
- CreateGroup can add new groups
- EditGroup can edit existing groups
- DeleteGroup can delete groups
- EditPermissions can change permissions
- SuperAdmins (Group=@All, GroupAdmin, CreateGroup, EditGroup, DeleteGroup, EditPermissions)
- NA_Admins(Group=@NA, GroupAdmin, CreateGroup)
- USA_Admins (Group=@USA, GroupAdmin, CreateGroup)
- MN_Admins (Group=@Minnesota, GroupAdmin)
This is how directory structures like LDAP work. Now if you want to create a new permission, such as "can send email to these people", the SuperAdmins can create a new permission for it and assign a group to them.
As a matter of fact, you might be better off just using an existing LDAP server to manage your permissions. That way your software can interface with a published API instead of creating one, you can find people who understand LDAP administration, and they can use existing LDAP client tools to manage their users and groups.