[OpenAFS] Re: Ideas for finer grain set acl controls
Michael Meffie
mmeffie@sinenomine.net
Wed, 11 Nov 2009 14:38:51 -0500
Andrew Deason wrote:
> Recent discussions have shown that there are a few possible ways we
> could go about restricting ACL-setting access. With this email I hope to
> detail all of the ones that have come up so far, and demonstrate the
> pros and cons of each.
Andrew,
Thank you for expanding on the ideas being considered.
There seems to be consensus a volume level control is what is
desired, regardless of the options currently under consideration.
My opinion is we need to find an option that would be must
intuitive to end-users, and I'm not sure we know enough yet
to say which approach would be the least confusing and
surprising for end-users. I hope some others will chime in
to express some opinions.
> Since the rest of this is quite long, here's a quick summary of the
> conclusions. We have three methods: 'method 1' is the "volume ACL
> policies" idea, 'method 2' is the "volume-level ACL overlays" idea, and
> 'method 3' is the "volume ACL masks" idea. To cover all uses cases, we'd
> either do method 1, or a combination of 2 and 3. Or we could just
> implement all of them; I don't see anything stopping us from
> implementing everything desribed here.
>
> The bottom line is that I find method 1 to be the most flexible and the
> least confusing to end-users, but it is the most confusing to
> administrators, and it is the slowest (when changing the volume-level
> permissions). Using methods 2+3 has the opposite pros/cons.
>
> Here are the details. Each method has an explanation for what it
> generally is and how it works, followed by its use in a few simple
> use-case scenarios, followed by the pros/cons.
>
> Method 1, "volume ACL policies":
>
> With this method, we maintain policies of who is allowed to set what ACLs
> in a volume. For example, to allow nobody but system:powerusers to grant
> idwka rights to system:anyuser, we'd have a policy for system:anyuser
> that would look like this:
>
> system:powerusers rlidwka
> system:anyuser rl
>
> After that policy is set, any time a user not in system:powerusers tries
> to grant system:anyuser more than rl rights, they will get an EACCES
> error. This does not change the existing ACLs in the volume; an
> administrator will need to run an auditing tool to make sure that
> existing ACLs comply with the volume policy.
>
> "How do I prevent system:anyuser/system:authuser write access?"
> --
>
> You would call something like this
>
> vos setpolicy -add-positive \
> -user system:anyuser \
> -set-rights rl \
> -for-user system:anyuser \
> -in-volume user.adeason
>
> to prevent people fromt giving system:anyuser write access. To ensure
> that existing ACLs don't permit write access, you would need to run
> something like
>
> vos auditpolicy -vol user.adeason
>
> "How do I prevent group.foo write access?"
> --
>
> To prevent an arbitrary normal group from getting write access, things
> are slightly different. You would need to prevent users from taking away
> negative idwka rights, and then assign negative idwka rights to all
> directories in the volume. So, something like
>
> vos setpolicy -remove-negative \
> -user system:anyuser \
> -set-rights rl \
> -for-user group.foo \
> -in-volume user.adeason
>
> Would allow users to only remove 'rl' rights from group.foo in negative
> ACLs. Then you would need to set negative idwka ACLs on all directories
> in the volume.
>
> "How do I guarantee group.bar read access?"
> --
>
> Prevent normal users from taking away read access from group.bar, and
> from granting negative read access for group.bar:
>
> vos setpolicy -remove-positive \
> -user system:anyuser \
> -set-rights idwka \
> -for-user group.bar \
> -in-volume user.adeason
>
> vos setpolicy -add-negative \
> -user system:anyuser \
> -set-rights idwka \
> -for-user group.bar \
> -in-volume user.adeason
>
> Then, grant read access for group.bar in all directories in the volume.
>
> Method 1 pros:
>
> - More flexible for a variety of situations. In particular, this allows
> administrators (or an arbitrary administrator-defined set of users)
> to override the volume policies, and set e.g. system:anyuser write
> on a particular directory if they wish.
>
> - No performance overhead at access-check time. All of the additional
> access checks are done during SetACL.
>
> - Minimal end-user confusion. ACLs accurately represent exactly what
> rights different users have. Trying to set an ACL that violates the
> policy will result in EACCES, so they know the SetACL operation
> didn't work. It may be confusing as to why it did not, but at least
> it is clear that the ACL was not changed.
>
> Method 1 cons:
>
> - Volumes need to be 'audited' (or all of the ACLs just need to be set)
> to make sure they comply with the ACL policy, which can be slow, and
> is just another step that needs to be done.
>
> - Higher end-administrator confusion (perhaps). Setting the policies
> can get confusing.
>
> Method 2, "volume-level ACL overlays":
>
> With this method, we maintain a single additional ACL in the volume
> metadata, which is applied to access checks in the volume, after
> performing the per-directory ACL check. It can be thought of as similar
> to the fileserver -implicit flag, but more generalized.
>
> For example, if we wanted a volume where system:backups was guaranteed
> to have 'rl' rights, and system:evilusers was guaranteed to not have
> _any_ rights, the volume-level ACL would look like:
>
> positive:
> system:backups rl
> negative:
> system:evilusers rlidwka
This is compelling to me, as users should already be familiar
with ACL based rights, so we are just augmententing what is
already in place.
I could see an updated fs tool to show "volume level acl(s)"
which could only be set be someone in the SUsers.
fs la /afs/example.com/user/mike
Access list for /afs/example.com/user/mike
Normal rights:
group:foo rlidwka
system:anyuser: rl
mike rlidwka
system:backups rl (volume)
Negative rights:
andrew rlidka
system:evilusers rlidwka (volume)
where the (volume) indicated volume level acls, which
are read-only for a user with admin rights on a directory.
>
> Thus, any time an access check is done on an ACL anywhere in the
> volume... after we do the normal directory ACL check, we look at this
> volume-level ACL. If the accessing user is in system:backups, they will
> get rl rights, and if they are in system:evilusers, all of their rights
> will go away.
>
> "How do I prevent system:anyuser/system:authuser write access?"
> --
>
> You can't. If we allow you to specify the 'anonymous' user, you could
> assign negative idwka rights to 'anonymous' on the volume-level ACL to
> prevent system:anyuser write access. But there is no way to prevent
> access for system:authuser.
>
> Note: giving a negative ACL on, say, system:anyuser would prevent _any_
> user from getting rights; that's not what we'd want.
Since system:anyuser represents all users, it seems to me we could
introduce a way to indicate anonymous users. Perhaps with a new
system group, system:anonusers which represents users that are
not authenticed?
At that point we would specify a volume level negative right,
Negative rights:
system:anonusers idwka
>
> "How do I prevent group.foo write access?"
> --
>
> Just grant negative idwka access to group.foo on the volume. Something
> like:
>
> vos setacl -vol user.adeason -acl group.foo idwka -neg
>
> Members of group.foo will now not be able to write anything in the
> volume.
>
> "How do I guarantee group.bar read access?"
> --
>
> Same as above, just grant positive read rights. Something like:
>
> vos setacl -vol user.adeason -acl group.bar rl
>
> Method 2 pros:
>
> - Changing the volume-level rights is quick.
>
> - Minimal end-administrator confusion; this is relatively simple to
> understand.
>
> - Simpler than method 1 to implement.
>
> Method 2 cons:
>
> - We have no way to restrict access of special groups like
> system:anyuser, system:authuser, or host IP groups. To get this, we'd
> have to combine with method with method 1 or 3.
>
> - There is no way to override the volume-level ACL, and have an
> administrator force e.g. system:anyuser write access on a particular
> directory.
>
> - Higher end-user confusion. With legacy 'fs listacl', there is no way
> to see that there is a volume-level ACL in play, and users may have
> no idea why access is failing for certain cases. Of course, with new
> tools we can fix that.
>
> - Performance impact is an extra O(n) ACL calculation for the
> volume-level ACL. But those ACLs should be small anyway.
>
> Method 3, "volume ACL masks"
>
> With this method, we maintain a mapping of users to a rights mask. Any
> time an ACL access check is performed, if a positive ACL entry matches a
> user in that table, the acquires rights are masked to the rights mask in
> the table.
>
> For example, if we wanted to prevent users from giving away write
> access to system:anyuser, and prevent users from giving admin access to
> system:authuser, we could have a table like so:
>
> system:anyuser rl
> system:authuser rlidwk
>
> So any time an ACL entry for system:anyuser appears, everything is
> treated as if the rights in that ACL entry were logically ANDed with
> 'rl'.
>
> "How do I prevent system:anyuser/system:authuser write access?"
> --
>
> Set the rights mask for them to just 'rl'. Something like:
>
> vos setaclmask -vol user.adeason -user system:anyuser -mask rl
>
> So any time an ACL entry for system:anyuser appears in the volume,
> everything will act as if the rights were limited to rl.
>
> "How do I prevent group.foo write access?"
> --
>
> You can't. Well, you could, but then someone could do this instead:
>
> pts createg adeason:foo
> pts addu group.foo adeason:foo
> fs sa dir adeason:foo rlidwka
>
> which would bypass the check for 'group.foo' appearing in the ACL list.
>
> "How do I guarantee group.bar read access?"
> --
>
> You can't.
>
> Method 3 pros:
>
> - Changing the rights mask is quick.
>
> - Maybe small end-administrator confusion (I don't know, is this simple
> to understand?)
>
> - Runtime performance overhead is O(1).
>
> - Simpler to implement than method 1.
>
> Method 3 cons:
>
> - Only works for restricting special groups like system:anyuser,
> system:authuser, host IP groups, etc. Cannot restrict 'normal'
> groups, and cannot add rights.
>
> - No way to override the ACL masks on a particular directory, if the
> administrator wants to.
>
> - Higher end-user confusion with legacy client tools.
>
>
> I assume that if we don't do method 1, we could combine both of methods
> 2 and 3.
>
> To summarize the major areas where each one is better:
>
> Better | Worse
> ---------------------
> flexibility: : method 1 | method 2+3
> end-user confusion : method 1 | method 2+3
> end-admin confusion: method 2+3 | method 1
> policy-change speed: method 2+3 | method 1
>
> There are other pros and cons, but I think those areas are the only ones
> where it matters much.
>
Thanks,
Mike