What is the best way to keep groups, roles and permissions synchronised between 2 environments?

Scenario:

We have 2 Auth0 accounts. Call them dev and prod. Both accounts have the authorization extension installed.
After setting up some roles and permissions on dev we used the export/import function in the extension configuration to populate prod with the same roles and permissions. We manually removed the users section of the exported JSON (as it was referencing dev users that did not exist on prod) and we changes the applicationIds accordingly too.

A side effect of this is that the roles and permissions on dev and prod both have the same ids. I’m not sure if this is a good thing or a bad thing.

Problem:
We have now done more dev work, and added several roles and permissions to dev that don’t exist on prod. prod however now has relationships between users and roles that don’t exist in dev. If I was to do the same thing as before, exporting json from dev and importing into prod (while stripping all the users) then these existing relationships would be “nuked.” My options seem to be:

  1. Manually create the new roles/permissions on prod in which case they will no longer have the same ids as dev and I will need to add extra configuration to our services.
  2. Export json from both dev and prod and then manually reconcile these somehow before re-importing into prod (while hoping that nothing changed on prod during this process because it will be lost)

Neither of these solutions feels very attractive. Is there something I’m missing or doing incorrectly?

It’s hard to provide a definitive solution to this, like you mentioned there will be a few ways to approach this and each will have their own pros and cons. From a personal opinion I would try to remove the dependency on specific identifiers, the groups, roles and permissions should be identified by their names and when applicable association with a particular client application.

In addition to the above, I would consider enabling the extension API support and then during development perform any change through a scripted API call. The objective here would be that at the end of development you would have a script that can replicate the same API calls on the production environment. The script could need to be a bit more smart than just pure HTTP calls in situation where it could possibly need to do some lookups based on names instead of dealing with identifiers.

Also, the above is just an idea; I never tried to put it in practice so it’s more something that I would consider to see if it would be feasible. It could also be good to have an intermediate environment, so that the scripted calls are initially created and applied one to one on development, then a compilation of scripted calls is created and applied on a QA environment and if everything goes well, it’s just running it again on production.