Hi Richard,
I don't know if you have seem them, but we had quite some issues with OpenACS permissions when designing the Project/Open permission system. Everything could basicly be boiled down to the fact that we didn't need permission on a per-user level for most of the objects in P/O. Such a per-user and per-object granularity directly leads to a N*M storage complexity (number of users * number of objects) if the matrix matrix is more or less filled (i.e. if it's not a particularly sparse matrix).
So we decided to "tweak" the OpenACS permissions system in order to reduce the storage complexity to N, using a single "magic" object and a number of "privileges". Then we use a fixed number of groups to make the management of the privileges more easy. That did work out very well. We simply don't have to consider optimizing the performance.
The problem are the objects which _do_ need per-user access control, such as projects. These objects required us to introduce a N * M type of permissions. However, we didn't need inheritance here (neither hierarchical groups nor security contexts), so we can use plain optimized query with a _time_ complexity of log(N * M).
Finally, we had to qualify the relationships between member and projects a bit more, because a project manager should have more rights then a plain project member, particularly in terms of filestorage and discussion groups. So we used the acs_rels table to store the N * M matrix and added a custom relationship holding a relationship qualifier such as "project_member" or "full_member" or "software_tester" etc. so that we didn't have to multiply the N * M matrix with a constant factor (for various possible categories).
I know that this design isn't 100% compliant with the best programming practices @ OpenACS, but atleast we're not having any trouble with performance...
Good luck!
Frank