简体   繁体   中英

Best practices - what kind of file for saving api keys?

What is the proper way to store API client id/secret information in a separate file? There are many approaches, but there seems to be a lack of convention. If picking an approach for saving volatile strings is highly subjective, what are the deciding factors one should consider that go into making the decision and when is appropriate to use the String type vs a configuration library?

I see a couple of simple options to implement this that could be adapted to potentially follow the DRY principle:

String variables

-- define string variables in keys.hs
mykey :: String
mykey = "key here"

-- then in the main file import these keys
import keys

Raw text file

keyFile :: String
keyFile = "keys.txt"

getKeyFromFile :: IO B.ByteString
getKeyFromFile = B.readFile keyFile

Also, one could potentially use a library and of course for when you need to manage more keys:

OAuth Authentication library

-- Define a data structure for each set
myoauth :: OAuth
myoauth =
  newOAuth { oauthServerName     = "api.server.com"
           , oauthConsumerKey    = "key here"
           , oauthConsumerSecret = "secret here"
           }

Configuration manager and use their config format

--taken from their example
my-group
 {
   a = 1

   # groups support nesting
   nested {
     b = "yay!"
   }
 }

I think there are two issues here, and its important to distinguish them:

1: What is the best practice for storing user secret keys regardless of the language.

2: What is the best way of implementing the above in Haskell.

I would always recommend keeping secrets in a separate file from the rest of the configuration information because it may well need to be treated differently. For instance a config file might be world readable and backed up, but the secrets file must not be world readable and might not be included in the backup. SELinux might also be configured to treat it differently by restricting which programs can read or write it. Designing your program to keep it separate enables the user to make these decisions.

As for data format, personally I would use JSON so you can store structured data such as salts, (user,password) pairs or whatever your application requires. But that is purely a matter of taste. A Binary instance will also work fine.

You might also take a look at this previous answer of mine which discusses ways of ensuring that secrets are securely wiped from memory as soon as they are no longer required, although that isn't going to help if you use Haskell to parse a JSON representation of your secret data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM