Really, Frank, there's nothing wrong with what you've done. A magic object to hang permissions on? OpenACS itself does that in order to define system administrators (we want to change that magic object to be a site-wide object of type "group" so we can use the group admin UI to add/remove sitewide admins but it will still be "magic", just not quite as "magic").
Using groups as you discuss is fine, too.
Your last bit, using ad hoc roles which extend acs-rels, could easily be solved in the permissions system IF object types themselves were objects. You'd then declare each role as an object type, have each acs-rel object of that object type inherit perms from the object type itself. You wouldn't have N*M permission rows to check in this case ...
I don't know if the above is clear but we've talked about "objectifying" object types because various kinds of things can be solved by allowing permissions to be assigned to object types themselves if the code then sets context_id to the object type. Very lightweight in principle...
(making object types objects would help solve other problems too)