Friday, March 11, 2011

Saving your API key with nuget.exe

While you can push NuGet packages from http://nuget.org/, it is often more convenient to do it straight from the command line using nuget.exe.

Phil did a nice post on how that works, which you should read first if you have not done this before.

The one pain point about this technique is that you need to find your API key every time you push a package. I have had to go to http://nuget.org/Contribute/MyAccount each time to locate my key, copied it and pasted it on the command line. It gets old quickly! :)

The good news is that the newest version of nuget.exe (get it here) lets you save it once and for all! Credit goes to Matthew Osborn for this new feature.

Here is how it works.

Saving your key

First, you run the new SetAPIKey command, e.g.

D:\test>nuget SetApiKey 78a53314-c2c0-45c6-9d92-795b2096ae6c
The API Key '78a53314-c2c0-45c6-9d92-795b2096ae6c' was saved for the source 'http://go.microsoft.com/fwlink/?LinkID=207106'.

This encrypts the key and saves it in a config file under your %APPDATA% folder. e.g. mine ends up in C:\Users\davidebb\AppData\Roaming\NuGet\NuGet.Config. This file contains:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<apikeys>
  <add key="http://go.microsoft.com/fwlink/?LinkID=207106" value="AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAnMGkdu4+rkqpSdQUWwjfIgAAAAACAAAAAAADZgAAwAAAABAAAAA5gG4wxeb8Vn4X0Y0p//OvAAAAAASAAACgAAAAEAAAAF/llublBpBgL9lSFaE9/A0oAAAAC4NVHflYsUU5UgVgOq+h3t1jwY6l2BEji6Td4F0lvxsZcZ73L2m6BRQAAABJ0TZLKdIYStn8DWawbtzdo3mrKg==" />
</apikeys>
</configuration>

Note that the key is saved per server URL, with the server defaulting to nuget.org (you can pass -src to change that).

Using the saved key

Once you have done this one-time step, pushing packages becomes a breeze, as the only thing you need to pass is your package file. e.g.

D:\test>nuget push DavidTest.1.0.nupkg
Publishing DavidTest 1.0 to the live feed...
Your package was published to the feed.

Likewise, if you want to delete a package, you’d do:

D:\test>nuget delete -noprompt DavidTest 1.0
Deleting DavidTest 1.0 from the server.
DavidTest 1.0 was deleted from the server

Hopefully this will make your NuGet package management experience a little bit easier!

4 comments:

  1. Curious to know how this solution would work with codbetter's TeamCity setup where multiple projects can all run under the same credentials...

    ReplyDelete
  2. I'm not sure if would still solve the problem of running it under a CI server like TeamCity or others for that matter which run under one account. And the key is still visible....

    ReplyDelete
  3. @Rex/@Hadi: this was more targeting the dev box scenario. Not sure how the CI scenario can work. If the same account is used for multiple users/projects, it seems difficult for them to hide their keys from each other, yet have it somehow be available at build/push time.

    ReplyDelete
  4. to solve CI problem i think its best to use the environment variables.

    Most linux tools like git use this.
    They first check the local config file .gitconfig in the source code repo, then check in the global config which is usually set per user, and if it still can't find, the check the environment variables.

    So I think nuget can fall back to environment variable if it doesnt find anything in the NuGet.config file.
    And might be still better to have an additional parameter called --env (to force getting the api key from environment variable)

    https://github.com/prabirshrestha/ProfilesAndSettings/blob/master/.profile.ps1#L74
    In this powershell profile i set my editor to vim, so git picks up automatically since i havent define it in .gitconfig files.
    $env:EDITOR = "vim"

    so we an have something like
    $env:NUGETAPIKEY

    but one downside is we are locked with allowing only one nuget api.
    so might we we should be able to choose the environment variable name from command line
    nuget push ... env=apikey1

    ReplyDelete