Automated Coder

Exploring the Code of CruiseControl.Net

Security Scenario 1: Small Team

Posted by Craig Sutherland on 10 January, 2009

!!Update!!

Since this post security has been modified slightly. Please see this post for further details.

Welcome to Security

As I promised previously, here is the first in the set of tutorials on security. In this scenario I’ll look at setting up security for a small, fictitious team.

The company is Acme Insurance, the company that provides development insurance for software houses. Bob leads a team of six people – three developers, a business analyst (BA) and a couple of testers. The systems they develop are in-house systems for the company – and consists of a couple of Windows applications plus an internal intranet web application.

Bob wants to secure their installation of CruiseControl.Net so he knows what is happening and to limit access to certain projects.

The Build Setup

Each application (two windows apps, plus one web app) has three projects in CruiseControl.Net. Additionally there are a few smaller projects for common libraries – which are used by the main applications – bringing the total number of projects to twelve.

Each application, plus the libraries, have a simple compile-and-test build project. This projects ensures that the code builds, the local unit tests run and the successful outputs are copied to a central “store” for the executables. These are triggered on an interval basis (when code is checked in) or via a force build.

The applications also have two deploy projects each – deploy to QA and deploy to PROD. These generate “production” builds, copy all the executables and related files into deployment packages and copy them to the staging area. Additionally the web application is automatically deployed to either the QA or pre-PROD servers. The QA versions run overnight, the PROD versions must be manually triggered.

So despite this being a small team, there are still a fair number of projects, plus some can potentially screw up processes (either QA or PROD).

The Goals

The twelve projects can be divided into three security zones: low, medium and high. The following table helps to define these three zones:

Zone Description Projects People
Low Projects that everybody can access Compile-and-test projects (six) Everybody
Medium Projects that need to limit access Deploy to QA projects (three) Team lead, BA and testers
High Projects that can affect production Deploy to PROD projects (three) Team lead and BA

For low security, they don’t really care what happens to the projects – it is the entire responsibility of the team. While this can still lead to an abuse of trust, the consequences would be reasonably minor.

As the security needs increase, the consequences of someone screwing things up (either deliberately or by accident) increases. Damaging the QA environment could lead to a loss of one or more days work by the testers and the BA – not serious consequences but potentially a large waste of time and resources. Damaging PROD would lead to a serious waste of time, plus potentially damage the company’s client-relationships.

The Plan

With these goals in mind, this gives two actual levels of security. The first level is unsecured – anyone can do anything to the projects and there is no real need to audit anything. This is very similar to how CC.Net currently works.

The security level limits who can access and modify projects in CC.Net. Within this level there are two groups – testers and releasers. Membership to the testers group allows full access to the deploy to QA projects, while the releasers group allows access to all deployment projects.

This definition gives a very simple design – two roles with two users in each. Six projects need security, while the other six do not. Since the users need to be secured they will use passwords (to ensure the other people don’t “use” their user name). Finally, all deployments will be audited to assess the effectiveness of security in the long run.

The following diagram shows how I’m going to implement the security:

Tutorial 1-1

The Configuration

Since I’m looking at the security, not the actual projects, I’m going to use the following general configuration for each project:

<project name=”WinApp1-Build”>
<workingDirectory>C:\Build\WinApp1-Build</workingDirectory>
<artifactDirectory>C:\Build\WinApp1-Build\Deploy</artifactDirectory>
<webURL>http://localhost/server/local/project/WinApp1-Build/ViewProjectReport.aspx</webURL>
<triggers>
<intervalTrigger buildCondition=”IfModificationExists” seconds=”300″/>
</triggers>
<publishers>
<xmllogger/>
</publishers>
</project>

WinApp1 will be changed to the different project names. There are twelve projects in total – their names roughly match the names above (the arrows are changed to dashes). With this background, I can now begin to configure the security.

Turning On Security

First, I’m going to turn on security for the server. This involves adding a security block to the config file. Since there is only one security type defined so far, I’ve added a sessionSecurity element (this can be added anywhere within the config, as long as it is directly under the cruisecontrol element – i.e. it cannot be in a project or queue element). For the moment, I’ll leave it with the default settings.

Running this config through the validator, I see that the security element needs an assertions element and a setting element, so I’ve added some blank instances of these. Now the config file passes validation and security has been turned on for the server. But, all this has done is completely lock down the server, so no one can do anything!

Adding Some Roles and Users

So the next thing to do is to add the users and roles. First, I’ve added the two roles – “Testers” and “Releasers”. These are defined as follows:

<settings>
<roleAssertion name=”Testers” forceBuild=”Allow” defaultRight=”Deny”/>
<roleAssertion name=”Releasers” forceBuild=”Allow” defaultRight=”Deny”/>
</settings>

Each of the roles has force build rights only, all other rights are still denied. Before I can add some people to the roles, I first need to add the users to the security. So I’m going to add four users, each with their own password (which are hard-coded for the moment).

So, now the security settings looks like this:

<settings>
<roleAssertion name=”Testers” forceBuild=”Allow” defaultRight=”Deny”/>
<roleAssertion name=”Releasers” forceBuild=”Allow” defaultRight=”Deny”/>
<passwordUser name=”bob” display=”Bob (Team Lead)” password=”bob1″/>
<passwordUser name=”jane” display=”Jane (BA)” password=”jane2″/>
<passwordUser name=”john” display=”John (QA)” password=”john3″/>
<passwordUser name=”joe” display=”Joe (QA)” password=”joe4″/>
</settings>

Next step is to add the users to the roles, so now the roles look like this:

<roleAssertion name=”Testers” forceBuild=”Allow” defaultRight=”Deny”>
<users>
<userName name=”john”/>
<userName name=”joe”/>
</users>
</roleAssertion>
<roleAssertion name=”Releasers” forceBuild=”Allow” defaultRight=”Deny”>
<users>
<userName name=”bob”/>
<userName name=”jane”/>
</users>
</roleAssertion>

Finally, I added a generic role for all the other uses:

<simpleUser name=”*”/>

This now gives me the roles and users. But, until CCTray and the dashboard are configured, they still can’t do anything!

Configuring the Clients

Configuring CCTray is done on the client-side. The user needs to go to settings, click on the Build Projects tab, and then click on “Add…”. This will open up the list of servers – from here the user clicks on the server to modify and then clicks on “Configure”. This will finally open up the security configuration:

Security Configuration

Here the user will need to check the “Server is secure” checkbox and then choose the authentication mode. Once they have done this they need to click on the “Configure” button and enter their credentials. Finally click on “Ok” all the way back to the main screen and security is now configured for CCTray.

Configuring the dashboard needs to be done at the server level instead. This involves opening dashboard.config and adding the following section underneath <plugins>:

<securityPlugins>
<simpleSecurity/>
</securityPlugins>

This adds a login section to the site, which allows the person to login with their username only. People with password secured accounts will fail to login. For this scenario this mode is fine for most people – the people in the other roles will need to use CCTray.

Now people can login and perform force builds, etc. However, the problem is everyone can force build any project! The next step is to configure the projects.

Locking Down Projects

For the projects that are in the low security zone, there is no need to change the configuration. These will continue to work as-is.

For the remaining projects, I need to lock them down. This is done by adding a <security> element to the project element. At the moment there is only one type of security – defaultProjectSecurity. So to start with I added the following XML to the project element:

<security type=”defaultProjectSecurity” defaultRight=”Deny”/>

The defaultRight attribute is optional, but this changes the default permission so no-one can do anything on it. Of course, this isn’t much use, so it’s time to add in the assertions:

<security type=”defaultProjectSecurity” defaultRight=”Deny”>
<assertions>
<roleAssertion name=”Testers” ref=”Testers”/>
<roleAssertion name=”Releasers” ref=”Releasers”/>
</assertions>
</security>

This is the definition for a medium security zone project, the high security zone is similar, but without the Testers role in it.

And that’s it! Security has now been configured for this scenario.

Some Comments

While this security setup does work, I found a few issues along the way.

First, because the dashboard plug-in only supports one authentication method I couldn’t configure the security plug-ins in the dashboard. Therefore I’ve turned them off in my dashboard configuration for this scenario (otherwise people would be confused).

Second, security is very open by default. While this was intentional, it does mean the onus is placed on the administrator to lock everything down.

Third, passwords are stored openly in the configuration, and people have no way of changing them. This is similar to the basic approach that Subversion uses, but it would be nice to make it a little more secure.

Complete Configuration

For those who want to see my complete configuration, I have added them to my storage site:

Feel free to send me any suggestions for improvements or ideas on how to clarify these scenarios.

5 Responses to “Security Scenario 1: Small Team”

  1. [...] Small Team [...]

  2. [...] is the second in a set of scenarios on security. In my previous scenario (here) I looked at a small team, this time I’ll look at a large [...]

  3. John said

    Sorry it appears my node references didn’t show.

    Point one should say have multiple sessionSecurity nodes and point two should say multiple securityGroup nodes within a since sessionSecurity node.

    • Craig Sutherland said

      Hi John,

      Thanks for the feedback – you’ve brought up a scenario I hadn’t thought about :-|

      I’ve spent a bit of time thinking about this (hence the slow response) and I think the best approach would be to make a new security manager that gets the users from an external file. This is something I’ve been thinking about for a while (mainly in light of password handling) but I’ll make sure it also covers your scenario as well.

      Craig

      Craig

  4. John said

    Hi,

    Firstly thanks for the CC.NET effort I am sure a lot of people will benefit from it.

    I do have a suggestion (not sure if it is an improvement or not…I’ll leave that for you to decide :D ):

    There are teams that share CC.NET instances. Now they can group their projects with a category (which you could filter the view for a category across servers but that is a point for another day) and they can have their own project configurations in an external xml file (and import them into the ccnet.config using xml entity includes). This security setup would mean they would have to share security settings shouldn’t be a problem but can be (e.g. they want to maintain their project/settings file under their own branch).

    Could we have the option of:

    1) Either having multiple nodes

    or

    2) Have the option of one or more nodes (which would have team/department specific assertion & settings child nodes) within a single node?

    Either sessionSecurity or securityGroup would have an id attribute to uniquely identify a team or department’s security setup. A team could then add an id attribute to the security node within their project(s). This allows teams to have this information in an external file that they control (possibly under source control or as part of their external project file) without the risk of clashing when it comes to group names etc.

    John

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>