openSUSE:Build Service Concept ACL
A new draft proposal for supporting project and package wide access control via Access Control Lists.
- 1 Scope
- 2 Usecases, Functions
- 2.1 Usecases
- 2.2 Project owner's view
- 2.3 Functions
- 3 Architecture and implementation
- 3.1 Introduction
- 3.2 Details
- 3.3 Constraints
- 4 Status
- 5 Testing
- 6 Examples
Access control is a means to provide filesystem like access permissions on OBS object access. Currently, only basic access control is performed in OBS: once you have logged into OBS, you can read all data in an OBS system. Write access is controlled via specific users roles. With the Implementation of access control, this situation changes. All operations inside OBS on objects like files, meta data and other objects are then subject to access control checks that are coded in so called access control lists, ACLs. This implementation bases access control on the group, role and permission system of OBS 2.0.
The use cases section might look outdated in some parts. The initial proposal was to base ACL on attributes which correspond to an object which is protected. The current implementation is based on the group and role management of OBS.
Complete anonymous read access
OBS server instance where we want people to have read access without creating a login
- Allow read access to whole build service anonymously
- It should be possible to configure this in any OBS instance without special global option
Combined read/write Access
Use case A: Company setup where users should only see their own projects but not others
Use case B: Public server with access for closed source or prerelease software that should not be publically seen
- Coupling of read access to write access
- Every logged in user has read access only to those packages/projects that he has write access to.
- Question: Access setup per project - or full server?
There should be a global rule and than specific rules, based on the user roles in the specific projects. This is how the rest of permissions is implemented and we should not go away from this without reason.
Each project can than define additional roles (and therefor rights), for example for reading for specific users or groups.
So, we can for example disallow reading by default, but introduce a "reader" role for example. Similar to maintainer or downloader. If you add user or groups to projects or packages they will get the rights there. If you add it to master name spaces (eg openSUSE project) this is also valid for openSUSE:Tools project for example.
Of course in this specific case it is not enough to implement it in the api, it must be also support in the backend. or we just disallow to use source links, aggregates, kiwi builds and repository reusages in general on such instances.
Separate read/write access
Add separate read access that can be granted to projects and packages in addition to write access
Fine granular ACLs
Currently write access is to full project/package. Enhance it to make it fine granular to control:
- write access to packages
- write access to meta data (description, granting rights)
- rights to add (top-level) projects
- rights to delete projects
- rights to add new packages
- rights to delete packages
This could either be implemented as ACLs or with different roles and people would get roles for a project or for the whole build service (similar to wordpress that has Admin, Editor, Author, Subscriber)
Wordpress analogy with ACL
- download-only - end-user, enabled if released / pendant to publish - downloader
- anonymous view - browse service (could be default, if no other rights set), but no download - viewer
- read access - able to read (and branch ?) packages - subscriber
- write access - able to write to a prj/pkg - author
- write access to requests/meta - able to accept requests/change meta +add/delete pkg - editor/reviewer
- full access to prj/pkg - all of above + attributes - admin
Inheritance down the project path with revoke on per-subprj/package basis ? E.g. don't write to released/stable, but elsewhere inherit prj ACL.
JanSimon: The Wordpress analogy makes sense to some extend. I have these rights and groups (of rights) in mind:
JanSimon: I see an issue as soon as branching/linking is allowed - either we inherit some restrictions in the branched package, or a branch will then be a possibility to break the acl. Or a branch/link gets only "maintainer" role and inherits owner and acl from original pkg. Thus acl would be preserved and the user can work on the fixes and submit to original pkg.
Currently we have only single users and give them access, it might make sense to define groups of users and give those the same rights.
Project owner's view
Some thoughts on what closed projects may need.
All project types restrict write access. The closed project type restricts read access to source only; the secret/confidential project types restrict read access to source and binaries.
Project is open
This is a typical open source project.
- Project and packages appear in lists
- Only named people/groups can update the project and source
- Source is freely available
- Repositories for resulting packages are available
Project is closed
This kind of project protects the source but the binaries are fairly easily accessible.
- Project and packages appear in lists
- Only named people/groups see source from the project.
- Sources are ACLed
- Source doesn't leak out
- Binaries are available so leakage is not an issue.
- Repositories for resulting packages are available
Probably the most important additional requirement here is that the management of the source ACLs is simple in order to avoid accidental leakage. Eg it should be very hard (impossible?) to add a package/sub-project and accidentally make the source world-readable.
When packages from within a 'closed' project are copied elsewhere, they should default to retaining their closed permissions.
Project is confidential
This kind of project is closed but visible. Only authorised users can access source and binaries. Certain other projects can use the binaries.
- Project and packages appear in lists and build queues
- Only named people/groups see source from the project
- Sources are ACLed
- Binaries are ACLed
- Source and Binaries don't leak out
- Repositories for resulting packages are ACL protected
- Project can be used by specific projects for building 
 same toplevel namespace or this may means that projects act like userids and have permissions.
Project is secret
This kind of project is totally closed. For non-authorised users the only visibility should be unidentifiable resource usage. Very similar to confidential.
- Only named people/groups see any information about the project.
- When the project is building it shows <private> instead of any project data
- Source doesn't leak out
- Binaries don't leak out
- Protected repositories for resulting packages
- Project can't be used by other projects for building
Architecture and implementation
ACL sits on top of two features introduced with OBS 2.0: Role and Permission Management as well as freely definable user groups. ACL uses 4 specifically defined permissions ‘source_access’, ‘private_view’, ‘download_binaries’, ‘access’. Also, the preexisting roles “maintainer”, “reader” and “downloader” had been modified with specific predifined permissions (which can at any time changed with the role and permission editor dynamically). And last but not least 4 new flags ‘sourceaccess’, ‘binarydownload’, ‘privacy’ and ‘access’ had been added to the project and package descriptions to signal that some information is only readable by specific users or groups, or that information is hidden.
How do I use ACL
There are 4 steps to use ACL (a part of them a optional and can only be performed by the Administator of an OBS instance). Step one is to assign the listed permissions to a role, user or group (this step can be done only by the admin, and is not needed for the predefined roles “maintainer”, “reader” and “downloader”). Step two is to add a group for special users to projects which are intended to be run with ACL (this operations can only be performed by the admin). Step three is to protect a project with appropriate protection flags at project creation by adding them to the project meta. Step four is to add other users or groups with one of the new predefined roles that has ACL permissions added to the project meta.
What information can be protected by ACL
The protected information is grouped into 4 categories. Category 1 (flag ‘sourceaccess’) is source code. Category 2 (flag ‘binarydownload’) is binary packages or logfiles or builds. Category 3 (flag ‘privacy’) is project or package information like build status. Category 4 (flag ‘access’) is all viewable or accessable information to any project or package (full blocking of all access and information).
The wiring between permissions and roles takes place in the role editor of the OBS admin interface. The Admin can dynamically assign permissions to roles, create new roles and assign users to groups and assign users or groups to roles. All API calls of OBS have been instrumented for ACL access (which means the list in src/api/config/routes.rb) that handle objects which are under access control. Those are particularily, but not limited to, all listing operations and all file access operations.
Correspondence of Permissions and Flags
There is a 1:1 correspondance between granting an access permissions and the access flag. It is carried out by the operation: if an access flag is set and the user has either directly got the permission granted or he got a role assigned which got the permission granted or he is part of a group which gets the permission granted via role or direct permission assignment, then he can access the protected object.
The source path of the OBS is any exiting method to access source files. These methods are:
1. _link 2. "link" directives in a project 3. published build repositories with source packages 4. API calls with 'source/' prefix 5. access to source via OBS Interconnect (special of 4.)
Be cautious that the end result of files can be a combination of a list of links with diff that have to be followed up to the final object. The end result gets expanded.
The binary path of the OBS is any exiting method to access build results. These methods are:
1. _aggregate 2. "path repository" directives in a project 3. Imaging Descriptions - KIWI descriptions, product definitions 4. published build repositories with binary packages 5. API calls with 'build/' prefix 6. access to binary packages via OBS Interconnect (special of 5.)
Be cautious that kiwi and product files can also be linked line of _link files with possible diff file or via project links.
Comment on the API calls protections: if an API call comes in, the pattern matching the call is applied top down. So if there is an "O." case, this is applied when no other case matches.
Overview on permissions (related to acl):
download_binaries - This permission is related to the binarydownload flag source_access - This permission is related to the sourceaccess flag private_view - This permission is related to the privacy flag access - This permission is related to the access flag
Overview on flags (related to acl):
privacy - project looks like binary-only project. no packages visible, but available as build target sourceaccess - sources inside the package files are not available binarydownload - built binaries are unavailable access - hides existence and access to a project and its packages (also jobs/workers invisible).
Overview on roles:
Admin - has the right to access all below reader - is a special role for getting sourceaccess reviewer - is special to review workflow, needs all permissions (privacy, sourceaccess, access) downloader - has binarydownload permission (does he need also privacy ?) maintainer - has by default permissions privacy, sourceaccess, access, binarydownload
Overview on users:
Admin - has the role Admin usually _nobody_ - user used for accessing the OBS interconnect authenticated user - can only use special permissions where one of the roles, usually maintainer in objects he owns
API Calls protected by privacy flag (API calls see src/api/config/routes.rb):
1. 'build/:project/_result' - lists buildresults of a project, in combinations 2. 'source/:project' - lists packages of a project, empty if user / group has no permission 3. 'public/source/:project' - lists packages, same as 2. but auth with "_nobody_", see also OBS interconnect O. Other index functions - not protected. Index functions list object names
API Calls protected by sourceaccess flag (API calls see src/api/config/routes.rb):
1. 'build/:project/:repository/:arch/:package/_log' - build log, if user / group has no access, 403 is returned 2. 'source/:project/:package/:file' - source file, if user / group has no access, 403 is returned 3. 'source/:project/:package' - source file list, if user / group has no access, 403 is returned 4. 'source/:project' - project list, if user / group has no access, 403 is returned A1. OBS interconnect - rerouted, using auth of "_nobody_" A2. Files of 1. with access granted - special checking rules applied see below O. Other index function - not protected. Index functions lists object names
API Calls protected by binarydownload flag (API calls see src/api/config/routes.rb):
1. 'build/:project/:repository/:arch/:package/_log' - build log, if user / group has no access, 403 is returned 2. 'build/:project/:repository/:arch/:package/:filename' - binary package, if user / group has no access, 403 is returned 3. 'published/:project/:repository/:arch/:filename' - binary package, if user / group has no access, 403 is returned A1. OBS interconnect - rerouted, using auth of "_nobody_" O. Other index function - not protected. Index functions lists object names
API Calls protected by access flag (API calls see src/api/config/routes.rb):
1. Any Index function - hides access protected objects 2. Any Access function - protects objects with 404 - object not found A1. OBS interconnect - rerouted to 1. or 2., using auth of "_nobody_" A2. Files of 2. with access granted - special checking rules applied see below O. Other index or access function - should not be applicable, must be covered by 1. or 2.
Table covering actions vs. roles (document user-visible actions):
|Action vs. role||_anonymous_||authenticated, but uninvolved user||reviewer (special for review workflow)||downloader||maintainer||admin|
|viewing packages in project (privacy flag)||no||no||yes||yes||yes||yes|
Table covering actions vs. permission flags (document actions on api):
|Action vs. permission||none||privacy||binarydownload||sourceaccess||access|
|build_controller/get result (privacy flag)||no||yes||no||no||no|
This section contains undocumented, sparsely documented, or obvious, but existing behavior of the current OBS and underlying build process (debian and rpm) that cannot be changed because it is inherently used. One issue documented by constraints is "backwards compatibility".
The implementation of ACL was done by keeping full compatibility to the status of OBS that was present in OBS 2.0. That means the osc command line client as well as the WebUI 1.9 and WebUI 2.x had to work more or less out of the box.
Specifically the flag "access", which also hides a project in every possible place is treated for the users that have no access to it as non existing.
The OBS interconnect can currently be used without authentication, thus the approach has been chosen to treat all these accesses as if they were beeing done be the user "_nobody_". Since this user can be modified in its roles and permissions, the safety of the OBS interconnect can be changed by the Admin dynamically.
Source RPM Handling and Publishing
Currently, there is a safety belt that prohibits any source packages from beeing put to the pool of build results for protected projects. The reason for this is that _aggregates would allow you effectively to access the sources of a project when only binary access is grated. Another reason is that the source packages get also published to the publisher repository.
This solution is subject to change in a later revision.
Publishing is currently not protected by any access control. Maintainers are advised to switch off publishing for protected projects. Reason is a missing interface for authorization of the downstream chain for OBS.
This solution is subject to change in a later revision.
Special Safety Checks
There is are special security checks inside to prohibit the user from unvoluntarily opening a project or package which is protected by ACL. That means that references of type:
1. links / aggregates - files with the name "_link" or "_aggregate" 2. Imaging Descriptions - KIWI descriptions, product definitions 3. project meta - Tags with "link project" or "path repository" directives
are special cases to be treated. Since they can themselves contain data referencing to a repository or project or package, they are checked against the following security violations:
1. A link points from an unprotected object to a protected object 2. The user has no access to the position where the references points to
Of course can there be chains of these objects, e.g. link to link to project or product to link to project.
Last but not least, only the Admin is allowed to raise the permission level of an existing and unprotected project to a protected level. The reason for this is that the project or package build results could have already been published or the project or package could have already been used by any reference as listed above.
This is subject to change in a later revision and is likely to be replaced by a dynamic and flexible solution.
Updating from an old Release
Updating a complex installation, specifically from 2.0, can result in a number of changes to be carried out by hand. The reason is that with OBS permissions and group / role management has been introduced.
That means an Admin should cross check the permission assignments for roles that are created or that will be created.
Linking and Branching
In case of a branch project is created, it inherits the permissions of the project where it is branched from, when a fresh project is created.
In case of existing projects where a branch or link is created, see above on the rules that are checked for safety.
The current status is that the complete API of the OBS git master had been instrumented with ACL code, critical portions of the API controllers had been code inspected and a big portion of these API calls now have a testcase in the OBS testsuite. Work is ongoing to make ACL as secure as possible. The complete API is now instrumented to hide all information for the "access" flag, and the source and binary path are protected by the flags "sourceaccess", "binarydownload" and "access". Code drops of current git master are under test in some bigger OBS systems, most notably the openSUSE Buildsystem, because you can publicly access it. You can find snapshots of this codebase as usual in the OBS project openSUSE:Tools:Unstable.
For OBS 2.1
Due to the review status of 2.1, "access" will only be available via a patch. Users can try out this new feature. To not mislead users, because the binary path of OBS is not completely secured for 2.1, the option to deactivate it has been choosen. Still flags binarydownload, sourceaccess, privacy, access are implemented.
1. after security review, "access" is switched off, can be used by a patch 2. the source path (access to sources in packages) has been reviewed
List of Security Warnings for OBS 2.1
OBS Release 2.1 Beta 1 and later have deactivated the flags "privacy" and "access" for security reasons. That is not because they do not work nor because they do make the system less secure, but because the existence should not put you as an Admin or User in false security.
There is a patch available to reenable those two flags, with the security warnings:
- In case of KIWI and Product builds are enabled, you can access the binary path of protected projects
- Single package binary protection does not work correctly because currently OBS does not know about binary packages as a separate object
- In case of you raise the security level of an unprotected project to protected as an Admin, existing "links" (any of the above listed possibilities) to this project do not get cut
- The publishing repositories of OBS are currently not separately protected. If you do not switch off publishing, and do not filter published repositories before they go to your webserver, you publish the binary packages of your protected projects
- Project hiding via "access" does not 100% work yet. It might be possible to guess project or package or other object names via tricky API calls. Anyway, activating "access" should stop any API from explicitely listing any hidden object
- It is not clear if the request controller can give you information about hidden objects protected via "access"
- If the WebUI is run with caching enabled, it might be possible that hidden information is exposed. We want to fix this issue when coming up during 2.1 Release line
- The OBS interconnect is running with user "_nobody_" when accessing ACL protected objects. Should this not be secure enough, the Admin should change the permission / role / group settings of "_nobody_"
- Migrating to OBS 2.1 does not change any already changed or added groups, roles or permissions to not confuse the Admin. Be careful to set permissions and roles for users and groups appropriate
This section gets amended in case of we find new issues not yet listed. Also, we try to fix any new issue with new 2.1.x releases in case this can be done with appropriate effort.
For OBS 2.2
The list below is currently a TODO list for 2.2. The goal of this release is to have all flags binarydownload, sourceaccess, privacy, access are implemented, reviewed and active.
1. hiding of objects improvement by: 1a. uniform error messages / refactoring ACL code 1b. correct instrumenting of all put methods 2. all remaining uninstrumented API have to be instrumented for ACL 3. remaining holes in the binary path have to be closed 4. the binary path has to be reviewed for security issues 5. testsuite has to be further enhanced 6. review WebUI caching code. Which caches across the users 7. clarify how to deal with notification of hidden content OI. fix any popping up security issues
This includes specifically, from above list, items:
- check the request controller for hiding - "_link + patches" mode - run testsuite also with .kiwi and .product files
List of Security Warnings for OBS 2.2
Adrian Schröter updates these "Alpha Snapshots" relatively often, on a 1-2 weekly basis, and runs the testsuite on git master daily. The testsuite is very easily configured, see link below, such that all maintainers of OBS are advised to run the tests before any git commit. This had been introduced after the OBS 2.0 branch, and has considerably reduced malformed code changes. Thanks to Jan-Simon Möller for putting in many of the testcases into the testsuite for the ACL checks. On OBS Testing in general, read also Development and Test.
The examples below are to explain where ACL can directly or indirectly be involved. The rules that apply are described above in the implementation details.
Example Project Meta using ACL flags and roles
This is a fantasy project meta file, which contains user, group, ACL flags as well as the two checked reference cases using <link project=" and <path project=" directives that are checked against protection violations.
<user userid="MartinMohring" role="maintainer" /> <!-- grant user full write and read access --> <group groupid="MeeGo-Reviewer" role="maintainer" /> <!-- grant group full write and read access --> <group groupid="MeeGo-Developers" role="reader" /> <!-- grant group full source read access --> <group groupid="MeeGo-BetaTesters" role="downloader" /> <!-- grant group access to packages/images --> <sourceaccess> <disable/> </sourceaccess> <!-- disable read access - unless granted explictely. This flag will not accept arch or repository arguments. --> <binarydownload> <disable/> </binarydownload> <!-- disable access - unless granted explictely - to packages/image and logfiles --> <access> <disable/> </access> <!-- disable access - unless granted explictely-, project will not visible or found via search, nor will any source or binary or logfile be accessable. This flag will not accept arch or repository arguments. --> <privacy> <disable/> </privacy> <!-- project will not visible or found via search. This flag will not accept arch or repository arguments. --> <link project="openSUSE:Tools"/> <repository name="openSUSE_11.2"> <path repository="standard" project="openSUSE:11.2"/> <arch>i586</arch> <arch>x86_64</arch> </repository>
Example Product Definition using repos which need ACL checks
Below you find the beginning of a Product Defintion. The <repository path="obs:// directives are part of an ACL access check, as well as other files referenced by <xi:include href=
<?xml version="1.0" encoding="UTF-8"?> <productdefinition xmlns:xi="http://www.w3.org/2001/XInclude"> <products> <product id="OBS-Addon-Factory"> <vendor>openSUSE</vendor> <name>OBS-Addon-Factory</name> <version>2.0.0</version> <release>0</release> <summary>openSUSE Build Service Add on for Factory</summary> <description>This Addon can be installed on current openSUSE Factory installations. It provides a full Build Service server instance. </description> <buildconfig> <producttheme>openSUSE</producttheme> </buildconfig> <installconfig> <datadir>suse</datadir> <descriptiondir>suse/setup/descr</descriptiondir> <distribution>OBS-Addon-Factory</distribution> </installconfig> <runtimeconfig/> </product> </products> <repositories> <repository path="obs://openSUSE:Tools/openSUSE_Factory"/> <repository path="obs://openSUSE:Factory/standard"/> </repositories> <xi:include href="archsets.inc" />
Example KIWI File using repos which need ACL checks
Below you find the beginning of a KIWI file. The <source path="obs:// directives are part of an ACL access check.
<?xml version="1.0"?> <image schemeversion="3.7" name="buildhost-opensuse-11.1"> <description type="system"> <author>Adrian Schroeter</author> <contact>firstname.lastname@example.org</contact> <specification>openSUSE buildhost system</specification> </description> <profiles> <profile name="xen" description="Boot with xen kernel/mboot.c32"/> </profiles> <preferences> <type compressed="true" primary="true" filesystem="ext3" boot="netboot/suse-11.1" bootprofile="xen">pxe</type> <version>1.4.0</version> <size unit="M">687</size> <packagemanager>zypper</packagemanager> <rpm-check-signatures>False</rpm-check-signatures> </preferences> <drivers type="drivers"> <file name="drivers/ide/*"/> <file name="drivers/block/loop.ko"/> <file name="fs/ext4/*"/> <file name="fs/ext3/*"/> <file name="fs/ext2/*"/> <file name="fs/binfmt_aout.ko"/> <file name="fs/binfmt_misc.ko"/> <file name="fs/mbcache.ko"/> <file name="fs/quota_v1.ko"/> <file name="fs/quota_v2.ko"/> <file name="fs/jbd/*"/> <file name="drivers/xen/*"/> <file name="drivers/ata/*"/> <file name="drivers/acpi/dock.ko"/> </drivers> <repository type="rpm-md" priority="1"> <source path="obs://openSUSE:Tools/openSUSE_11.1"/> </repository> <repository type="rpm-md" priority="2"> <source path="obs://openSUSE:11.1:Update/standard"/> </repository> <repository type="rpm-md" priority="3"> <source path="obs://openSUSE:11.1/standard"/> </repository>