Using Team Foundation Server Registry–Part I The concepts
Since the beginning Team Foundation Server uses a registry to store it’s settings (like Sharepoint location,external address,database configuration, etc), with the introduction of the 2010 version, the registry has been revamped to be much easier to use (pre 2010 it was a XML file that you had to manager yourself. Including the values that didn’t pertain you).
So starting with 2010, we have a nice API to manipulate the registry in a easier way. The registry is not only used by TFS to store it’s settings but it can also be used to store your settings.
There are many scenarios for which you can use the registry. If you need to store metadata that is project related and needs to be shared globally among several users you can use the registry to store those values instead of storing them on your own database.
The advantages are obvious, no need to manage an external storage mechanism, the data is contained within TFS with all the associated advantages (backup/restore, if you move a collection to another server they follow the collection, etc.).
The registry is not a database, you don’t (formally) define a schema for your settings. The registry is an hierarchical key/value database. You can define your keys in an hierarchical manner and the registry is agnostic about your data values (so you can use it to store, .Net types (being string the most common) or XML).
For example TFS uses the registry to store the email notifications settings on the following keys:
- /Service/Integration/Settings/EmailEnabled
- /Service/Integration/Settings/SmtpServer
- /Service/Integration/Settings/EmailNotificationFromAddress
Notice the trend? Service –> Integration –> Settings stores a bunch of TFS related settings.
The API is public and you are free to use the registry, unfortunately the registry is not widely documented. I hope with this post demystify the registry, it’s semantics and how you can manipulate it.
There are two types of values in the registry. values and user values.
The values are registry scoped and anyone can read/write them (as long as they have the appropriate permissions), so it is appropriate to use when you have a setting that is going to be shared among all users.
User values are scoped to the user, they are private to the user and only the user can read/write them. This is great if you want to store settings for a user independent of it’s location, so you can store values in the user registry and he/she can roam around machines having the same settings everywhere (when you say application you can also say Fat client (eg: visual studio) and web. In fact this is exactly what Web Access does, it stores user preferences in the user registry.
There are two different registry storages, the project collection registry and the server registry (stored on the configuration database). The collection registry is stored along with all data of the project collection, so if you detach the collection and move it to another server the registry follows the collection, the configuration registry is stored on the configuration database, so you should use it to store parameters that are server related. If you move collection to another server and you are relying on some values on the configuration registry, it will be your responsibility to recreate them on the other server.
There are two kinds of security constraints applied to the registry. To read/write registry (depending on the registry) enters you need the following permissions
- View collection-level information for a collection registry
- View instance-level information for a configuration registry
These permissions are the first barrier, then you need permission to access the object itself (but since this is hierarchical you can grant/deny permission to a branch of tree). By default these are permissions to registry keys.
For the configuration registry
Permission |
Team Foundation Service Accounts |
SharePoint Web Application Services |
Team Foundation Administrators |
For a collection registry
Permission |
Project Collection Service Accounts |
Project Collection Administrators |
Project Collection Valid Users |
Note: reading the registry has a semantic that is not common, if don’t you have first level of permissions (View collection-level information for example) the operation will fail with an exception. If you don’t have permission at the object level any read operation will not fail with an exception but it won’t return anything (even if the object exists).
This happens to avoid disclosing information that a node exists (it’s mere existence) to people who do not have access to it. It’s a typical technique of multilevel security systems to avoid leakage of information with inference atacks. For example if you have a value with a key /Settinga/OnToBeFiredList/JohnDoe I may not have access to it’s value due to lack of permission but if an error was flagged we could know it exists. Sometimes the mere acknowledge of the existence of information is reason enough to be denied.
It is debatable if the existence of such semantics doesn’t out weight the costs of not having errors being flagged when we don’t have access to information that we want to access. But such discussion is pointless since that the way things are.
As of today (to be read, it is like it is today it can change tomorrow) access to the registry on Team Foundation Services (AKA as tfspreview.com or TFS on Azure) has been hardened so you can’t read/write no matter what kind of permissions you have.