Scenario 3: Open Source Project

Background

Petros has been working on an open source project called Midas for about a year now. This project is hosted on SourceForge, and he is the only administrator. However recently it's been getting some press and other people have volunteered to help, which he thinks is wonderful\!

He has convinced his work (a chemical conversion company) to host a CruiseControl.Net instance for the community to use. However, he doesn't want to allow everybody full access to the server. He is happy to let everybody view the current status, but he only wants to let approved developers force build. He doesn't want to let anybody stop or start the projects. Finally he wants to know who performs any release builds.

The Build Setup

Petros's build setup is really simple - there is only two projects in his config.

The first project is a CI build - it polls every five minutes and performs a build if any changes are detected. This does the standard compile, run unit tests and generate installer. The outputs are stored in a publically accessible location.

The second project is a releasing build. Again it does the compile, unit tests, etc, except this time in release mode. The outputs are then stored on his open source website and a release post is added to tell the world. This project must be manually forced.

The Goals

Since Petros has full access to the server and is the only person who needs access, there will be only one security zone.

This security zone will grant approved developers access to force or abort a build on the project. Currently security does not prevent viewing the reports, so this will not require configuration.

To keep things simple, all force builds will be audited.

The Plan

There will be only one security group - CanBuild. This group will have force build access to both projects, but no other access.

All developers who need force build rights will be manually added to this group.

The Configuration

The full configuration is as follows:

 1<cruisecontrol>
 2  <project name="Open_Source(Build)">
 3    <workingDirectory>C:\Build\OSB</workingDirectory>
 4    <artifactDirectory>C:\Build\OSB\Deploy</artifactDirectory>
 5    <webURL>http://localhost/server/local/project/LAS-Main/ViewProjectReport.aspx</webURL>
 6    <!-- Source control block defined here -->
 7    <triggers>
 8      <intervalTrigger buildCondition="IfModificationExists" seconds="300"/>
 9    </triggers>
10    <tasks>
11      <!-- Tasks defined here -->
12    </tasks>
13    <publishers>
14      <!-- Publishers defined here -->
15      <xmllogger/>
16    </publishers>
17  </project>
18  <project name="Open_Source(Deploy)">
19    <workingDirectory>C:\Build\OSD</workingDirectory>
20    <artifactDirectory>C:\Build\OSD\Deploy</artifactDirectory>
21    <webURL>http://localhost/server/local/project/LAS-Main/ViewProjectReport.aspx</webURL>
22    <!-- Source control block defined here -->
23    <triggers />
24    <tasks>
25      <!-- Tasks defined here -->
26    </tasks>
27    <publishers>
28      <!-- Publishers defined here -->
29      <xmllogger/>
30    </publishers>
31  </project>
32</cruisecontrol>

Again the first step is turning on security - just added the internalSecurity element, plus the users and permissions children.

Adding Some Roles and Users

Now the security has been added the next step is to add the users and the CanBuild security group. Since this is an open source project, Petros doesn't want to bother with much security. Therefore each person who is allowed to build has been added as a password user. At the moment, this is only Petros himself:

1<internalSecurity>
2  <users>
3      <passwordUser name="petros" password="whoareyou"/>
4  </users>
5  <permissions>
6  </permissions>
7</internalSecurity>

Note there is a domain in here - I've just changed it to localhost for this example. Without the domain the active directory authentication will fail as the authenticator won't know where to look.

I've also added a server-level permission for the high-security permissions:

 1<internalSecurity>
 2  <users>
 3      <passwordUser name="petros" password="whoareyou"/>
 4  </users>
 5  <permissions>
 6  <rolePermission name="all" defaultRight="Deny" forceBuild="Allow">
 7    <users>
 8      <userName name="petros"/>
 9    </users>
10  </rolePermission>
11</permissions>
12</internalSecurity>

I've also set the default right on the internal security element to Deny, so everyone else will be unable to do a force build.

Locking Down Projects

The final step for preventing force builds is to secure the projects. This is the same configuration as previous:

 1<project name="Open_Source(Build)">
 2  <workingDirectory>C:\Build\OSB</workingDirectory>
 3  <artifactDirectory>C:\Build\OSB\Deploy</artifactDirectory>
 4  <webURL>http://localhost/server/local/project/LAS-Main/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    <xmllogger/>
15  </publishers>
16  <security type="defaultProjectSecurity">
17    <permissions>
18      <rolePermission name="all" ref="all"/>
19    </permissions>
20  </security>
21</project>

This checks that the user is in the role, and if so the user can do a force build. All other permissions are denied at the server level.

Audit Logging

The final step once more is the auditing. Since this is very simple, I've just added the default audit logger block:

 1<internalSecurity>
 2  <audit>
 3    <xmlFileAudit/>
 4  </audit>
 5  <auditReader type="xmlFileAuditReader"/>
 6  <users>
 7    <!-- Omitted for brevity -->
 8  </users>
 9  <permissions>
10    <!-- Omitted for brevity -->
11  </permissions>
12</internalSecurity>

And that's the security settings for this scenario - the full example :

 1<cruisecontrol>
 2  <internalSecurity>
 3    <users>
 4      <passwordUser name="petros" password="whoareyou"/>
 5    </users>
 6    <permissions>
 7      <rolePermission name="all" defaultRight="Deny" forceBuild="Allow">
 8        <users>
 9          <userName name="petros"/>
10        </users>
11      </rolePermission>
12    </permissions>
13  </internalSecurity>
14  <project name="Open_Source(Build)">
15    <workingDirectory>C:\Build\OSB</workingDirectory>
16    <artifactDirectory>C:\Build\OSB\Deploy</artifactDirectory>
17    <webURL>http://localhost/server/local/project/LAS-Main/ViewProjectReport.aspx</webURL>
18    <!-- Source control block defined here -->
19    <triggers>
20      <intervalTrigger buildCondition="IfModificationExists" seconds="300"/>
21    </triggers>
22    <tasks>
23      <!-- Tasks defined here -->
24    </tasks>
25    <publishers>
26      <!-- Publishers defined here -->
27      <xmllogger/>
28    </publishers>
29    <security type="defaultProjectSecurity">
30      <permissions>
31        <rolePermission name="all" ref="all"/>
32      </permissions>
33    </security>
34  </project>
35  <project name="Open_Source(Deploy)">
36    <workingDirectory>C:\Build\OSD</workingDirectory>
37    <artifactDirectory>C:\Build\OSD\Deploy</artifactDirectory>
38    <webURL>http://localhost/server/local/project/LAS-Main/ViewProjectReport.aspx</webURL>
39    <!-- Source control block defined here -->
40    <triggers />
41    <tasks>
42      <!-- Tasks defined here -->
43    </tasks>
44    <publishers>
45      <!-- Publishers defined here -->
46      <xmllogger/>
47    </publishers>
48    <security type="defaultProjectSecurity">
49      <permissions>
50        <rolePermission name="all" ref="all"/>
51      </permissions>
52    </security>
53  </project>
54</cruisecontrol>

Credits

This scenario was originally posted on Automated Coder