Feature Proposal: Pluggable Access Control Implementation

Motivation

To have different Access Control modules that can retrieve the permissions from different places (topics, LDAP, database, etc), or to implement faster caching, and to speed up queries.

Description and Documentation

Access control is currently tied explicitly to a loaded Meta Object. This feature will re-create it as a pluggable part of the Store API, by moving Meta::haveAccess() to Access::haveAccess(), adding overloaded parameters to allow testing of Foswiki::Meta, web, topic, attachment or Foswiki::Address.

The implementation for this will then be placed in Foswiki::Access::* and accessible as an EXPERT option in configure.

A new and simpler to use API will be added to Foswiki::Func

basic usage examples:
Foswiki::Func::checkAccessPermission('SPIN', 'IncyWincy', undef, 'ThisTopic', 'ThatWeb', undef); #legacy usage - ew! 
Foswiki::Func::haveAccess('SPIN', 'IncyWincyUser', 'ThisWeb', 'ThatTopic');
Foswiki::Func::haveAccess('SPIN', 'IncyWincyUser', $somemeta);
Foswiki::Func::haveAccess('SPIN', 'IncyWincyUser', $someaddress);

$session->access->haveAccess('VIEW', $cUID, 'ThisTopic', 'ThatWeb)
$session->access->haveAccess('VIEW', $cUID, $meta)
$session->access->haveAccess('VIEW', $cUID, $someaddress)

$meta->haveAccess('VIEW', $cUID); #will probably remain as a stub that calls $session->access->haveAccess('VIEW', $cUID, $meta)


=begin TML

---++ ObjectMethod haveAccess($mode, $User, $web, $topic) -> $boolean
---++ ObjectMethod haveAccess($mode, $User, $meta) -> $boolean
---++ ObjectMethod haveAccess($mode, $User, $address) -> $boolean

   * =$mode=  - 'VIEW', 'CHANGE', 'CREATE', etc. (defaults to VIEW)
   * =$User=    - Canonical user id (defaults to current user)
__$User may need to be extended to allow for the non-CUID style permissions lists that Rafael and AndyG envisaged__
Check if the user has the given mode of access to the topic.

*Developer detail*: This call may result in the topic being read.

=cut

I'm going to go with Rafael's 2 initial implementations - normal ACL, and AdminGroup only ACL, and then will add a third that attempts to cache the ACLs to see if that makes a speed difference. (This will then be the basis for the in MongoDB ACL evaluation).

There should be no impact on the normal user - other than to offer more choices as they scale.

Impact and Available Solutions

WhatDoesItAffect:
AffectedExtensions:
HaveQuickFixFor:

Implementation

The Foswiki::Access module is a skeleton that serves to define the public API for Access Control, and to serve as a factory for the selected implementation.

Implementations must extend Foswiki::Access, implement every method, and reside in the Foswiki::Access package (anywhere in the @INC path) have the "Access" suffix (ie, TraditionalAccess).

The user can select the desired implementation using the configure interface. configure will "discover" all the available implementations an present them to the user.

Attached is a patch with the current implementation extracted to TradicionalAccess and a alternative implementation that blocks everyone except Administrators.

-- Contributors: RafaelAlvarez

Discussion

-- RafaelAlvarez - 03 Mar 2006

Is there going to be some documentation about the required methods or do we have to hack through the code?

-- HaraldJoerg - 09 Mar 2006

So far, you'll need to hack through the code. Anyway, the pod documentation of Access.pm will list all the required methods. Also, there is a mechanism in TWiki::Access so if any package extending from it fail to implement a method, an assertion error will be generated.

As soon as there is an official "go!" to Edin* (that's it, when any commit to DEVELOP don't get flamed for not spending the energy bugfixing TWiki4), I'll prepare the documetation and commit everything.

-- RafaelAlvarez - 10 Mar 2006

We should enumberate the various types of access control models and their modes of operation.

  • Mandatory or Discressional
  • Lattice-based
  • Role-based
  • Task-based

  • How will it be administered?
    • Who will have reights to change access control?
    • Audit trail of changes to access control (optional)
  • Centralized access cotnrol using
    • PAM
    • TACAS
    • RADIUS
    • NTLM
    • LDAP
Of course do realise that access control is dependant on Identification and Authentication. Please do not consfuse those two, they are very different although many applications do not fully separate them.

Access Contol lists are easy for a programmer to implement in a liited case but in reality get to be very awkward in corporate settings for a number of reasons. The two bigies are that they don't scale well from the administrative POV and that they don't reflect modern besiness functional models. Role Based access control is much better.

All this leads back to a need for a managed user database which has parts that the user can modify and parts that the administrator only can modify.

-- AntonAylward - 30 Mar 2006

One good thing about parts of TWiki, one of which is Access.pm, is that it is object-oriented. That is, Access.pm creates an access object. Therefore a different implementation can be written as long as the public methods are implemented.

To faciliate this, I suggest that Access.pm be renamed ClassicAccess.pm, which would be a subclass of Access.pm, and Access.pm rewritten as an abstract class. If those places that create an instance (TWiki.pm possibly being the only one) create an instance of ClassicAccess.pm, then there is no effect.

-- MeredithLesly - 31 Mar 2006

If you check my patch, you'll find that Access.pm is now an empty shell to serve as a base class and to provide runtime checking of non-implemented required methods. All the functionality was moved to two subclases: One for Tradicional (what you call classic) and one for AdminOnly.

-- RafaelAlvarez - 31 Mar 2006

Anthon, can you define the difference between Identification and Authentication? I sincerely don't see it.

Anyway, any complete security API should be able to answer at least three questions:
  • Is a valid user for the system?
  • Is the user actually who he/she says he/she is?
  • Is the user allowed to perform X operation?
I think that Access.pm should answer only the last one. The other two are the domain of the password and user managers.

As I see it, for some mechanism the same class should implement the password, user and access management.

-- RafaelAlvarez - 31 Mar 2006

Most IT systems do not fully separate the concepts of identification and authentication - they meld them into one concept -- "login". However identification is a key aspect to the idea of continuity of transactions.

TWiki confuses matters here becuase it does not have a clear mechanism for account vs. non-account access. There is no "null" identity, only the on-null of TWikiGuest. Database old timers will recall this isses from the 70s.

In fact this problem exists elsewhere in TWiki. Consider:
   * Set TOPICDENYVIEW =

If you read TWikiAccessControl and compare the Cairo and Dakar version you will see that Dakar has the note:
Be careful with empty values for any of these. In older versions of TWiki,

    * Set ALLOWTOPICVIEW = 

meant the same as not setting it at all. However since TWiki Dakar release, it means allow no-one access i.e. prevent anyone from viewing the topic. Similarly

    * Set DENYTOPICVIEW = 

now means do not deny anyone the right to view this topic. See "How TWiki evaluates ALLOW/DENY settings" below for more on this.

What this means is on Cairo "DENYTOPICVIEW = " meant a null whereas in Dakar it means the empty set. The sematics have completly changed.

However TWiki uses TWikiGuest to mean both the null identity and the guest account. This is an acrchitectural shortcoming that eventually leads to operational compromises that we have come to take for granted.



Rafael, you go on to raise points that make me thing you do understand the difference.

As you say, a user may be valid for the system. Regardless of anything else. (But also consider the corollary!) The authentication is the proof of identity. Finally you list the issue of access control.

You are right in how you see the division of responsibility.

But don't forget: a complete solution is only possible when we have all three capabilities; identification, authentication, and authorization.

This, ultimately, is the shortcoming of the Cunningham-model wiki. Unless you have all three components you have no audit trail.

  • Was this person allowed to do this operation?
  • Was it really this person?

-- AntonAylward - 01 Apr 2006

Anton, thanks. Yep, it seems that I knew the difference, but didn't know that I knew it smile

-- RafaelAlvarez - 02 Apr 2006

In DenyVsAllowWebChangeVsViewIsBroken I mention that view versus change access control lists are annoying to the administrator. The actors who have change access is normally a subset of those who have view access. It is better to have separate access control lists for read-only and read-write, with the read set computed dynamically as read-only UNION read-write.

... but, that's not what brings me here. I am looking for some discussion of InterfacingToExternalAccessControlListManagers.

Like LDAP, but in my world we use LDAP, and a lot of other different things.

-- AndyGlew - 14 Apr 2006

Fixing escapes of ALLOWTOPICVIEW that broke the RSS feeds.

-- PeterThoeny - 15 Apr 2006

I am not going to raise concern but it would nice if this proposal got a little more documentation added at the top before implementation starts.

Read the code means that only hard core perl programmers understand what is going on. No Tolstoj novel. Just a few more lines please.

-- KennethLavrsen - 17 Aug 2008

And while that's happening, can you make sure you address any relevant concerns from PluggablePermissions?

-- SvenDowideit - 19 Aug 2008

I'll add my name as CommittedDeveloper there.

-- RafaelAlvarez - 19 Aug 2008

Accepted by 14 day rule.

Still remember to enhance the spec before you begin to code to enable better peer review quality wink

-- KennethLavrsen - 15 Sep 2008

RefactorACLCheckOnResultSetAsFilter might means its easier for me to implement this than not - The F::Access class does not exist anymore, but might well come back - at this point i'm just collecting thoughts from past memes.

-- SvenDowideit - 17 Jun 2011

Adjusted the examples to reflect web,topic parameters not topic,web.

The rubric at the top says "to allow testing of Foswiki::Meta, =web, topic, attachment" but the examples and POD only allow for web,topic (which makes sense as long as attachments don't have independent access control)

-- CrawfordCurrie - 05 Jul 2011

If you pass a Foswiki::Address which points to an attachment, and your Foswiki::Access implementation cares about the attachment part, then I guess you can check ACL on attachments.

-- PaulHarvey - 05 Jul 2011

This is in trunk and will go into 1.2.0 - I've added rudimentary docco to configure and DefaultPreferences

however, this feature adds something useful to 1.2.0 - a configure based AdminOnlyAccess setting that would allow the admins to clean up a big mess, or do safe upgrades or deployments.

(Note also that there is an ACL Cache implementation in MongoDBContrib for it - it makes a massive difference to performance)

-- SvenDowideit - 01 Mar 2012

This change also makes it extremely trivial to add a configure based TopicACLReadOnlyAccess setting that will deny all permissions except for view. It is a "soft" readonly in that extensions that use API's that bypass access controls can still make updates. A read only store in some cases would be a better option. But for some types of maintenance this is a reasonable restriction. I have not tested registration yet but I suspect that wouldn't be disabled by this.

-- GeorgeClark - 09 Apr 2014
Topic revision: r10 - 05 Jul 2015, GeorgeClark
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy