1
votes

I'm in the process of automating the setup of git repositories for a client. This involves setting up build template definitions in TFS 2015. I've chosen to store the configuration of these templates in a separate repository along with many other build / deploy related files (there are hundreds of repos, and they all share similar builds by default).

I'm using the new on-prem TFS 2015 build system (very similar to the VSTS / VSO build system), and querying the API for all kinds of things. Build definitions and Build Definition Templates are what I'm working with right now, which is where my specific problem lies.

A number of the build variables contain API keys which I would like to keep private:

Secured Variable in TFS UI

When queried (for either a stored Build Definition or a Build Definition Template), TFS rightly returns a blank string for any variables that are set as "secure" - but the response JSON does not contain any reference to the variable being "secret". Here's an excerpt of JSON returned when I retrieve a Build Definition (its the same for a Build Definition Template):

Call Uri (defined in documentation)

GET https://{instance}/DefaultCollection/{project}/_apis/build/definitions/{definitionId}?api-version={version}[&revision={int}]

Excerpt

"variables":  {
    "system.debug": {
        "value":  "false",
        "allowOverride":  true
    },
    "system.prefergit": {
        "value":  "true"
    },
    "MySecureVariable": {
        "value":  ""
    }
}

I would expect there to be a property like "isSecret" or similar, but I can't find any documentation or examples referring to this. The docs also fail to mention if it's not supported, so I'm at a loss.

If I set the variable to a value (i.e. I use a Build Definition Template to create a new Build Definition), the "secret" option is disabled in the UI, and the key is visible. You could argue that someone could go into the UI and mark the variable as secret manually, but that's an additional step that lends itself to forgetfulness.

These secret variables are stored in a password safe, and I will be prompting the person who runs the scripts to enter them at runtime (or I will automate the read from the safe - not sure yet). That's beside the point though.

Can anyone advise on how I can set secure variables directly via the API?

1

1 Answers

1
votes

I figured it out by doing some debugging / HTTP traffic monitoring whilst setting variables in the TFS UI. Basically, my guess was correct!

No matter how you set up the build definition templates, or build definitions, TFS never reports that a variable is secret via the REST API. However, if you store your templates elsewhere (or manipulate the JSON object returned from the "Get Build Definition" or "Get Build Definition Template" REST API call) you can set the setting yourself.

My example above becomes:

"variables":  {
    "system.debug": {
        "value":  "false",
        "allowOverride":  true
    },
    "system.prefergit": {
        "value":  "true"
    },
    "MySecureVariable": {
        "value":  "",
        "isSecret": "true"
    }
}

Saving this setting in a Build Definition Template via the REST API does not mean that variable will be marked as secret if you use that template via the TFS UI. However, if you automate the creation of a Build Definition via script and set the property, the resulting Build Definition will mark the variable as secret.

What a faff about!