Every project used the Postgres superuser, the RabbitMQ administrator, an
admin S3 identity and the Zitadel instance-admin PAT, so any one of them
could read or change the others' data.
A new one-shot, `provision` (runs on every `up`, idempotent), gives each
project in x-projects its own:
- Postgres role, owner of its database. No database is open to PUBLIC
anymore, so a role can only connect to its own. An existing database
and everything in it is handed over to the project's role.
- RabbitMQ user, with permissions on its own vhost only.
- Zitadel service account, PROJECT_OWNER of its own project only; its
PAT is written to zitadel/.output/<project>/ for that project's
zitadel-init to mount instead of the admin PAT.
SeaweedFS renders one S3 identity per project, limited to its bucket, and
refuses to start with a clear message on a malformed or repeated key.
The admin accounts stay with this stack. postgres-init is gone: provision
creates the databases. *.sh files are checked out with LF so they run in
the Linux containers from a Windows checkout.