1 ===================
2 Security Mechanisms
3 ===================
5 :Version: $Revision: 1.4 $
7 Current situation
8 =================
10 Current logical controls:
12 ANONYMOUS_ACCESS = 'deny'
13 Deny or allow anonymous access to the web interface
14 ANONYMOUS_REGISTER = 'deny'
15 Deny or allow anonymous users to register through the web interface
16 ANONYMOUS_REGISTER_MAIL = 'deny'
17 Deny or allow anonymous users to register through the mail interface
19 Current user interface authentication and controls:
21 - command-line tool access controlled with passwords, but no logical controls
22 - CGI access is by username and password and has some logical controls
23 - mailgw access is through identification using sender email address, with
24 limited functionality available
26 The web interface implements has specific logical controls,
27 preventing non-admin users from accessing:
29 - other user's details pages
30 - listing the base classes (not issues or their user page)
31 - editing base classes
33 Issues
34 ======
36 1. The current implementation is ad-hoc, and not complete for all `use cases`_.
37 2. Currently it is not possible to allow submission of issues through email
38 but restrict those users from accessing the web interface.
39 3. Only one user may perform admin functions.
40 4. There is no verification of users in the mail gateway by any means other
41 than the From address. Support for strong identification through digital
42 signatures should be added.
43 5. The command-line tool has no logical controls.
46 Possible approaches
47 ===================
49 Security controls in Roundup could be approached in three ways:
51 1) at the hyperdb level, with read/write/modify permissions on classes, nodes
52 and node properties for all or specific transitions.
53 2) at the user interface level, with access permissions on CGI interface
54 methods, mailgw methods, roundup-admin methods, and so on.
55 3) at a logical permission level, checked as needed.
57 In all cases, the security built into roundup assumes restricted access to the
58 hyperdatabase itself, through Operating System controls such as user or group
59 permissions.
62 Hyperdb-level control
63 ---------------------
65 Control is implemented at the Class.get, Class.set and Class.create level. All
66 other methods must access nodes through these methods. Since all accesses go
67 through the database, we can implement deny by default.
69 Pros:
71 - easier to implement as it only affects one module
72 - smaller number of permissions to worry about
74 Cons:
76 - harder to determine the relationship between user interaction and hyperdb
77 permission.
78 - a lot of work to define
79 - must special-case to handle by-node permissions (editing user details,
80 having private messages)
83 User-interface control
84 ----------------------
86 The user interfaces would have an extra layer between that which
87 parses the request to determine action and the action method. This layer
88 controls access. Since it is possible to require methods be registered
89 with the security mechanisms to be accessed by the user, deny by default
90 is possible.
92 Pros:
94 - much more obvious at the user level what the controls are
96 Cons:
98 - much more work to implement
99 - most user interfaces have multiple uses which can't be covered by a
100 single permission
103 Logical control
104 ---------------
106 At each point that requires an action to be performed, the security mechanisms
107 are asked if the current user has permission. Since code must call the
108 check function to raise a denial, there is no possibility to have automatic
109 default of deny in this situation.
111 In practice, this is implemented as:
113 1. there's a mapping of user -> role (in hyperdb)
114 2. there's a mapping of role -> permission (in code)
115 3. there's a function that's available to all roundup code that can ask
116 whether a particular user has a particular permission.
118 Pros:
120 - quite obvious what is going on
121 - is the current system
123 Cons:
125 - large number of possible permissions that may be defined, possibly
126 mirroring actual user interface controls.
127 - access to the hyperdb must be strictly controlled through program code
128 that implements the logical controls.
131 Applying controls to users
132 ==========================
134 Individual assignment of Permission to User is unwieldy. The concept of a
135 Role, which encompasses several Permissions and may be assigned to many Users,
136 is quite well developed in many projects. Roundup will take this path, and
137 allow the multiple assignment of Roles to Users, and multiple Permissions to
138 Roles. These definitions will be stored in the hyperdb.
141 A permission module defines::
143 class InMemoryImmutableClass(hyperdb.Class):
144 ''' Don't allow changes to this class's nodes.
145 '''
146 def __init__(self, db, classname, **properties):
147 ''' Set up an in-memory store for the nodes of this class
148 '''
150 def create(self, **propvalues):
151 ''' Create a new node in the in-memory store
152 '''
154 def get(self, nodeid, propname, default=_marker, cache=1):
155 ''' Get the node from the in-memory store
156 '''
158 def set(self, *args):
159 raise ValueError, "%s are immutable"%self.__class__.__name__
161 class PermissionClass(InMemoryImmutableClass):
162 ''' Include the default attributes:
163 - name (String, key)
164 - description (String)
165 '''
167 class RoleClass(InMemoryImmutableClass):
168 ''' Include the default attributes:
169 - name (String, key)
170 - description (String)
171 - permissions (PermissionClass Multilink)
172 '''
174 def hasPermission(db, userid, permission):
175 ''' Look through all the Roles, and hence Permissions, and see if
176 "permission" is there
177 '''
180 The instance dbinit module then has::
182 in open():
184 perm = permission.PermissionClass(db, "permission")
185 role = permission.RoleClass(db, "role")
187 wa = perm.create(name="Web Access",
188 description="User may log in through the web")
189 wr = perm.create(name="Web Registration",
190 description="User may register through the web")
191 ma = perm.create(name="Mail Access",
192 description="User may log in through email")
193 mr = perm.create(name="Mail Registration",
194 description="User may register through email")
195 aa = perm.create(name="Access Everything",
196 description="User may access everthing")
197 role.create(name="User", description="A regular user, no privs",
198 permissions=[wa, wr, ma, mr])
199 role.create(name="Admin", description="An admin user, full privs",
200 permissions=[aa])
201 ro = role.create(name="No Rego", description="A user who can't register",
202 permissions=[wa, ma])
204 in init():
206 r = db.getclass('role').lookup('Admin')
207 user.create(username="admin", password=Password(adminpw),
208 address=instance_config.ADMIN_EMAIL, roles=[r])
210 # choose your anonymous user access permission here
211 #r = db.getclass('role').lookup('No Rego')
212 r = db.getclass('role').lookup('User')
213 user.create(username="anonymous", roles=[r])
216 Authentication of Users
217 -----------------------
219 Users must be authenticated correctly for the above controls to work. This is
220 not done in the current mail gateway at all. Use of digital signing of
221 messages could alleviate this problem.
223 The exact mechanism of registering the digital signature should be flexible,
224 with perhaps a level of trust. Users who supply their signature through their
225 first message into the tracker should be at a lower level of trust to those
226 who supply their signature to an admin for submission to their user details.
229 Action
230 ======
232 The CGI interface must be changed to:
234 - authenticate over a secure connection
235 - use unique tokens as a result of authentication, rather than pass the user's
236 real credentials (username/password) around for each request (this means
237 sessions :)
238 - use the new logical control mechanisms
240 The mail gateway must be changed to:
242 - use digital signatures
243 - use the new logical control mechanisms
245 The command-line tool must be changed to:
247 - use the new logical control mechanisms (only allowing write
248 access by admin users, and read-only by everyone else)
251 Use cases
252 =========
254 public
255 end users that can submit bugs, request new features, request support
256 developer
257 developers that can fix bugs, implement new features provide support
258 manager
259 approvers/managers that can approve new features and signoff bug fixes
260 admin
261 administrators that can add users and set user's roles
262 system
263 automated request handlers running various report/escalation scripts
264 privacy
265 issues that are only visible to some users