In Octopus Deploy, when using username/password authentication, we've always taken care to hash passwords with a salt, and we never store the plain text. In earlier versions we used SHA1 hashes, and last March we switched to using PBKDF2.
However, when using our HTTP API, you can also authenticate using an API key. And like most applications, we store the API key as a plain text string (although the Octopus database itself is encrypted anyway).
Many web-based applications with API's work this way - log in and you'll find an API key in plain text. Which means that the key is probably stored in a database in either plain text or can be decrypted. That means that if someone is somehow able to read contents from the database, it's possible that they could take your API key and use it to impersonate you.
Amazon Web Services recently made a change. In the past, you could return to the AWS portal to get your API secret key whenever you need it. Now, when you ask for an API key, they give it to you once, and you're expected to keep it yourself. I don't know if they plan to start storing the secret keys hashed or not, but it probably makes sense.
In Octopus Deploy 2.2 we're going to do something similar. We're going to store API keys hashed and salted, using PBKDF2, just like we do with passwords. You'll no longer be able to retrieve your API key from the web portal, since just like password storage, it can't be reversed. We're also going to make it possible to keep multiple API keys and to deactivate them when one is compromised, accidentally shared or no longer needed.
When you request an API key, you can give it a name. We assume you'll use the API key immediately for a specific integration.
After generating the key, you'll be able to see the key just once, and we only store the hashed version. If you need to use it again, keep it someplace safe like a password management tool.
To improve auditing, we're also going to add the method of authentication used when you use an API key on any audit events. This way if an API key is compromised and used to do something naughty, you'll know which API key to deactivate.