Hi...
This post is my 666th, so expect pure evil...
I think needed objects should be created as needed, and orphans removed automatically, otherwise the interface will treble in size. Say you add a permission. Now you need a way to list permissions in the system when they are attached to roles as well as checking a permisison is present when no roles are hooked up to it. Suddenly you have createPermission(), dropPermission(), isPermission(), show<Orphaned|All>Permissions(), permit(), deny(), addRole(), dropRole(), showAllRoles(), showPermissionsByRole()

. This is before we add usage into the mix.
By using just the permit() method to create things we prevent meaningless situations occouring in the first place (affordance). As well as stripping a load of simple accessors out of the interface we take away the maintanence burden from the client. After all they just want to set permissions to a user, not micromanage our library.
But there is an exception. I would suspect that the permission structure edits would be done at a different time from assigning users and could get out of sync. Assigning users would probably be done automatically as well. Thus the exception is trying to assign a role to an access key without that role existing. It means an isRole() method somewhere.
Ok, I don't mind smaller steps.
I really don't think it is the job of our library to tell the application how to handle errors as it just leads to endless wrapping and extra interfaces. Look at the suffering PEAR:: DB inflicts on us

. In lieu of exceptions a simple last error accessor is the least damage we can do, but if a connection error uses another mechanism then there is really only one possible error state. So at this juncture I agree - it is unnecessary.
No for once. The permit() method has enough information to do everything it needs.
A non-role. The access can be created if it doesn't exist as outlined above. Adding independent access keys doesn't make sense without a role. In fact adding them would be a three step process: Add access (low level), add role (administrator), assign access (low level again). Nothing is gained with that first step.
The reverse is not true though so we have an intersting case coming up. If the administrator adds a role, a bunch of access keys are added and then the admin. drops the role, we don't want to dump the entire user base. For this reason I think that dropRole() should not be allowed if users are attached to only that role. This area needs work, perhaps with some typical use cases.
yours, Marcus
Bookmarks