Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Genuine question here: isn’t it a standard security practice to avoid committing keys (or other secrets) to repos?

Edit: and what’s the best practice here? Is it using a key management system of some sort? (I’m thinking of scenarios where you might need to deploy your code + secrets on a remote server, say to authenticate with a third party API)



Yes, standard is using a key management system (KMS), but there's a lot of nuance and complexity there. Depending on the threat model, you can use software systems, hardware systems, multiparty crypto systems, and you need to think through all kinds of failure modes very carefully (particularly around disaster recovery or insider attack scenarios.) A good place to start is cloud-based key management systems, because they take care of a lot of the complexity, but you still have to do it carefully (e.g., paper backups in a multiple safes, protecting the cloud resources correctly, 2FA on your account, etc.)

Protecting high-value cryptocurrencies is particularly hard, and as much as crypto people like to say "not your keys, not your coins", the reality is far more nuanced, and the average person is much better off using a well-known platform like Coinbase. Even hardware wallets are not as simple as people thing to use safely.

(If you're building cryptocurrency apps, never upload wallet private keys to cloud KMSs. Instead, generate wallet keys using the KMS itself, and use those wallets for small "in-transit" funds only. Think of them like bank branches, when you manually transfer small amounts of funds securely from a set of central wallets.)


> Genuine question here: isn’t it a standard security practice to avoid committing keys (or other secrets) to repos?

When you deal with high value amount of cryptocurrencies, you have a hardware wallet so things like these are not even possible in the first place, as the keys are safely stored in the hardware. Storing anything on disk (unencrypted at that) that corresponds to $40K is basically begging to be stolen from you.

Besides that, when you open source something that even has a chance of containing something you don't want to make public, you read through every single file before hitting publish.

> I’m thinking of scenarios where you might need to deploy your code + secrets on a remote server, say to authenticate with a third party API

Commonly you use environment variables for this. So the code references `process.env.MY_SECRET_VAR` or equivalent, and then you set that variable inside your server. That's the simplest way, then there are more complex/"secure" ways too, quick search for "secrets management" in your favorite search engine will tell you more.


Then you need to read through any file in any revision. Because if you have a newer commit with the secrets removed they are still in the history.


Or `rm -rf .git && git init && git commit -m "init"` and then read through. Common to scrap previous history when you go from private -> public repository anyways, a lot in order to scrub potential things like this to leak through.


If I'm at all worried about having accidentally committed secrets in the past, I usually create a new repo for the public release with a fresh git init.


Someone should come up with a paper-based version of hardware wallets that are easy to exchange.


It is standard security practice to try to avoid committing keys, yes. Unless it's to a private repo you know will never be made public.

There are a variety of options, depending on what type of software you're developing, how much you're willing to be locked into third party tools, and things like that.

The simplest is to just save the credentials somewhere like the user's home directory, outside of the git repo. This is what a lot of command line tools do.

Environment variables are also a popular option - most CI build systems will let you store 'secrets' that are passed into the build process as environment variables.

Larger scale projects will often end up with a configuration management mechanism, enabling 'configuration as code'. When doing this it will often be interlinked with credential management. After all, why not store the hostname of the database alongside the username and password?

If you're in a cloud environment, they will have 'instance metadata' that can (with configuration) pass cloud provider credentials into your instance. They will often provide a secret store service you can access using those credentials, and will let you authenticate to databases and blob stores and whatnot using those credentials so long as you stay within their cloud ecosystem.

Large corporations like 'credential rotation' where secrets get revoked and re-issued on a regular basis. The cloud environment can do this between your instance and their provided services - or you can do it yourself in an ad-hoc way.

All the major PC operating systems provide a secret storage function or 'keyring' although it's debatable whether it's all that different to just saving a file on disk. It used to be, back before the rise of full disk encryption though.

And of course if you're writing a mobile app, the operating system is a lot more locked down. So there you can store credentials in the system keyring and other applications can't access them.


>Unless it's to a private repo you know will never be made public.

Not even then and this is why


Even if it’s private don’t put keys in the repo


Usually the simplest way is leveraging environment variables. You can set the API key as one on the remote server, then you can get it with `API_KEY = os.environ.get("API_KEY")`. That's a Python-specific example - but hopefully you get the idea.

There are other services that manage securely saving/storing these keys rather than just hosting it on the server itself (e.g. AWS Secrets Manager)


Generally you deploy or use some sort of secret/config delivery service.

For example most/all VPS provider allow you to give extra data to the machine; this could be the secrets directly or maybe a connection url to a local* redis server with the configs.

Or you can copy paste a file vis ssh.

*AWS-like providers allow you to also deploy private networks so that only approved services vps can access a db


It is, if you know what you are doing.

@your edit: you can use environment variables for example, just don't commit your dotfile or just don't store in the same folder as the repo if you don't know what a dotfile is.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: