Scenario 1 : Small In-house Development Team

Background

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:
Scenario1Overview.jpg

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:

 1<project name="WinApp1-QA">
 2  <workingDirectory>C:\Build\WinApp1-QA</workingDirectory>
 3  <artifactDirectory>C:\Build\WinApp1-QA\Deploy</artifactDirectory>
 4  <webURL>http://localhost/server/local/project/WinApp1-QA/ViewProjectReport.aspx</webURL>
 5  <!-- Source control block defined here -->
 6  <triggers>
 7    <intervalTrigger buildCondition="IfModificationExists" seconds="300"/>
 8  </triggers>
 9  <tasks>
10    <!-- Tasks defined here -->
11  </tasks>
12  <publishers>
13    <!-- Publishers defined here -->
14  </publishers>
15</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 the security will be defined internally, I'm going to use the internal security definition:

 1<cruisecontrol>
 2  <internalSecurity>
 3    <users>
 4    </users>
 5    <permissions>
 6    </permissions>
 7  </internalSecurity>
 8  <!-- Projects defined here -->
 9</cruisecontrol>

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:

 1<cruisecontrol>
 2  <internalSecurity>
 3    <users>
 4    </users>
 5    <permissions>
 6      <!-- Roles -->
 7      <rolePermission name="Testers" forceBuild="Allow" defaultRight="Deny"/>
 8      <rolePermission name="Releasers" forceBuild="Allow" defaultRight="Deny"/>
 9    </permissions>
10  </internalSecurity>
11  <!-- Projects defined here -->
12</cruisecontrol>

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:

 1<cruisecontrol>
 2  <internalSecurity>
 3    <users>
 4      <!-- Authenticated users -->
 5      <passwordUser name="bob" display="Bob (Team Lead)" password="bob1"/>
 6      <passwordUser name="jane" display="Jane (BA)" password="jane2"/>
 7      <passwordUser name="john" display="John (QA)" password="john3"/>
 8      <passwordUser name="joe" display="Joe (QA)" password="joe4"/>
 9    </users>
10    <permissions>
11      <!-- Roles -->
12      <rolePermission name="Testers" forceBuild="Allow" defaultRight="Deny"/>
13      <rolePermission name="Releasers" forceBuild="Allow" defaultRight="Deny"/>
14    </permissions>
15  </internalSecurity>
16  <!-- Projects defined here -->
17</cruisecontrol>

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

 1<cruisecontrol>
 2  <internalSecurity>
 3    <users>
 4      <!-- Omitted for brevity -->
 5    </users>
 6    <permissions>
 7      <!-- Roles -->
 8      <rolePermission name="Testers" forceBuild="Allow" defaultRight="Deny">
 9        <users>
10          <userName name="john"/>
11          <userName name="joe"/>
12        </users>
13      </rolePermission>
14      <rolePermission name="Releasers" forceBuild="Allow" defaultRight="Deny">
15        <users>
16          <userName name="bob"/>
17          <userName name="jane"/>
18        </users>
19      </rolePermission>
20    </permissions>
21  </internalSecurity>
22  <!-- Projects defined here -->
23</cruisecontrol>

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

 1<cruisecontrol>
 2  <internalSecurity>
 3    <users>
 4      <!-- Authenticated users -->
 5      <passwordUser name="bob" display="Bob (Team Lead)" password="bob1"/>
 6      <passwordUser name="jane" display="Jane (BA)" password="jane2"/>
 7      <passwordUser name="john" display="John (QA)" password="john3"/>
 8      <passwordUser name="joe" display="Joe (QA)" password="joe4"/>
 9      <!-- Generic role -->
10      <simpleUser name="*"/>
11    </users>
12    <permissions>
13      <!-- Roles -->
14      <rolePermission name="Testers" forceBuild="Allow" defaultRight="Deny">
15        <users>
16          <userName name="john"/>
17          <userName name="joe"/>
18        </users>
19      </rolePermission>
20      <rolePermission name="Releasers" forceBuild="Allow" defaultRight="Deny">
21        <users>
22          <userName name="bob"/>
23          <userName name="jane"/>
24        </users>
25      </rolePermission>
26    </permissions>
27  </internalSecurity>
28  <!-- Projects defined here -->
29</cruisecontrol>

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:
CCTrayConfiguration.jpg

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>:

1<securityPlugins>
2  <simpleSecurity/>
3</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:

1<project name="WinApp1-QA">
2  <!-- Omitted for brevity -->
3  <security type="defaultProjectSecurity" defaultRight="Deny"/>
4</project>

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 permissions:

 1<project name="WinApp1-QA">
 2  <!-- Omitted for brevity -->
 3  <security type="defaultProjectSecurity" defaultRight="Deny">
 4    <permissions>
 5      <!-- Grant permissions to this project -->
 6      <rolePermission name="Testers" ref="Testers"/>
 7      <rolePermission name="Releasers" ref="Releasers"/>
 8    </permissions>
 9  </security>
10</project>

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.
Here is the full configuration for the example. I have omitted the duplicate projects since this scenario is focusing on the security:

 1<cruisecontrol>
 2  <internalSecurity>
 3    <users>
 4      <!-- Authenticated users -->
 5      <passwordUser name="bob" display="Bob (Team Lead)" password="bob1"/>
 6      <passwordUser name="jane" display="Jane (BA)" password="jane2"/>
 7      <passwordUser name="john" display="John (QA)" password="john3"/>
 8      <passwordUser name="joe" display="Joe (QA)" password="joe4"/>
 9      <!-- Generic role -->
10      <simpleUser name="*"/>
11    </users>
12    <permissions>
13      <!-- Roles -->
14      <rolePermission name="Testers" forceBuild="Allow" defaultRight="Deny">
15        <users>
16          <userName name="john"/>
17          <userName name="joe"/>
18        </users>
19      </rolePermission>
20      <rolePermission name="Releasers" forceBuild="Allow" defaultRight="Deny">
21        <users>
22          <userName name="bob"/>
23          <userName name="jane"/>
24        </users>
25      </rolePermission>
26    </permissions>
27  </internalSecurity>
28  <project name="WinApp1-QA">
29    <workingDirectory>C:\Build\WinApp1-QA</workingDirectory>
30    <artifactDirectory>C:\Build\WinApp1-QA\Deploy</artifactDirectory>
31    <webURL>http://localhost/server/local/project/WinApp1-QA/ViewProjectReport.aspx</webURL>
32    <!-- Source control block defined here -->
33    <triggers>
34      <intervalTrigger buildCondition="IfModificationExists" seconds="300"/>
35    </triggers>
36    <tasks>
37      <!-- Tasks defined here -->
38    </tasks>
39    <publishers>
40      <!-- Publishers defined here -->
41      <xmllogger/>
42    </publishers>
43    <security type="defaultProjectSecurity" defaultRight="Deny">
44      <permissions>
45        <!-- Grant permissions to this project -->
46        <rolePermission name="Testers" ref="Testers"/>
47        <rolePermission name="Releasers" ref="Releasers"/>
48      </permissions>
49    </security>
50  </project>
51  <!-- Other projects defined here -->
52</cruisecontrol>

Credits

This scenario was originally posted on Automated Coder

Scenario1Overview.jpg - Scenario1Overview.jpg (41.5 kB) Ruben Willems, 10/01/2011 04:24 pm

CCTrayConfiguration.jpg - CCTrayConfiguration.jpg (16 kB) Ruben Willems, 10/01/2011 04:25 pm