Hacker News new | past | comments | ask | show | jobs | submit login
Sign arbitrary data with your SSH keys (agwa.name)
637 points by h1x on Nov 13, 2021 | hide | past | favorite | 320 comments



>Here's why I like SSH signatures:

>* It's not PGP.

The most important reason people use the OpenPGP message format is because it is a well accepted standard. Sure the cryptography is not new and fun but it is secure. If you sign something with OpenPGP then you can be sure that those signatures are verifiable on any platform by anyone. The OpenPGP standard has provisions to ensure that the signatures are from a particular entity. This proposal suggests that Github could be treated as a trusted third party. If that is the case then you don't need signatures at all.

Obligatory "The PGP Problem" rebuttal:

* https://articles.59.ca/doku.php?id=pgpfan:tpp


> The OpenPGP standard has provisions to ensure that the signatures are from a particular entity.

No, it does not - it has provisions to ensure that the signatures are from a particular private key. Mapping that to a human-meaningful entity is beyond the scope of the OpenPGP specification.

The article you link does not really address that point, and it doesn't at all substantiate the claim that using GitHub as a trusted third party means you "don't need signatures at all".

(Also, the original post says that other means like key transparency can be used instead of trusting GitHub.)


Well, if you trust github enough for the keys, you can just download and distribute the arbitrary data through github itself. I guess that is what he was referring to.


Isn't the web of trust part of a PGP? That maps private keys to human-meaningful entities. Or is that not part of OpenPGP?


It's one way to use PGP, and it's not the only way. Almost certainly the most common use of PGP by number of operations per day is verifying RPM and apt signatures, which relies on trusting specific keys delivered through out-of-band means (in practice, mostly previously delivered via HTTPS).

In turn, the subject information in these keys does not matter - either the signing key is trusted, or it's not. There's an ongoing philosophical debate among users of the web of trust about what the subject (name and email) means. Should you sign a key if you see a passport Are you attesting to legal names? If someone works via a pseudonym, how (if at all) should you sign their key? How do you validate the passport? Maybe you should only sign keys for people you actually know, and attest to knowing their identity in a human sense and not to them having legal documents? What about the email field - do you need to verify that they possess the email? How?

The OpenPGP spec includes just enough functionality to encode trust into local keys (and specifies that it should not be exported), but it does not say anything about a web of trust: https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.3....


The argument is that the whole "web of trust" thing never really took off, so you can't rely on it in practice.


As people can discover from the search bar on this site, your argument against that blog post (which I co-wrote) includes the notion that authenticated encryption is bad, because unauthenticated encryption creates opportunities for data recovery. Restating for the record: I agree in part; where we part company is that I think creating opportunities for data recovery for adversaries is a bad idea.

At any rate: this comment thread is about signing with SSH keys, not your idiosyncratic response to my blog post.


I don't think they're being idiosyncratic. You start your post off with a paragraph that complains about how bad PGP is. Of course people will respond to that part.

I don't think PGP is that bad either. It's pretty standard asymmetric crypto. The implementations and especially the key sharing leaves a lot to be desired but for personal use I like it. And I love that there's lots of hardware key support. This is why I use it.

I personally use my hardware OpenPGP keys also for SSH, on yubikeys and OpenPGP smartcards. I also use those for encrypting and signing data. So I'm already doing something similar to start you're saying, just the other way around.

Having my keys on a hardware token is a must-have for me and I wonder if that's possible with your method. I also prefer having a token that requires a hardware input for each use like the Yubikeys can. You can set them up to require a touch for every signature or authentication. This stops a compromised server you log in to from milking your SSH agent.

But how would I store the keys in hardware if not PGP? I tried PKCS11 modules with different cards before but the software chain with middleware is pretty terrible. PGP's is pretty sane (gpg --card-edit is much more user friendly than what was offered by the other more expensive cards I used!)

And I don't like Fido2 either for this because it can't be used for content encryption/signing (which is what your blog post about)

So, I'm pretty open to doing what you're doing but my requirement for hardware key storage makes it pretty hard I think.

It would be nice to hear your thoughts on this, how this could work with hardware-backed keys.


This whole thread is off-topic (talking about AEAD in a post about signing), but:

You can use age's AEAD encryption with Yubikeys. Yubikeys can do ECDHE in PIV mode.

I wrote https://github.com/tv42/yubage as a subprocess plugin to https://github.com/str4d/rage (and hopefully https://github.com/FiloSottile/age once they think plugins are stable in enough to go in the reference implementation). The rage author also wrote their https://github.com/str4d/age-plugin-yubikey


Ditto on the hardware token. This SSH signing thing looks to require an actual file in the file system, which is a complete non-starter to those of us who don't keep our keys in ~/.ssh/id_* files.


From the man page:

> The key used for signing is specified using the -f option and may refer to either a private key, or a public key with the private half available via ssh-agent(1).


I think you are referring to my comparison of age vs gpg[1]. That in no way indicates that I have anything against authenticated encryption. I just point out that age has no data recovery utility.

BTW, when used in a normal way, an offline capable, stateless system as embodied in the OpenPGP message standard uses signatures to provide integrity protection[2]. Which might bring us a bit closer to the matter at hand I suppose.

[1] https://articles.59.ca/doku.php?id=pgpfan:agevspgp

[2] https://articles.59.ca/doku.php?id=pgpfan:authenticated


> GitHub acts as a trusted third party here, and you have to trust them not to lie about people's public keys, so it may not be appropriate for all use cases. But relying on a trusted third party with a professional security team like GitHub seems like a way better default than PGP's Web of Trust, which was nigh impossible to use.

Hopefully that's a false dichotomy and the entire Free Software community doesn't end up reliant on Microsoft to host all our keys for us. The article goes on to mention key transparency, though, which does seem like the right solution.

I note that rekor (the transparency log implementation used by sigstore) already supports signing with SSH keys[0], so this TechRepublic article about it[1] from March (which lists only "GPG, x509 and Minisign") is already out of date.

[0] https://github.com/sigstore/rekor/blob/main/types.md#ssh

[1] https://www.techrepublic.com/article/a-new-linux-foundation-...


Its not like anyone has ever really come up with a good solution to key distribution. You either trust a central authority (pki), deal with the mess that is web of trust, or blindly trust your first connection and verify the person hasn't changed (tofu).

Honestly it kind of reminds me of the problem of defining "Truth" (in a philosophical sense)

All options are sucky in their own way.


I really liked how keybase [1] approached this issue, their methodology involves generating keys on the client and making it post "proofs" on whatever social media(s) you use. This gives a my identity -> My key relation, and their client (which is open sourced) would verify these proofs clientside. So it's a server aided but still trustless.

Unfortunately the development seems to have ceased after zoom acquired them.

[1] https://keybase.io/


I'd say that DNSSEC records coupled with something resembling WKD makes for a pretty good way to distribute information in a somewhat trusted manner.

Nothing can really replace out-of-band in-person verification because human perception is remarkably difficult to spoof against or MITM. Comparing keys found in two bands, e.g. DNSSEC records and WKD (using TLS verified by the wpki system), is close enough for most threat models: you'd have to compromise DNSSEC and a CA to break that system.


You're still just replacing one central authority with a different one [or i guess 2] (i assume WKD = web key directory, in this context). With the email domain owner (i assume different from the recipent) being a cenral trust point (and if you totally trust them, why not just use mta-sts?).

Now sure, depending on your needs, you might be able to get mild improvements by chosing a different set of trusted parties than the webpki's CAs, but i'm not sure its really that different at the end of the day.


DANE + DNSSEC is much, much stronger than our CA system; if you control the keys (let alone if you go all the way and self host your DNS and mail servers), then you cut out pretty much all the intermediaries you reasonably can. You still have to trust DNS at the end of the day.

MTA-STS depends on webpki and the CA system.

Since not everything leverages DNSSEC yet and it's tricky to implement I'd supplement records with something resembling WKD so you have two bands.

Another possibility is having clients fetch keys over both clearnet and an overlay network (e.g. Tor); this doesn't help if the web server is being MitM'd but at least you have to trust client endpoints a bit less.


The opposite thing is true. DANE is far weaker than the CA system; it is centralized and controlled by parties that aren't accountable for security (and, more importantly, haven't spent the last decade with Mozilla and Google's gun aimed at their head over security issues). DNSSEC's centralized governance can get away with that, because they are de jure owners of the DNS hierarchy, and nobody can make them accountable for anything. You can't revoke .COM. But Google and Mozilla revoked all of Verisign.

I trust Google and Mozilla more than I trust the world governments that control the DNS hierarchy, and I see the actual transparency mechanisms, like CT, that the WebPKI watchdogs have built; unlike with DNSSEC, they aren't simply a theoretical thing that could be built in the future, but rather operate today and have been responsible for numerous detections of misissuance.


Governments do not control DNS in any practical sense. Even if, in theory, the US Department of Commerce could revoke SIDN control over .nl, it would be totally impractical for any directed attack.

Control of Chrome or Google itself is a radically different matter. And with the CA system, there are a 140 other trust points to be attacked.

What is weaker will depend on your perspective and threat model, but if the measure is how easy it would be for the government to create an arbitrary fraudulent SSL certificate, it is objectively much easier than creating an arbitrary fraudulent DNSSEC record.


This argument, which is common, amounts to saying that if Google Mail doesn't like the way .COM is run, it can just leave .COM.


I can not see how that argument could possibly follow. For the record, I do not think that Google Mail neither easily could, nor should, switch their domain.

Even if the argument is, and I do not think that it is, that domain validated TLS certificates for the .com top domain are the only CA signatures worth considering, it is important to note that it is comparably more straightforward for the government department in question to seize those domain names if needed.

A domain registry PKI where domain ownership is cryptograhically asserted can never be less secure than the heterogenous global CA directory we have today, in any possible sense, not for domain validated certificates.


Sure it can. The domain registry PKI for Google Mail is literally controlled by the USG. They can compel different names to be given to different people, and there's no CT system to monitor it.


s/PKI// and the sentence still holds true. The argument for CT is good, we still need CT logs no matter which kind of PKI we would like to see. But surely the security of other domains outside of Department of Commerce control are of interest too?


Just substitute "US Government" out for whichever government controls the TLD you're thinking of. You'll be no better off; none of them are more trustworthy than Mozilla and Google are.

(I don't find Mozilla or Google to be especially trustworthy, of course; I simply have absolutely no faith in the reverence government agencies have for the sanctity of the DNS. Something about the way they publicly brag about manipulating it probably has a lot to do with it.)

I think the idea that we should vest more Internet trust into the DNS, the one bit of core Internet infrastructure governments have demonstrated any kind of deftness at manipulating, seems, respectfully, pretty nutty.


And 20 minutes into the future, when Google is the undisputed monopolist of web browsers? Do you trust Google to be our unimpeachable lord and master?


Do I trust an undisputed monopolist Google to run Internet public key infrastructure more than I trust the United States Government? Yes, I don't even have to think hard on that.


I think there is some promising work around using blockchains for this purpose.


Thanks for the insight and links!

And really... > relying on a trusted third party ... like GitHub seems like a way better default than PGP's Web of Trust

Made me scream: "What??" I'd personally prefer some decentralized torrent-like way of user key distribution.


Distribute your public keys via DNS TXT records:

https://www.go350.com/posts/age-file-encryption/#age-pki-iss...


That only creates a link between SSH keys and a domain; It's even worse than relying on GitHub since you have to trust that multiple account haven't been hacked (registrar + DNS) and that neither the DNS host nor the registrar are acting maliciously.


Psst. Github has all that stuff too. Just more because it is a growing and changing webapp instead of an ancient, solidified key value store.


I agree. DNS is its own bundle of insecurity.


What would that look like? Distributing keys is always the hard part.


Well, I tried to avoid saying blockchain, which is already being implemented https://hackernoon.com/decentralized-public-key-infrastructu... but is resource-heavy. On the second thought, there are potential problems with DHT-like way of distribution (rogue peer overwhelming, etc) I can't seem to find article on this idea (it's pretty old), sorry.


Its kind of missing the point (unless im missing something). The hard part is linking keys to well known identifiers (ensuring that a malicious person can't trick you into thinking you have someone else's key when you really have the evil person's).

Having an append-only store is not the hard part of the problem and there are much better solutions than blockchains for that.


Identifiers are just attributes. If you want to attach a library card, US Passport, refugee id to a blockchain instance of your identity, you can inherit that endorsement.

In NIST speak, you can get a level 2 assurance level (good for most commerce) by collecting two strong identifiers or verifying one.


That does not solve the problem. If it did, we would have solved the problem decades ago

Case in point - pgp supports exactly that - you can have keys, which can have attributes which are endorsed by your key. We've had this since the 90's. It didn't solve the problem back then, reinventing the same thing but worse using blockchains won't solve the problem now.


Distributing small chunks of text sounds like the wrong problem to call "hard". It is building trust in them. Problems with the web of trust are well documented and pretty much boil down to "random people in the Internet turn out to not really be the most trustworthy of mediums".


There’s one final problem even harder than that. Creating a UI that by itself explains this whole complex concept, to a user with an average attention span of 3 microseconds.

Just look at how many scam attacks have been made possible just on urls.


Regarding PGP's 'Web of Trust', I thought the purpose of this was to validate the link between the key and the owner of that key. This is not what you get from retrieving a public key from github... that only gives you the link between that key and a github account. But what does that give you?

From what I understand, it gives you nothing for anything that is signed and that does not have a direct link to a github account. Obviously, if someone releases software on that github account and I find a signed release of that software, I can validate that it really was signed by the official source of that software on github. For anything that does not have that direct link, it really does not give you anything.

I've never used PGP, but I thought the web of trust was used to validate metadata on the key and that this can be used to validate that a key really belongs to the person that you think it belongs to. I saw it more like how you have SSL certificates with different degrees of validation and where you must deliver more proof of your identity if you want to receive a certification with a higher degree of validation.

I'm all for using SSH keys for signing, but I still would like to have something like PGP's web of trust for those keys.


In a very practical sense, I (the human writing this comment) pay close attention to the security of my GitHub account and to what SSH keys are added, because I use it regularly and care about the security of my account. I also care about the security of all my client devices that can push to GitHub, and in fact a few of my devices cannot push to GitHub (they have to route through a device I am more careful with). If you have a link to my GitHub account, you have a very high confidence that you have a link to me the human.

Meanwhile, I've been to multiple PGP key-signing parties and organized one or two myself, and the quality of the link is always very low. At one Ubuntu Developer Summit (a community that heavily relies on the Web of Trust), the person organizing the party wanted us to verify short key IDs. I refused, and set up my own list of full fingerprints that I distributed to participants, and earned the ire of the organizer. At one DebConf (another community that heavily relies on the Web of Trust), I saw at least one driver's license from another country that was of such quality that it could be easily reproduced by any fake ID shop for college kids. There may have been features on it to verify its authenticity; I certainly did not what I should be looking for, and I doubt others did. I don't remember if I signed the key in the end. I think I did. I expect others did.

So, if you find a signature on the Web of Trust for my key, what does that give you? What confidence do you have that the person signing it actually verified it was me?


I agree, but I think it's pretty clear that web-of-trust has failed. There may be 6 or fewer degrees of separation between us, but the chance that there's a path of people that actually validate and sign keys isn't very high.

As an alternative keybase.io worked well. If you knew the person controlling the github account also controlled the mastodon/twitter where you talked to them, and the website/blog, etc, then you can be pretty sure it's them. (I saw mention of more open systems here too https://news.ycombinator.com/item?id=29132024).

> I'm all for using SSH keys for signing, but I still would like to have something like PGP's web of trust for those keys.

same here. I use my gpg key for ssh (stored on a yubikey). Seems like a better option to me.


i think the main assumption that keybase makes is an important one: you don't need to link a key to a person, you need to link it to an identity. and a github page or a twitter account is an identity. the IRL identity of the person controlling that web identity can be considered out of scope.

if you do need to link a key to an actual non-digital person, then you've got a whole different set of problems.


The problem of gpg/PGP servers is that they never counted on the phenomenon of 'spammers'. I have not put my key in a public directory for at least 15 years now.


Chances are you're already using SSH keys for SSH authentication, whether for your own machines or as part of a Pubnix/tilde server [0]. That can prove useful for signing data in a server-to-server model (eg. to advertise vhosts to mirror or provide secondary NS/MX for) or identifying users on a less-secure channel (eg. SSH-sign a JSON HTTP request).

When you think about it, SSH keys are used as identifiers (just like PGP keys) so there's no reason not to use them as such. But as you pointed out, SSH doesn't have a WoT yet so we rely on trusted 3rd parties to discover keys (so far).

[0] https://tildeverse.org


Age uses this feature of GitHub, as an example, in the documentation:

"Encrypting to a GitHub user

Combining SSH key support and -R, you can easily encrypt a file to the SSH keys listed on a GitHub profile.

$ curl https://github.com/benjojo.keys | age -R - example.jpg > example.jpg.age"

I also like distributing public keys via DNS TXT records and have written about that some here:

https://www.go350.com/posts/age-file-encryption/#age-pki-iss...


Thanks! I was already wondering if this would be possible. Signing data has its uses, but I more often have to transfer sensitive data to other GitHub users and this tool seems really useful for that!


That's encryption (recipient key), not signing (sender key). But yeah (r)age is pretty useful for that.


I get that they're "public" keys, but I was surprised to learn (and from somebody other than github themselves) that ssh public keys are just available at that github.com/username.keys URL (without there being an option to disable it, it seems?). Did most people already know that? Probably fine but just surprised. Just tried searching their authentication docs [0] and I don't get any results for "public key url" either

https://docs.github.com/en/authentication?query=public+key+u...


>I get that they're "public" keys

From your quote around "public", I presume you think there is some sense in which they're not really public? They are and should ALWAYS be considered PUBLIC. If you find yourself ever crafting a security solution where public keys somehow need to be private or secret, go back to the drawing board or reach out to someone with serious expertise.

There are cases where information on a certificate (which is associated with a public key)may indeed need to be protected, in that case you need to implement an information mask (via hashing) that can protect the private information, we had to do something similar with Certisfy.com certificates. But public keys should be considered public without exceptions.


> If you find yourself ever crafting a security solution where public keys somehow need to be private or secret, go back to the drawing board or reach out to someone with serious expertise.

I know you’re taking the “strict teacher” approach with your comment, but you’re totally wrong. And the reason you’re wrong is, security doesn’t equal privacy. But for the “average person,” security does equal privacy, or should, so they find systems that could potentially expose their identity to be “insecure.”

In this particular case, there have been past examples of using keys to fingerprint users without their consent. Yes, it’s been super edge-case and proof-of-concept, but for a lot of people — and perhaps more importantly, in a lot of jurisdictions — leaving a personal identifier sitting around like this (without ever informing the user!) is the very opposite of a best practice.

The end result is, you should only have a key on GitHub that isn’t used anywhere else. That’s what I do, and I’m sure lots of us on this comment thread do, but there’s definitely lots of My First Coding Bootcamp people who were guided through their GitHub account installations who might not have been aware that these are keys that shouldn’t be reused elsewhere.

I would have a very different view on this if GitHub had been explicit about the use of registered keys for other services. That’s a GREAT concept, but I’m not going to trust a company with that business when they’ve just backdoored themselves into it without asking for permission. And the problem for them is, in this particular situation you need the weird paranoid privacy crowd on your side for it to work.


If you need privacy then you shouldn’t be uploading to GitHub in the first place. The moment you do that you’re publishing email addresses, other projects that you contribute too and potentially leaking your timezone by virtue of commit times.

Your SSH public key is really the least of your identifiable information you’d be worried about because that’s the easiest to create a unique key for GitHub.


Information being made public or shared with others against the user’s expectation is always bad. I agree that’s it’s more a documentation and UX issue than a security concern, but it’s not nothing.


This is how I see it as well. May I have all of your usernames? No, but those are "public" in the spirit of this thread as well. However most are protective of them. Maybe you use a very specific email address for a password manager that you don't use with anything else. I wouldn't want a SaaS service automatically saying - "Oh you know <username>? This is an email they use."

Just because the functional security of a system isn't dependent on the exposure of a public component doesn't mean it should implicitly be shared.


I’m not aware of any service that is protective over usernames. Some don’t allow scraping of user profiles for “privacy” reasons but that always struck me as a shallow excuse given they’re publishing them anyway - I often suspected the real reason was more that profile data is valuable for analytics so they’d rather offer deals selling that data. Deals that are undercut by scrapers.

Some platforms don’t publish users lists but it’s often the same platforms that like to post headline figures about their user base so I suspect not publishing user lists is more about a company being able to exaggerate its worth rather than privacy. Especially when those same platforms readily publish user names in every format aside one consolidated list.

In short, if a piece of information isn’t available on a social platform, or is frowned upon scraping, then odds are it’s more likely financially motivated than it is down to privacy. Given these same companies typically make their money from you handing over your data in the first place it would be naive to think they really care about your privacy.


Exactly. Even if it's a "public" key. Public can be interpreted in different ways.


As far as I know, the design of the SSH protocol requires that the keys be public: you can pull them via SSH rather than http.


> Your SSH public key is really the least of your identifiable information you’d be worried about

I disagree. The article points to simplifications that SSH did compared to GPG, like no web of trust.

But there's now something very close to one, a bit hidden though: SSHFP + DNSSEC

I think a lot of people here may not be familiar with SSHFP records, so check https://fanf.livejournal.com/130577.html for a more detailed explanation.

It's more or less a work around the problem of initially trusting a key, by using SSHFP records to verify that the server keys are validated by the domain, with DNSSEC validating the whole thing.

When you can match server keys to domains and user keys to github users, you are just one link away from having a global picture of the web of trust.

EDIT: and I wonder how feasible it would be to do just that with a sniff of the initial handshake

> because that’s the easiest to create a unique key for GitHub

And how many people do you think have done that, instead of uploading the keys of the servers/laptops/etc. they use?

I hate to say this, but Bitcoin did it right: by having a discardable private+public pair of keys derived from a seed key, it prevents leaks of information by correlation based on the public key.


Thanks for posting this — it’s super-interesting. It seems as though it’s more about authenticating the server rather than the user, unless I read it wrong?

The setup process looks a bit crazy, so I’m hoping it’s gotten easier since 2014? I would love to test it out, but life is too short for the process they’ve outlined...


> It seems as though it’s more about authenticating the server rather than the user, unless I read it wrong?

You are correct.

> The setup process looks a bit crazy, so I’m hoping it’s gotten easier since 2014?

I don't think I used that in uni, so I can't tell you how complicated it was. It's just a nice didactic article that I found explained all the details.

In practice in 2021, you run a sshfp script on the server, and publish the output of the script on your DNS by adding a key.

If you use scripted DNS, it's a one step process, if not, a 2 step process.


> And how many people do you think have done that, instead of uploading the keys of the servers/laptops/etc. they use?

Equally they might use the same user name as on other services, thus making them traceable.

Ultimately if you care about privacy then it’s up to you, the individual, not to share that information or to provide anonymous information yourself.

Sharing identifiable information and then blaming the company you shared it with is like blaming the horse for bolting after you’ve intentionally left the barn door open. Sure it should be that way but ultimately it’s your own responsibility to keep your stuff safe.

I’d agree with your point more if you were advocating that documentation should be more explicit. Ie helping educate users into making smarter choices.


"If you need privacy then you shouldn’t be uploading to GitHub in the first place."

Nonsense. Would you say the same thing about a password? Would you make the same comment about a conversation over a messaging service? This is a configuration detail of an account setting -- not a blog post.

Privacy is not binary; there are many shades of grey. It is surprising that this is made public and while it is not necessarily wrong to provide this service (I'm fine with it; I see the utility) it is also reasonable to ask for a way to opt out.


> Would you say the same thing about a password?

Passwords are secrets. Public keys are not. So the comparison doesn’t work.

> Would you make the same comment about a conversation over a messaging service?

If it was a public messaging service like HN, or public comments on Twitter or Facebook, then yes.

> This is a configuration detail of an account setting -- not a blog post.

We could be here all day and night saying what this is or isn’t but it doesn’t address the point I was making. The moment you create a GitHub account you start leaking far more sensitive data than your public keys. Data that is far harder to create anonymously (unlike your SSH keys). Thus if privacy is a concern then you shouldn’t be using GitHub in the first place. Even git version control itself leaks information about you.

> Privacy is not binary; there are many shades of grey.

Ironic you state that when you’re the one applying privacy in a binary way. I’m saying the SSH public keys are a lower risk than other details you share in GitHub. Not that it’s a zero or 100% bad thing, which is the only pidgin holes you’re allowing for this discussion.

> It is surprising that this is made public and while it is not necessarily wrong to provide this service (I'm fine with it; I see the utility) it is also reasonable to ask for a way to opt out.

That’s literally the point I’ve been making.


> Passwords are secrets. Public keys are not. So the comparison doesn’t work.

These are not binary attributes. A public key absolutely can be a secret, and in many cases should be.

> If it was a public messaging service like HN, or public comments on Twitter or Facebook, then yes.

You're avoiding the question because in this case it isn't a "public messaging service." It's an attribute of an account configuration.

> Thus if privacy is a concern then you shouldn’t be using GitHub in the first place.

Nonsense. What if I use a private email for my github account? What if I only use private repositories?

You're repeatedly making an error of portraying privacy as black and white and it simply is not.

> I’m saying the SSH public keys are a lower risk than other details you share in GitHub.

No, you made a categorical, absolute statement that "If you need privacy then you shouldn’t be uploading to GitHub in the first place."

This statement is utter nonsense. Now you're just arguing that you didn't say what you actually said.

> That’s literally the point I’ve been making.

No, your statement that we're discussing was "If you need privacy then you shouldn’t be uploading to GitHub in the first place."

This statement is flatly incorrect. Your comments are demonstrably false, and your followups are irrelevant deflections.


> You're avoiding the question

I answered your question despite it being a straw man argument.

> No, you made a categorical, absolute statement that "If you need privacy then you shouldn’t be uploading to GitHub in the first place." This statement is utter nonsense.

Thus far all the arguments you’ve made have been either unsubstantiated or straw man.

Take the quote above, you argue it’s nonsense but offer zero evidence to back up that remark.

> Now you're just arguing that you didn't say what you actually said.

You’re changing the subject again instead of providing a counter argument. I’ve made my points clear, with examples as to why I’ve came to that conclusion, and there’s history of our chat in this forum.

This is clear an emotive topic for you but if you want to prove me wrong then please at least stick to the subject.


> I answered your question despite it being a straw man argument.

You didn't, and I think that's all that needs to be said. There's no need to address the rest of your comment. I don't care to engage in whatever it is you're doing.


Have a read of the following and then you’ll understand my frustrations conversing with you:

http://www.paulgraham.com/disagree.html

Thus far we’ve seen DH2, DH3 and DH4 but you haven’t yet refuted my central argument (nor even anything close to it) despite posting a multitude of emotionally charged paragraphs.

Now take a look at the discussions I’ve had with others in this thread. They’ve been on topic and informative. Unlike the responses from yourself.

I’m genuinely open to discussion, if you’re genuinely interested in having one.


You've seen only DH6, a direct refutation of your central point which I'll quote for you again: "If you need privacy then you shouldn’t be uploading to GitHub in the first place."

Take another look at your own responses, vis a vis that article. You and I are done here.


So you are just trolling me then?

Pity you couldn’t be bothered to hold a proper discussion here because some of your other posts in other threads have been informative. C’est la vie


Thanks for making this point clear. I think a lot of people have been clinging to the idea that there is such a thing as privacy with online public services.

The parents quote I think is illustrative

> But for the “average person,” security does equal privacy, or should, so they find systems that could potentially expose their identity to be “insecure.”

And I’m not trying to pile on here, because I sympathize with that sentiment of “should”. But I think the two issues that make that never a real possibility are 1) privacy is actually a harder problem to solve than security and 2) companies aren’t incentivized to provide privacy.

Anything you provide online should by default be assumed to end up public, and as much as we might not want that, we all really need to assume that.


They are complementary, though -- in fact, intertwined. You cannot have durable privacy without the ability to selectively secure information. And many security mechanisms (especially those that are digital) rely on a secret, which is sort of the essence of privacy.


Actually, GitHub now defaults to obfuscating email address and has an easily accessible option which will reject any push that inadvertently reveals it.

Also, plenty of people collaborate in private on GitHub. It has free private collaboration these days, not to mention.. paid. While it never strongly irked me that SSH public keys are visible, it’s not really that obvious. And I don’t buy the “but it has public in the name!” bit either. Sure, it’s not made to be confidential, but that doesn’t mean it should be published indiscriminately. I mean, I’m using it to authenticate to GitHub, and nobody browsing GitHub needs it.

Having them visible by default can be convenient. I’ve used it to populate authorized_hosts for example. However it is unnecessary and unexpected. If you use different private keys on each machine, it reveals a lot of opsec info you may not have expected to be public.

It’s a “public” key in the cryptographic sense, not in the address book sense.


It's visible so that your commits that are signed by that key can be verified by other GitHub users. There's an option somewhere in settings that makes it so that any commit from you that is not signed is automatically flagged.


Signing Git commits by SSH public key is brand new. GitHub has been doing this since before SSH or Git supported this.


My public key would still be published even if I only ever dealt with private repos, so this argument doesn’t hold.


You profile isn’t private - regardless of whether you contribute to any repositories (even just private) or not.


What would that "profile" show though, apart from your username? Email can be hidden, as well as contribution dates/volume to private repos.


Exactly the same as what the public SSH shows you: ie nothing of any direct risk but an identifiable piece of meta data to someone determined enough assuming the person creating that profile didn’t bother to enter anonymised information for GitHub.

So your argument against SSH keys are just as valid for all the other items of meta data you’re dismissing as not a privacy problem.

And that’s the point I’m making. If you care enough about privacy that your public SSH key is an issue, then creating a GitHub account is not the brightest idea regardless of their policy on public SSH keys.

I don’t disagree that GitHub could do a better job documenting this risk nor that an ideal scenario would be giving users the option. But they’re all just side stepping the real issue that this is not a privacy because of the fact that public SSH keys are not more of a risk than any of the other data you’re already volunteering to be published by virtue of signing up to a social platform.

If you want privacy then host your own git server (it’s really easy!) because GitHub is designed around sharing, not privacy.

It’s weird the number of people here who don’t realise that convenience and privacy are often opposing forces and I bet the majority complaining don’t even pay for their GitHub account. Yet they are still complaining about specific aspects of privacy while willingly handing over a crap load more identifiable information for free. The whole debate here screams of security theatre: privacy for show rather than actual safeguarding of personally identifiable data.


I'm not trying to say anything about public keys, you're the one who claimed:

> If you need privacy then you shouldn’t be uploading to GitHub in the first place. The moment you do that you’re publishing email addresses, other projects that you contribute too and potentially leaking your timezone by virtue of commit times.

You are wrong. GitHub doesn't have to leak anything, apart from your public SSH key.


You can go long way with an anonymous gmail address (this is what whoever from GCHQ do on their open source GitHub stuff)


You know, if I was 17 and bored, I’d look up all of the keys for all of the people from national security agencies that have contributed to open source projects on GitHub and see if anything noteworthy turns up anywhere.


Somewhat related: a friend of mine crawled across a ton of publicly available PDFs from several security agencies and found a lot of interesting metadata about their setup (stuff like OS version, word processor of choice, even the author's names in some cases).

https://therecord.media/security-agencies-leak-sensitive-dat...


What you describe isn’t possible since commits are not associated publicly with SSH keys in any way.


They are if you sign them...


you mean gpg sign? By the way the gpg public keys are also available via a URL. https://github.com/Larusso.gpg

Edit If course you mean the new signing feature which will come to git and GitHub in the future. Sorry


You're entirely right, just a brain fart on my part that those are different keys. Not sure why you're downvoted.


Its actually the same thing. A shared identifier. Of course email is another thing to separate for separate identities. But it is way more widely known that email adresses are used ad an unique identifier.


That’s my point though. If you’re concerned about privacy enough that even a throwaway SSH public key is sensitive then GitHub (and even any public git repository) is going to be a bad idea because they’re going to be leaking far more identifiable data than just your SSH public key.

If you agree that said platforms leak lots of other identifiable data (which you seam to) then thus it is a fair statement to say GitHub hiding public keys do little to enhance your privacy. And thus one can reasonably conclude that privacy argument doesn’t really hold with regards to SSH keys.

I’m happy to agree that it’s bad UX and probably should be advertised better so people are aware they should follow the (in my opinion best practice) of using a unique SSH key for GitHub.


You might have gotten me having this too narrow to be broadly useful. Because we were already arguing about a detail and I concentrate just on this detail, not a general github privacy overview.

The whole intention was to raise attention to a less often mentioned part of the information github exposes about accounts.


The crowd that needs privacy is also the most high stakes and vulnerable crowd. They are the people that may save civil society with a structure built by thousands of small stones. Dismissing concern in that area is inherently giving tyrants and aspiring ones power.


You’re clearly super well-informed about this problem space. I’d like to talk to you about this a bit more, if you’re up for it — shoot me an email (it’s in my HN bio).


Is that sarcasm?


Not at all! You’ve covered all of the major threat vectors that others would dismiss or not know about. You’ve got true expertise in this area, my friend.


I am just wary of flattery and "my friend". I am not especially suspicious of your motives but we don't know each other yet. If you want to have an interesting conversation with me I am positive to do that pseudonymously. Maybe leave me a pubkey here


  ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCalPlcbQUWX5caNedbKuWxAOUG+wFU2jtPUXmAcUDTIUgNz9JeW7cOAH1FPAcouIBM/0e48hdswSB2XHR0yHj3HvGx2KfB1lsd+FxXRR+dGPzO3WiMHXHdKogmHilk9U1ztwEFoZAkXuxvykv+Sn16j/xHXgFHdx5IDl/jyT5/IEIZHiePQqPYgptea/kXDiQGClMcT5V1bczCQH5tIcXdSKHhXn3oV1IAd79FpznmeCMALsyS4MUeU7uSx32PknIpgev64aMFgZItJUanqaeABuc9mcGNgHLBhBdO+gCOwBnwd+7boKmRawvMnEwsoznN9elr4FeBB81mBRnc6Q53 numair


(Don't expect realtime/neartime messages. I'll write whenever I feel like it.)

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCssSd91viJEmUQNx28L6JifYcGwTNEkLnmvZvdNxWxdTCrKwPEBVdlLooN90QugL/mJVwcWj9qsnOLbcoVaJlqMppY8UYlHP6OnGwKRGkpPdbKHnBA+Rrg7r8GUwdLW/PvI8DWhEPXzzWvrCNiESJWVdSCT2bTfAA3CQuPnL9cr5hcpw0i1jf7PBXRiVw2E2133KhEr91xNMH/jXh4jrly3J+kmBEmJcrkHNrHj0O8Ml+PmVQknq+tYT1DivnE2dxHoMkfdP0xP9yV9s0+7/JhU+tnXJ2+kaIOSpOOmhBPyjNYO6wkNvQh3aYzKrtcoOWPO2y56sfw9Uqlbpyr1ZU1 Gargyle


Great comment and a huge important point people should be aware of.

Related, VPN users can easily be fingerprinted if they are assigned unique certificates for each account.


To shortcut a lot of this developing twister of why people should use different keypairs for different ssh hosts:

Its a big privacy leak, not a big security leak.

Your Pubkey can be used to cross-match multiple identities. Example: You have different coding personae. One that is activist, one that is company-peon. Different accounts, same SSH pubkey in Github or other server with publicly listed pubkeys --> Same person confirmed.

As a result of this the information can be used to target each of the identities in a more precise manner. On the human layer of the security side: New phishing/deception/blackmail vectors.

On the organizational layer: we have to target these keybearer devices now.

Maybe it even helps in a cryptanalytic way in some weird exotic scenario but not substantially.

And of course separation of concerns if you have different keybearer devices.

(Also the famous Keysticks are a nice solution to that organizationally but they are an additional risk for big scale attacks by having biased RNGs. In the end its hardware and audits are just a voluntary thing by corps. They can always choose to hide things from auditors or do a compromised batch at their mercy.)


> Your Pubkey can be used to cross-match multiple identities. Example: You have different coding personae. One that is activist, one that is company-peon. Different accounts, same SSH pubkey in Github or other server with publicly listed pubkeys --> Same person confirmed.

Doesn’t GitHub only allow a key to be associated with a single account? After all, they use it to authenticate SSH pushes.

The privacy worry here is a little more esoteric —- your SSH public key could be used to cross match your GitHub user account with an account on a different system.


I am not sure actually because I do not have any persistent github accounts. I only do them in a throwaway fashion. (Of course Github is making that more annoying by the month, as every other bigcorp site.)


GitHub does require that SSH keys only be used by a single user account.

I shouldn’t have phrased my comment as a question: a former employer required that I use different GH accounts for different purposes, and it was a hassle to get local repositories to use the correct keypair. I recall being annoyed at GH at the time, but since your SSH key is used as an authentication mechanism on SSH pushes, they really can’t let a keypair be associated with multiple accounts.


> and it was a hassle to get local repositories to use the correct keypair

I agree. The way that I deal with this is as follows:

In my ~/.ssh/config I have content that looks like:

    Host gh-company-a
            User git
            HostName github.com
            IdentityFile ~/.ssh/id_ed25519_company_a

    Host gh-acme-inc
            User git
            HostName github.com
            IdentityFile ~/.ssh/id_ed25519_acme_inc

    Host gh-sponges-corp
            User git
            HostName github.com
            IdentityFile ~/.ssh/id_ed25519_sponges_corp
And then instead of

    git clone git@github.com:companya/foo.git
I'd type

    git clone gh-company-a:companya/foo.git
Likewise, instead of

    git clone git@github.com:acmeinc/baz.git
I do

    git clone gh-acme-com:acmeinc/baz.git
and so on.

With this way of doing it, the correct key pair gets used both for the initial clone and for subsequent pulls and pushes.

I suppose I could make a wrapper program that would take care of the substitution for me, to further reduce the amount of hassle. In fact I might end up doing that. I already have a few wrapper programs for various git commands.


I guess you also need

   IdentitiesOnly yes
in there.

Otherwise all your public keys will be tried regardless.


Another way is to set $GIT_SSH_COMMAND when cloning:

  GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519_company_a -o IdentitiesOnly=yes" git clone ...
and then set it in your checkout's .git/config for subsequent fetches & pushes:

  git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_company_a -o IdentitiesOnly=yes"


Right. They always use git@ instead of account@ and there is no further meta in the git remote url. (gut remote url is a funny typo)


Doesn't OpenSSH by default also send all your public keys to the server to see if it accepts any of them? That would allow the server operator to identify you if you aren't careful.


Can be configured in .ssh/config. Shortcut for that is to use subdirs or filenames for keys that arent searched automatically and not have a default-name-key.


>Your Pubkey can be used to cross-match multiple identities. Example: You have different coding personae. One that is activist, one that is company-peon. Different accounts, same SSH pubkey in Github or other server with publicly listed pubkeys --> Same person confirmed.

How to practically manage this, with git in particular.


You can configure which key to use when signing your work https://git-scm.com/docs/git-config#Documentation/git-config...

i see that the docs are missing info on ssh there still. i will update this since with 2.34 you can also specify a ssh publik key literally in this variable or point it to a file with it.


Ah, this is what I was looking for. Thank you.


Generate a different public key for each service. Don't use the one for github, etc., anywhere else.


OpenSSH by default tries authenticating with all your identities. You should probably turn that off too.


Or keep sensitive identities in a different location, so they aren't automatically picked up like that. That forces you to specify an identity file when you need one of those, but that small inconvenience is probably not a concern if the identity is that sensitive.


>There are cases where information [...] associated with a public key)may indeed need to be protected, [...] But public keys should be considered public without exceptions.

Your answer actually stumbled into the reason why so-called "public" keys may not want to be published. There are 2 different objectives:

- public key as part of a encryption pair : publishing this is no big deal as it shouldn't compromise SHA256 private key for decryption. So "security by obscurity" isn't necessary.

- public key as an identity for metadata/tracing : some may not want public keys to be known for correlation ... e.g. That's why Bitcoin wallet software generates new public+private keys for each transaction even though exposing a public key doesn't compromise ECDSA encryption.


I think the perception is that "public" for internet privacy realists means someone might know that, not everybody can know that at will.

To say it another way. Private means, only I know it. And public just means anything but private. With varying degrees of how public something might be.

Funnily enough that's very different from what ordinary people think private and public is.

Private is everything they didn't explicitly intended to be visible to all the people on the internet and public is only that.


I would respectfully disagree. While relying on hiding a public key is not a meaningful security barrier, obscurity is a threat reduction tool and limiting information, including keys on a need to know basis is a valid control that may also reinforce separation of duties.

For example, to access secure areas of my network, you need to access the management plane first, with a separately managed system. Look at how GCP manages ssh keys for web consoles as another example.


Would the average user of GitHub except their public keys to be actually available to everyone? I think not. I was surprised (but not necessarily concerned) to learn this. I think GitHub could be more transparent about what adding a public key implies.


Please post here all your public keys from pairs you use for SSHing to your servers.


I would but 2 of them are RSA keys and I don't want to make the comments messy.

Here's my ed key though.

  ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN3sRdLQYzhroFcUsId9X2xS1Um9bP0E+FiuiO5/qF5W oehpr
What's your point with this? Is there some factor I need to be aware of here? Other have brought up privacy, but I'm fine with my servers knowing I'm devious hacker oehpr.


Yes, I rhetorically asked for your public keys because they are personally identifiable data.

While some may be fine having public keys dissiminated publicly, other github users would prefer keeping this data private, as it can be used for looking up their real identities.


From the security perspective, they are public information. You shouldn't have any vulnerability created by exposing them.

From the privacy perspective, they are PII. You should not publish them or link them to any information.

"Public" is a very overloaded word.


I don't think it's super well known, but it is very handy. Used it in the past to give people SSH access by just asking for GitHub user, and then basically just doing `curl https://github.com/victorb.keys >> ~/.ssh/authorized_keys` without sending keys back/forward.

Keybase (or similar) would ideally be used for this instead, but they chose to go a very weird route for their tool, and are now disappearing completely eventually probably.


There is also a tool ssh-import-id. It could do the similar with the command "ssh-import-id gh:<github username>". It checks if key is already in authorized_keys, and it's handy if you want to run the command in idempotent manner. It's available in Ubuntu packages, don't know about other distributions.


Shouldn‘t you be using different keys for different services though? What you are doing sounds like bad practice.


Why? I think the best practice is that you should use different keys for different client devices, not that you should use different keys for different services. A separate key per client allows a service to ban individual client devices if they get compromised, there's no practical scenario where a client device would want to ban individual services.


> A separate key per client allows a service to ban individual client devices if they get compromised

This isn't possible with the "oh I synced your public keys from GitHub" pattern. The user might revoke a key later (we all rotate our keys every six months, right?), and remove it from GitHub but it can still be used to access your service.

Maybe this is OK if you sync from GitHub on every access request (or cache for a short period), using it as a poor man's OAuth, but that's not what GP was proposing.


Even if you had different keys to different services, you'd never revoke just one of those keys. If you're revoking a key because your client device was compromised: well, your other service keys on the same device are compromised too. If you're revoking a key because you regularly rotate your keys every 6 months: well, you're revoking all those other keys from all those other services at around the same frequency, separate service keys aren't helping you revoke less.

There's never a practical scenario where you'd just revoke one service-client key-pair while the other service-client key-pairs are totally safe. Imagine your GitHub-specific private key was compromised somehow - a private key that has never left your laptop that also stores private keys for all your other services - do you think it's safe to only revoke your GitHub-specific key?


This is exactly the problem. You need to revoke your key (maybe just one key, maybe lots of keys) but you can't revoke it from the new service, only from GitHub, because the process of authorizing you to the new service was append-only.


It's not append-only. No one is suggesting that any new service must only pull keys from GitHub once and then it never changes. GitHub is just a convenient source to bootstrap from.

You might need to go into your new service (possibly through another factor like physical access or web admin) and manually revoke compromised keys.

I just don't think any of this is a reason to have a separate key for each service you use, that still seems rather unnecessary.


Solutions:

https://gist.github.com/sivel/c68f601137ef9063efd7 - uses AuthorizedKeysCommand to make a remote server the authoritative source of your SSH keys, so (if you wanted to) you could make GitHub your key provider.

https://github.com/ierror/ssh-permit-a38 - 3 years old but that's not necessarily an issue

https://github.com/gravitational/teleport


but this is just a problem with copying the keys in general-- it has nothing to do with github specifically at all


You should use different keypairs per identity, and different secrets per service. However, when a service relies on public-key cryptography, there's no reason not to reuse the same keypair for different services.

If your private keys are stored on your local machine, chances are if one is compromised, all are compromised.


If you're following good security practices like...

* Using a strong passphrase on your private key(s) * Never copying your private keys around between systems (especially not unencrypted) * Using a hardware key management dongle

...then there is little to no _security_ risk in using one key for multiple services vs individual keys for each service. The threat model here is that an attacker is able to discover your private keys somehow. If the system holding the private key(s) is compromised, they can grab multiple keys just as easily as they can grab one.

Others have noted that there can be a slight _privacy_ risk to sharing your SSH public key across services. If you never want your accounts across different services to be correlated with each other, then yes, you would want a separate SSH keypair for each. But many of us use the same identity across services anyway as part of our personal brand so that point is moot for us.


I don't think using different keys per service or host buys you much in terms of security. Yes, an attacker that compromised your keys would have to brute-force your passphrase for N keys rather than one private key, but that just takes N times as long, not really an obstacle.

It would be better to use a hardware authenticator like a Yubikey to either generate a FIDO token-backed SSH key or a GPG key and use the gpg agent as your ssh agent. This way you get SSH keys that cannot reasonably be compromised by other means than physical attacks (someone steals your key and coerces you to reveal pin code).


The only issue I see with this is if/when you run up on someone with multiple keys, then you’re blindly taking all the keys and giving access to multiple computers.


github stripped the key names/annotations from .keys (for good reasons), so if you do that and you use one ssh key per machine, when you need to revoke a machine you won't easily know which key to remove from authorized_keys.


Even cooler, you can tell cloud-init to download your SSH keys from GitHub and drop them in the user's ~/.ssh/authorized_keys. Something like this IIRC:

    users:
      - name: foo
        ssh_authorized_keys: [gh:foo]


That was sarcasm, right? (Genuine question). 'cos that sounds like a bad idea to me, and if it's not a bad idea, I'd like to understand why.

Doesn't doing this mean you trust github implicitly?


I trust Github explicitly. Or in my case Gitlab, as that's where our code and our CI/CD is. I'll go even further and tell you that I'd trust the public key on Gitlab to be correct more than I'd trust the keys on my own hard drive to be correct. If I make a mistake in my opsec, and run for example a NPM package or Ruby gem or whatever outside of a container, I could have my keys compromised without me ever noticing. At least Gitlab will drop an e-mail in my inbox saying my key changed. Beyond that, I presume Gitlab is employing a security team that outclasses my little startup by orders of magnitude. If Gitlab gets hacked to the point where people's public keys get changed, that surely would be noticed very quickly.

Curious why you think it would be a bad idea to trust Github/Gitlab to warrant your identity.


Fair points. But git(hub|lab) has a much bigger target painted on their back.


It's not sarcasm. I only use this for hobby projects and I already put my source code and various secrets on GitHub so they could pwn my blog if they really wanted to whether or not I pull public keys from GH or bake them into my user-data.


Then this is bad advice in general because its specific to a low trust expectation. Would be sensible to note that in your comment.


it's not advice at all. they are just saying you can do it.


The parents comment style is inherently advice.


GitHub can alter the CODE. Why it should play with just a key? If GitHub wants to pwn the whole world, it can do it right now.


Well, github will already shut down repositories that contain words that they deem unacceptable. So they are doing it now...

https://news.ycombinator.com/item?id=9966118


GH specifically going out of their way to falsify keys of a user would be a much bigger breach of trust than just shutting down repos. They know ssh-import-id-gh is a thing and people use it.


Can't argue with that, except to say "because it's bad, lets make it worse" doesn't feel like a good rule of thumb.


I had a different concern... if people eventually start to use SSH keys to sign git commits, (as the article suggests will soon be possible), people can't validate github commit sigs with github public keys directly at one point in time... because if one is compromised, so is the other.

The only way github could be used as key distribution for this purpose would be if individuals take (and keep) a copy of every public key they are interested for future verification in-case an attacker changes it. But then I guess any public key distribution system has this problem??


Bootstrapping is always a harder problem. But for updates, guix git authenticate [0] has definitely solved the problem. The idea is if you specify a certain commit that serves as a trust anchor, the .guix-authorizations file at that commit represents the public keys allowed to sign commits from that point: the file can be amended only by an already-approved key.

So if the repo has that file, and as long as you don't allow history rewrite when pulling (disabled by default), you can be pretty confident all commits have been signed only by authorized keys from the point you checked out initially.

About bootstrapping, several strategies are possible:

- [crev](https://github.com/crev-dev/cargo-crev) is an alternative (not PGP/SSH based) web of trust for vetting code

- [radicle](https://radicle.xyz/) is a p2p forge to do away entirely with web-based centralized forges (like github)

- we could imagine a sort of public-key-addressed DHT where a forge (such a Github) advertises the public keys of its members, for example based on IPNS (although a history-preserving system would be better)

- of course source-based distros like NixOS and GNU/guix are also a very good answer about bootstrapping trust in the code you run ; guix in particular does intensive research and development about bootstrappability and reproducibility [1] which you can read about on their blog [2]

Shameless plug: i wrote an article earlier this year about some of the challenges surrounding decentralized forging: https://staticadventures.netlib.re/blog/decentralized-forge/

[0] https://guix.gnu.org/en/blog/2020/securing-updates/

[1] I'm personally really amazed and slightly disappointed by both: they're really cool on paper, but although guix has a much better CLI UX than nix (and in my opinion Guile Scheme is much easier than nix programming language), both have very cryptic errors

[2] https://guix.gnu.org/en/blog/


How does this work for key revocation?


From the blogpost i linked:

> Since .guix-authorizations is a regular file under version control, granting or revoking commit authorization does not require special support. In the example above, commit B is an authorized commit by Alice that adds Bob’s key to .guix-authorizations. Revocation is similar: any authorized committer can remove entries from .guix-authorizations. Key rotation can be handled similarly: a committer can remove their former key and add their new key in a single commit, signed by the former key.

I'm unaware of the implementation details, such as whether git will validate sigs for a PGP key which has been revoked. That's a fair question, although for this usecase i can't imagine how it would be useful to deny signatures from the entire project's history because a key has been revoked.


This seems like it would work, but requires a centralized point to enforce it. Otherwise, it seems that you could trigger a "split brain" scenario where in one repo a key is revoked by a malicious user, and in another the malicious user's key is revoked (or development continues). Which lineage is correct?


Ideally GitHub or any key distribution server just works as a dumb registry, the trust should flow from different systems. Of course in practice people just rely on the registry anyway.


It's a very convenient way of distributing your public key.


We've implemented a DID method based on this!

https://github.com/spruceid/ssi/tree/main/did-webkey


How does it work from a client perspective? Are there any browser (or browser plugin) supporting it yet?

On paper it sounds pretty cool, i would dare say the only interesting application for DID i've heard so far :)


And similarly GPG keys are at github.com/username.gpg


This seems more legit. If a user is signing their commits, other users should have access to their public keys in order to verify the signatures.


Usefulness of that access from the same service you're getting the signed commit from is close to nil.

Public keys should be distributed in a trustworthy way.


They do seem to strip the name of the keys which I am thankful for.


It's a good idea to keep your public keys private. You can do this by using a different key for each purpose, and by explicitly configuring (in ~/.ssh/config) which key to use for which purpose.

By default, the ssh client will try to each of your public keys to connect to any given server, which naughty servers can effectively use to enumerate your identities.

Services like Github really shouldn't publish these keys without consent. One could argue they're really PII and subject to privacy laws ..


Maybe this needs more precise wording. Like ingress/signature key but more compressed instead of public key. Or peer key. Any nice ideas?


That's a good point. The wording makes sense from a cryptographic point of view, but it doesn't really convey the full meaning outside of that context.


This can be a security risk if you're using the same SSH keypair for other things, and you're using a less secure algorithm than RSA or ED or similar. Anyone doing a bit of research about you might discover a vulnerable host for which the vulnerable algorithm keypair might be targeted


When that happens you were relying on security by obscurity. It’s a hack waiting to happen. This, at least creates awareness and forces secure keys. But you are right, it may be a security risk, but only when it already was (arguably it was smaller).


It's one of those tricks that's not super well known but a decent few know it - The Ubuntu server installer will ask if you want to import your ssh keys from Github, for example, and there was a Show HN[1] with a cool trick[2] that took advantage of this information.

[1]https://news.ycombinator.com/item?id=10004678 [2]https://github.com/FiloSottile/whoami.filippo.io


Why would you want to disable it? They're not 'scare-quote' public, they're just public - analogous (kind of craply but workably) to 'distributing' your face, but not your passport/driving licence/etc.

The private key part is secret of course, never shared (that's where the analogy above breaks) but the public part is fine and desirable for everyone to have access to - that's how they verify that you signed something with your private key, how they encrypt a secret message to you.


Because they may be used to learn the identity of an otherwise pseudoanonymous github account if one uses the same keys with another account that is tied to his real identity.


If the account is intended to be anonymous, it should have its own keypair not shared with the real identity (or other independently anonymous account).

I say this regardless of whether public keys are being.. publicised. User database could be leaked, say, or public keys visible to employees/logged. OpenSSH literally refers to them as 'identities' - if you're trying to be anonymous/anon w.r.t. another it goes without saying that you need to not use the same identity!


One key per service. I've got a directory full of them and a long .ssh/config


I don't much want my face automatically associated with my GitHub (or other) account, either.


I think it's this feature that Ubuntu integrates into their install process, so you can add your GH keys for SSH auth. which is v.useful.


Could you expand on this a bit. Where does Ubuntu ask for your github username?


When installing new system, there is an option to input your github/launchpad username

http://manpages.ubuntu.com/manpages/bionic/man1/ssh-import-i...


Where I see it is in the interactive installer for Ubuntu server, there's a screen that asks if you want to install SSH on the host and then it asks if you want to import keys from GH. You pass it a GH user name and it lists the keys to be imported.


ive seen it few days ago while using the installer on the netinstall iso.. its an option to import keys from github while creating the regular user...


Yeah, I use that more than I really should - it's way easier to slightly change the URL in my already open github tab than scouring my disk for my or someone else's keys.

New versions of Ubuntu Server will actually let you import keys from GitHub during setup. Really handy, although obviously not something for highly secure environments.


At least they have filtered out the comment part, so that e-mail addresses and computer names can't be scraped.


This seems to have been public for quite a while. It's also how Userify.com imports public keys from Github.com for years (and also imports from Gitlab.com, which copied Github's approach.) For some reason, Userify itself doesn't also allow easy export of its users' public keys.


That's how I give ssh access to collaborators on VPS, add people to blackbox in git repos or share encrypted files with them.

It's pretty great.

I forgot where I learnt about it; I think I was inquiring how NameCoin was able to gift their cryptocurrency to GitHub developers with more than 50 followers.


It is the magic behind fast ubuntu server install: if you provide your github username, the cloud installer will pump keys on your default user and you will be able to ssh to the new server without a display.


It’s very handy. I use it often. Whenever I, or someone else, need to add my public key to a server somewhere, that’s where I get it from.


Are you guys really using one SSH key for all services? That‘s really bad practice.


No, it’s not. It’s not the same as reusing a password, because unlike a password, your private key never leaves your local machine. It doesn’t matter if one of the services that you’re using the key pair to authenticate to is compromised—your private key is still safe.

In order to compromise your private key the attacker would have to gain access to your local machine, in which case all of your private keys are compromised.

You should use different key pairs per client, so that if one client machine is compromised you don’t have to change keys on the rest of them.


You can put multiple SSH keys on GitHub.


Not what I am talking about.

I am talking about using the same key pair for two different things. E.g. GitHub and GitLab


What attack vector do you think this would mitigate?

You'd need several prerequisites for that to actually increase security, i.e. not using an ssh-agent (required password for every key prompt) and encrypting them at rest

Otherwise you'll leak all your keys as soon as any attack vector is utilized such as hostile host siphoning from the ssh-agent forwarding or filesystem access.


I want to be able to revoke individual keys. If I want to invalidate my key for any reason, I don‘t want to have to change it for everything.


but why do you want to do this.

there is no security benefit from revoking individual keys unless they've been compromised - however, the likelihood of only leaking a single key is extremely unlikely.

There are very few attack vectors how you can compromise a private/public key pair and they all basically boil down to local access. This is not a PreSharedKey situation like a password, where both parties effectively share a single string for authentication. The private key never leaves the authenticating machine, as you're only sending a signature over which will be validated against the public key. So, how are you going to compromise a single key that splitting them increases your security?

you're either completely compromised and somebody has filesystem access or you've forwarded your SSH-Agent to a compromised host. When its the former, you'll have to have the private-key encrypted so they're unable to use them (encrypted at rest) and when its the later, you cannot have your keys added to the agent, making the forwarding redundant in the first place.


Using different keys for different services is overkill most of the time.

Generally you need to have one key per host that you use (or per any storage location). You can use separate keys for separate services is if you for eg. privacy reasons don't want to associate the same identity with both services, but that's a personal choice, not something that improves security.


I am. My ssh key is my gpg auth key. It's stored on my yubikey requiring a touch each time I use it.

I use the same gpg key for talking to anyone, so why wouldn't I do the same with my ssh key? I suppose I could try to build a workflow around host-specific keys somehow derived from my auth key… but I'd need some reason to do so.


The Ubuntu Server installer has used this trick for a while to allow people to get their SSH keys imported during initial setup.


Why shouldn't they be? Public keys are perfectly safe to be shared publicly. Otherwise RSA would have very limited value.


Just use a public key for github alone. I tend to use a public key per-application.


Is it just me or can we not see out public keys in the settings page by design?


Do you hide your main door keyway?


Slightly related, but I use age[0] for most of my non-automated file encryption tasks; and one of the neat features it has is the ability to encrypt to a GitHub user's pubkey[1].

[0] https://github.com/FiloSottile/age

[1] https://github.com/FiloSottile/age#encrypting-to-a-github-us...


I think one of the most compelling reasons of using ssh for signatures is the possibilies of ssh-agent and especially agent-forwarding which allow for incredibly portable workflows like ssh to a ci/build host/container to sign some production binary/container/tag.

Please note that these come with their own pitfalls and precautions you'll need to take to ensure your key's safety!

If you consider agent forwarding i'd recommend use of "ssh-add -c" to have your agent at least confirm every use of your private key. Generally for private key security i'd always use a hardware token. Modern yubikeys are really easy to use and you can even enable touch policy instead of the agent confirmation. The UX for this is still a bit lacking in the tooling though.


Looking forwards to when this gets added to git in v2.34. Setting up pgp for commit signing is such a pain. Yet since ssh is installed everywhere and I'm using it for git anyways, that's one less setup step to worry about.


Is it a pain? At it's most basic, it's just one line of config in .git/config. The hard part is keeping track of historical keys and revocations, so that historical commits can be validated if they were made before (but not after) a revocation. And when that happens, you immediately run into the problem that time information in git offers zero security, and that the whole operation is moot.


Ledger/Trezor have solved this since ~2016. I have a Ledger that has a private key inside and using a small open source tool (https://github.com/romanz/trezor-agent) I can SSH into machines, sign random data and Github commits and FIDO authenticate into several websites. All of that and knowing that these devices offer some of the best security out there.


Hardware devices like the crypto wallets are a pretty good solution (no pun intended), imho. Both very convenient and very secure. I like the minimalism of something like the Trezor, no battery, tiny B/W display and two hardware buttons. Plug in, click button to confirm signing, done.


FIDO2 is even better because SSH supports it natively, so there's no setup at all.


> SSH public keys are one line strings that are easy to copy around. You don't need to use the Web of Trust

PGP public keys you can also just copy around? Nobody is forcing you to use the web of trust with PGP either, if you don't want it. But if you do use keys extensively, it actually helps you: if your boss already verified a customer key, you don't have to re-do the work and meet up in person or ask your boss to send it over before you can use it. Now extend that to a whole network of colleagues, where you configure per-colleague whether you think they properly verify other people's keys, and this whole key distribution problem becomes a lot easier without having to rely on third parties (CA system like with https).

Just a small note, this obviously doesn't invalidate the rest of the article!


On the other hand, it's very easy to "leak" keys into keyservers by one mistaken command with GPG.

Maybe you have backup signing keys or whatever secret project encryption keys - and you would prefer for privacy and obscurity that the "public" halves are not distributed on keyservers.

In this sense, I think GPG continues the culture of a more naive and smaller internet by thinking that most keys want to have their public part online.


I think one problem with using ssh key instead of gpg/pgp key for signing data is key to people mapping, for lack of a better word.

I can't speak about others, but for myself I use a single gpg key across all my machines, but I use one ssh key for each of my machine. When I replace a machine with a new one, I don't move/transfer that key to the new machine, I just generate a new key on the new machine and revoke my old key everywhere. To me a ssh key does not map to me, it maps to me and a machine combination. If I use an ssh key to sign something then after a few years I replaced that machine, that key is no longer used anywhere, and the verification can start to become tricky (I'll certainly remove it from my github, which invalidates the key distribution way proposed by the article).

I also always use name@machine to name/annotate my ssh keys, but github's name.keys strip that info (for good reasons).

So this is probably good for short lived signing needs, but for something that needs to be verified long into the future (git commits/tags), I don't think this is a good idea?


Apparently "Signing a file is straightforward" heh no, this can not be said to improve upon GPG's interface(*). But it will be cool to see where it can go.

(*) Hiding signing behind a command that's called keygen is not the interface we deserve.


So a little offtopic but I’m still curious: how do you handle multiple machines and SSH keys? I mean do you run ssh-keygen on a new machine and have for each computer a separate key pair or do you have one key pair that you copy on every new machine?

I have seen both and using one key pair looks very convenient but also makes me feel a little uneasy.

I myself have a key pair for each of my machines.

How do you handle it?


You can avoid specifying a lot of parameters at each SSH connection by defining aliases, e.g. of the form ssh-servername.

In each alias you put the appropriate "-i private_key_for_that_server", the server name and also "-l user_name" if you have a different user there and "-p port" if the server uses a non-standard port.

Thus, after the initial key setup, connecting to any server with different credentials is no more complex than when using a single key pair.

Except for an extra keygen step, the initial setup is not more complex than when using a single key pair, as you have to copy the public keys anyway, which is the more difficult part of the setup.


You might want to look into using .ssh/config instead, as it is built into SSH. In addition to letting you specify keys/usernames for arbitrary hosts, you can also use rules for wildcards, etc.


Shell completion over ssh is one of the really nice benefits of sshconfig. I’m not sure if this is zsh specific though


It’s definitely not, I use bash and completion works great. I’d be surprised if there was a major shell that was not supported.


With ssh-agent, up to five secret keys are tried (that’s a magic number on the server side). After five, I guess you must specifically maintain which secret key is used for each host or hostname pattern.

If you frequently move between workstations, maybe look into the new hardware key features (Circ’s version 8.3). If you have multiple users that all connect to the same account, a SSH CA (circa version 7.4) would permit new access without needing to constantly modify server-side authorized_keys.


I have one key pair per machine and service. About 20 pairs on my laptop, 15 on my desktop.


In the past I’ve used a certificate authority for ssh setup as one nice way to stop the proliferation of ssh keys. The other route is to use one hardware key fob with a gpg identity on it and use that as your global method of access.


I use two keypairs, but with no ability to read the private key (smartcard).


This is what I do as well. Yubikey configured as a smartcard running gpg-agent with enable-ssh-support.


You can actually use openssl with RSA keys generated by ssh-keygen to sign also, and this has worked for a long time.

https://www.linuxjournal.com/content/flat-file-encryption-op...

You will have to generate an openssl-compatible public key:

    openssl rsa -in ~/.ssh/id_rsa -pubout -out ~/.ssh/id_rsa.pub.openssl
To sign:

    openssl dgst -sha256 -sign ~/.ssh/id_rsa -out known_hosts.sha256 known_hosts
To verify:

    openssl dgst -sha256 -verify ~/.ssh/id_rsa.pub.openssl -signature known_hosts.sha256 known_hosts
Here is a little script to automate this:

    $ cat rsign 
    #!/bin/sh

    set -eu # http://redsymbol.net/articles/unofficial-bash-strict-mode/

    case "$(basename "$0")" in

    rsign)
      for n
      do openssl dgst -sha256 -sign ~/.ssh/id_rsa -out "$n".sha256 "$n"
      done ;;

    rchek)
      for n
      do printf "$n "
         openssl dgst -sha256 -verify ~/.ssh/id_rsa.pub.openssl \
           -signature "${n}.sha256" "$n"
      done ;;

    esac



    $ cp /etc/passwd /etc/group /etc/hosts .

    $ ./rsign passwd group hosts

    $ ls -l *.sha256
    -rw-r--r-- 1 luser lgroup 256 Nov 12 13:21 group.sha256
    -rw-r--r-- 1 luser lgroup 256 Nov 12 13:21 hosts.sha256
    -rw-r--r-- 1 luser lgroup 256 Nov 12 13:21 passwd.sha256

    $ ln rsign rchek

    $ ./rchek passwd group hosts
    passwd Verified OK
    group Verified OK
    hosts Verified OK


A major problem with doing this is that you have to worry about cross-protocol attacks because there is no namespace parameter like there is with SSH signatures. SSH signatures provide the necessary structure to safely use a single key for multiple purposes.


It's true, I do remember the DROWN exploit relying upon keys presented over differing protocols.

It doesn't take long to generate an RSA key, though. A dedicated signing key would seem to be the obvious thing to do.

https://en.wikipedia.org/wiki/DROWN_attack


Also, ssh keys are not really supposed to be portable across devices like an identity is... YOU (a person) could/should have multiple ssh keys. You have the one your laptop, ipad, phone, work, all bound to an identity. You don't want to use the same key across multiple devices or locations.

PGP ironically, got this right... and has a nice solution for this, where you can have multiple authentication subkeys tied to a single identity, each individually revokable, plus with key transparency when on is added/removed.


A reason SSH proliferation and lack of persistence matter so little is that that traditionally, SSH keys are used for transient session data authentication, encryption, and decryption, not for continued auth/decryption of PERSISTENT data.

In the case of SSH, if a key is lost or compromised, no big deal: create a new set of keys and distribute the public key(s) to system(s) for which you wish to authenticate to. There's also no need to use the same key for different remote systems --- you can use specific keys only for a specific remote system (making an adversary's task of determining what remote systems you connect to, based on public keys used on such systems if obtained, a bit harder).

The use-case for PGP was meant to be encrypting or authenticating (signing) data which would need to be accessible and/or validated from that point forward. If the sender's public key, or receipient's private key, are not available, valid, or uncompromised at some future time, then the data are either unreliable or unavailable.

Using SSH for more durable cryptographic transactions is convenient. But it also changes the use-case and environment around SSH. That will have side-effects.


^ Well said


Please consider donating to the OpenBSD Foundation (OpenSSH project)

https://www.openbsd.org/donations.html


Great idea: easy key distribution and management. Like most p2p ideas, PGP also sucked at this.

Terrifying idea: trusting a third party to maintain the metadata about a key and who's identity it represents.

PGP absolutely got this part right: if you modify the contents of the metadata, the hash changes. Basically, if a private key were to point to Myself, and I distributed it widely, then lost it... an attacker who recovered said key could _transparently_ change the identity of the key and we'd have no record of who was actually correct. And lets not pretend that a government couldn't coerce Github to add an ssh identity to your account (it is owned by Microsoft now, and they have DOD contracts to fulfill).

Keybase solved both these issues: easy and intuitive, transparent proofs, along with the rigidity of metadata with pgp keys: if a key owner changes, the pgp key mutates.


Are there resources on the impact of Keybase being bought by Zoom? Zoom is out of question too because they discourage e2e and darkpattern you into installing their software despite browser compatibility and because they darkpattern you into giving cam/mic access just to listen to a broadcast-only session even if unnecessary. They place their own controlled device toggles as source of truth instead of those by the browser UI and fail in weird ways if you toggle in-browser. (Same for almost all other similar software as well)

I tossed them without a second thought after they annoyed me with Stellar. Nobody uses Stellar if they dont have a hidden incentive. It always had a huge forced marketing vibe.

Is there some sucessor to keybase?

(Motivation disclaimer: I want to dump on Keybase because in the end, even with flawless crypto at first, those organizations always erode the good things down to centralized with platform control again.)


> Is there some sucessor to keybase?

Depends on the use case. E.g. for raw identity proofs https://keyoxide.org works well but it's not as straightforward to use as Keybase.


> if a key owner changes, the pgp key mutates.

How does Keybase address this problem completely? If an attacker gains possession of a key, they don’t have to change ownership, they just assume the role of that user. NB: I know they could feasibly only do this once before the key is considered burned by detection from the original user, so I’m somewhat lost here. Presumably you could mean that revocation of a known stolen key would be easy to point to, but any PKI can handle this.

Edit: I’m aware of Keybase itself doing per-device salts, but under a sophisticated attack, I don’t see a workaround here unless they’re doing some multi-party signing process with authorization against the Keybase server who acts as a second party, but even then, a sophisticated attacker who has control of the user’s machine impersonating someone would still be able to circumvent this.


If you have a PGP key bound to your email: yeehaw@woot.com and you change the email in the key to: haha@yougotserved.com it produces a definitive hash change, while the underlying key material doesn't change.

Contrast that to an ssh key, which has no bound metadata.

And to your point, both systems in isolation are useless. But the first, combined with proofs and a distribution point like keybase, form a complete system. The second however, ALWAYS relies on a trusted party not doing bad things.


Right, I guess what I was more critical of wasn’t a hash confirmation of associated data — it’s more the trivial bypass of this when the key is compromised in the first place. Theoretically, a user doesn’t export their key, or if they do, it’s under a tightly controlled manner which limits surface area for exposure to only the source and destination. So in this scenario, the only way a private key is exposed is if one of the user’s devices is compromised, in which case the promise of associated data is meaningless.


> PGP absolutely got this part right

Lol no.

There is no mechanism to invalidate keys by the domain owner, while it uses email as one of the core identifiers.

I purchased a cool domain, which had PGP users who published their keys to various key servers.

Their keys have no expiration, while I'm in control of the domain...

PGP was good, 30 years ago. But technology has evolved, along with the understanding of the problem.

I made a reply about SSHFP records (https://news.ycombinator.com/item?id=29212552), to push server keys in the DNS: that + DNSSEC means you remove the problem of initial trust (deciding to add a server to your known_host on the first connections)

Now imagine if something like MX records could also contain SSH keys for the mail users: you'd solve the problem of mail encryption on a global level.

People who want to send me encrypted mail could ask my server for my key, DNSSEC would prevent tempering with that, and if I lose access to the domain, there would be no issue with stale keys from old PGP directories.

As for scalability issues, DNS is perfectly done (with caching, etc) to handle that easily.

Like you, I could say "SSH got this part right" - but no. Again, technology has evolved.

The "only" problem would be correlation attacks, and I think that's a big one, in the age of surveillance.

Ideally, we'd have something like bitcoin key-derivation from a seed key, where you'd have:

- a key you publish to receive encrypted email,

- derived public keys, one per server, so that you do not risk correlation attacks

This is a great article, because it looks at the ubiquity of SSH keys, and how the technology is better than PGP keys, to advance the problem - say by signing git commits and tags.

I hope we'll also use the advances from other technologies.


Here is an example of how to change the email address associated with a OpenPGP identity on a key server:

* https://coderwall.com/p/tx_1-g/gpg-change-email-for-key-in-p...

If you want to invalidate the identity entirely you just upload the revocation certificate.


I don't think you understand: the key is not mine, it's from the previous users of that domain, so I can't apply these instructions as I don't have their private keys!

To make things worse, there is no mechanism to let the key server know that the emails associated with these keys are invalid.

And I have tried my best to get in touch with maintainers to explain the stupidity of this situation, but there is apparently no way besides revocation certificates to deprecate or delete a key. Or, if I give a less generous interpretation, maybe they want to keep pretending that PGP still has a lot of users?

So a known bad key is associated with my domain, with no way to fix that - except maybe waiting for PGP key servers to die and be finally replaced by something better.

This is why I call that an outdated technology. I'm sure it was good 30 years ago, but it should have evolved.


> Now imagine if something like MX records could also contain SSH keys for the mail users

Unfortunately that leads to this: now imagine said MX servers were under whatever political party you oppose.


> Unfortunately that leads to this: now imagine said MX servers were under whatever political party you oppose.

Hmm, what could I do?

Maybe change my MX records to move from mailgun to postmark or any other mail provider? Or self host?

But that's if we assume the key servers would have to be the same as the MX servers, because of some technological limitations.

Alternatively, it could be done like SSHFP where SSHFP records exist independently from the CNAME records: then the problem disappear, as you as the domain owner can delegate the MX part to one company, while only entrusting yourself with the publication of the public keys.

If you mean "but what about gmail users" - if gmail servers are under whatever political party you oppose, you've got a much bigger problem, and I don't think there can be a technological solution.


So many people in this discussion talking about how this isn't a true alternative to PGP while ignoring the fact that gnupg and all other PGP software are a giant usability trainwreck.

The PGP web of trust is as good as dead, and denialism around the usability issues in gnupg is mostly to blame. If we want people to use a decentralized web of trust solution going forward, it's time to accept the fact that we'll need a new set of clients and usability/accessibility standards.


>The PGP web of trust is as good as dead, ...

I don't think the thing you are referring to ever actually existed. Just like in real life you would trust someone just because someone you trusted trusted them. This is a common strawman and does not represent some sort of weakness in the relatively straightforward certifications provided by stuff that supports OpenPGP.


Cryptographic Trust /= Trust in persons motives.

I guess we need better words.


Of course I would trust someone if someone I trusted trusted them - subject to some obvious limitations. That is the essence of a social network. A cryptographic representation of that network is a profoundly powerful concept. But OpenPGP/gnupg are bad tools to represent it.


SSH tooling does not make that any better tbh.

Things are being worked on.

Watch Sequoia.

Maybe some things regarding UX on my radar will surface in a range of <2 years.


The ssh-agent protocol has always had the ability to sign data. It sounds like the new part is being able to verify signatures without needing the private key.

If you give ssh-agent some data and a public key then — if it has the corresponding private key — it will return a signature for your data using that private key.

The protocol command is SSH_AGENTC_SIGN_REQUEST and it’s the bread and butter of how the agent does its job.

Historically, it’s not tractable for public sign/verify but you can use it as a way to do symmetric encrypt/decrypt with ssh-agent.


It hasn't been able to do it in a meaningful way.

I've been patching support for this into ssh-agent for about a decade. I wrote a PKCS#11 module which talks to the SSH agent socket to forward your smartcard [0]. Doing so requires three changes to the protocol:

1. The ability to sign arbitrary data and get back the signed result [1]; normally you get back a hashed result [2].

2. The ability to decrypt data, this is what you said. This is less important since many things only require signatures (and not all algorithms support encryption/decryption).

3. The ability to request your certificates [3] [4] this one is kinda obvious.

The benefits of this are that you can use your smartcard on the remote host to do fully authenticated password-less sudo with pam_pkcs11. You can also do anything else that requires you to use your private key to be used, which can include fetching files (TLS client certificate authentication).

Within the US Government, passwords have been being phased out since 2004, but the requirements for authenticated privilege elevation remain.

Another way to accomplish this is to use SSH forwarding of your PC/SC socket but that's less portable and more fragile (and even less secure).

[0] https://github.com/rkeene/ssh-agent-pkcs11

[1] https://cackey.rkeene.org/fossil/artifact/0d0e90bbfdee672c?l...

[2] https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent...

[3] https://cackey.rkeene.org/fossil/artifact/0d0e90bbfdee672c?l...

[4] https://datatracker.ietf.org/doc/html/rfc6187#section-2.1


Is there a benefit to using ssh-agent in this way instead of using gpg-agent as an ssh provider?


You get X.509 certificates from the smartcard which can be used much more widely than GPG


Have you published your ssh-agent patches?


Yes, though primarily forge.mil as a patched OpenSSH source. It was based on an original PKCS#11 support [0] [1]. An old version of the patch is pretty small and available here [2].

Additionally, I wrote an SSH Agent (in JavaScript, for ChromeOS, but works on any platform) that has these modifications [3]. I use this more frequently these days (via Tcl [4]).

[0] https://marc.info/?l=openssh-bugs&m=119214228626872

[1] https://rkeene.org/viewer/archive/openssh/openssh-4.4p1pkcs1...

[2] https://rkeene.org/viewer/archive/openssh/openssh-4.5p1-pkcs...

[3] https://cackey.rkeene.org/fossil/artifact/0d0e90bbfdee672c

[4] https://cackey.rkeene.org/fossil/artifact/183583332c474aa9


Thanks!


The use of ssh-agent may be forbidden at some places, even on personal machines. I knew a few. And not that it's completely unjustified..


How about gpg-agent? Is that forbidden?


Nobody used or asked about gpg-agent back then ) The point about ssh-agent was that it stored personal keys in memory of machines shared by multiple users (admins, shifters, devs). So everyone had to type in passwords for every "ssh" )


Is it a good practice to use only one SSH key pair or different pairs for different things? Also, how do people usually store SSH keys for long term?


I use a different key pair for every service. Where "service" is defined pretty loosely. All the company servers I access for work, for instance, use the same key pair. But I have different key pairs for github, gitlab, etc. I also have a work github account for FOSS contributions, which uses a different key pair than my personal github account.

I have a config file per identity (work, personal, second job, etc) in ~/.git/config_$identity. Each of those files contains a Host entry with key configuration for every service I use. I rely on a bit of shell foo to to select the correct identity (an environment variable and an alias).

Life would be a bit easier if ssh_config supported the use of variables in Include statements, that way I could just Include ~/config_${identity}. Oh well.


This has been possible for a long time using a combination of OpenSSL and ssh.

To sign: openssl dgst -sha512 -sign ~/.ssh/id_rsa file > file.sig

To verify, needs converting the public key (who.pub) to something OpenSSL can grok:

ssh-keygen -e -f /tmp/who.pub -m pkcs8 > /tmp/who.openssl.pub

Then verify: openssl dgst -sha512 -verify /tmp/who.openssl.pub -signature file.sig file


What you get with this over monkeying around with openssl (other than having to deal with two tools with awful command line argument UX instead of just one) is that you can use ssh-agent to do the signing, which means you can also use tokens and such.


We use openssl to encrypt our passworddb using SSH pub keys. Works nice in scripts. Wonder why we need the new command line.


Is this the same AGWA that made git-crypt? I look forward to being able to encrypt the repo key to SSH keys, rather than GPG ones.


Yes it is, and they are awesome. git-crypt[0] is a godsend for smaller projects (and maybe larger ones if permissions are granular enough) -- way simpler than sops[1] and other alternative, with native integration via git filters (smudge). I use it on a ton of projects.

[0]: https://www.agwa.name/projects/git-crypt/

[1]: https://github.com/mozilla/sops


Same, I love it. The GPG bit is the only inconvenient part.


It's great that you can do this, but why stuff this functionality into ssh-keygen? A command called ssh-keygen should only do one thing: generate keys. The command for using an ssh key to sign something should be ssh-sign, especially since one of the ostensible design goals here is to get away from PGP's horrible UI.


ssh-keygen already does a bunch of other stuff, though it all relates to manipulating and using keys. It should probably really be renamed ssh-keytool or something.


He’s right, SSH is widespread and easy enough to understand for, at least, programmers. It makes for an excellent tool for signatures. Public keys are easy to upload everywhere. And you pass much less as a nerd as when using PGP.


I actually always feel kinda cool when using PGP.


Nerd.


I have my gpg key stored in my yubi keys and use those for SSH so does that make me a super nerd?


Probably, I did that too, but I wish I could switch to FiloSottile's age. However age still says in the docs:

> SSH keys held on YubiKeys can't be used to decrypt files.

So I'm stuck with gpg. I don't want to store my private keys as a file on a computer just to decrypt stuff.


Same. Imho it’s the best solution we have right now.


Only if you use monkeysphere and fwknop.


This was a problem I’d really hoped Keybase would solve. Thanks Zoom. Whenever I rebuild my Mac I seem to inexplicably have endless problems getting GPG and Git to play nice.

I quite like the idea of using my SSH Keys for this use case as it makes setting this up incredibly simple. I seem to spend a non zero amount of time helping developers and QAs at work setting up SSH Keys for GitHub, I might as well get them to sign commits at the same time now.


That's cool. I didn't know ssh-keygen could do this, but, to be honest, the UX of gpg is a step better as it manages the "allowed signers" file. Not that ssh-keygen couldn't do that, but it seems to be minimal design (which is fine and right for that tool).

Also, article is biased toward pki (vs web of trust) and tries to pass off github as a type of 'cert authority'. ssh signing is 'web of trust' but it leaves the trust implementation totally up to the user. Neither system is "better", the tradeoffs just need to be known and at least pgp implementations will have ux to provide for web of trust.


Also: something that pgp ironically got right: expiration dates. And modification of said dates produces a mutation of your identity... whereas using an ssh key as an identity doesn't have any sort of fetaures.


ssh keys don't have expiration dates, but ssh certificates do [1]. Which is.. how it should work. A certificate is a declaration of providence of data, a key is not (in itself) that.

At any rate, if you want to tell me you actually believe most users of PGP actually properly deal with key rotation and don't just give up and set unreasonably long expiration cycles on their keys or stop using pgp when they first encounter an error about an expired key, I might have a bridge to sell you.

[1] See `man ssh-keygen` for the -h and -s arguments and -V for the validity window.


I thought it wasn’t advisable to use Ed25519 for signing arbitrary files? It’s at least not advisable to sign large files due to the multi-pass nature of signature generation, per RFC 8032 (sec 8.7). Where do you draw the line on “large”?

I’d assume they’re using Ed25519ph (pre-hash) with a context (the -n file namespace), but I can’t find the source for ssh-keygen with a quick search to confirm. But then again, it’s also not advisable to share keys between Ed25519 and Ed25519ph, which the author would be doing...


That's pretty interesting. To some extent, it was possible even before - Support for converting SSH RSA Keys to OpenSSL formats is old old, and you can use those to encrypt/decrypt or sign/verify arbitrary data via the openssl command. In fact, AWS uses this in their Windows instances, to encrypt the Administrator password[1]

Definitely will mean some interesting things for Git workflows, though. I've long been in favor of requiring every commit to be signed, and making that easy to enforce either in merges or push hooks. On the other hand, Linus is publicly against it[2], with good reasoning, though I don't think compelling enough reason[3].

Signing every commit would completely break the common pattern of handling merges centrally. Most companies, unlike kernel development, have a centralized server with a "trunk" and code review is done as part of that. Signing every commit with your SSH key would break that model, badly, but it could instead be an opportunity to improve the git tooling.

One of my favorite features of the now-defunct Phabricator was that you typically merged your commits with `arc land`, which a) squashed and annotated your merge with the Phabricator code review metadata and b) Deleted your branch. The latter was especially handy, but the former made code review great. Github and Gitlab can do the same as part of their UI, but it would be far better if it were nicely integrated with your existing git workflow, and this would be the opportunity to add prepush hooks to nicely integrate with hosting sites and code review tools.

[1]https://docs.aws.amazon.com/cli/latest/reference/ec2/get-pas... [2]https://web.archive.org/web/20201111174438/http://git.661346... - There has to be a better archive of this mailing list than the wayback machine. Searching for this, though, led me to my previous comment[3] [3] https://news.ycombinator.com/item?id=12291462


I think if you trust your maintainer/central tool enough to merge code from your developers then i think you can also trust them to verify all the commit signatures they receive and then resign the resulting merge right? After all they could simply create all the commits they want themselves right? The authors commit signature from before the merge will be lost. If you use signed tags though the merge will retain the initial signature on merge in the merge message.

btw. i am also a great fan of the phabricator workflow :)


Fossil [0] can sign every commit [1] (with GPG or S/MIME) and have merges performed centrally because it never modifies history.

Git can probably also do this for certain merge modes ? I'm not very familiar with how this works in Git.

[0] https://fossil-scm.org/

[1] https://fossil-scm.org/home/help?cmd=clearsign


Git can sign commits and tags.


This is awesome and should be more widespread.

I always feel embarrassed when I see government systems that use digital signatures infrastructure. Usually, a government website has their own web application through which you input your private key and your password. Sure, usually those applications use standard libraries that do computations locally. But how do I know this? If such a website is hacked – my private key will be exposed.


> web application through which you input your private key and your password

Sorry, what? Can you point me to some examples, because this sounds so crazy. Why would you ever upload your private key to a server? Sounds like security theatre to me...


The verification is local (through javascript, nowadays). But you can't know this if you're not a hacker that can check it. It's widespread in Ukraine, and I assumed it's similar in other countries.

I mean hackers could change the code of the website so that private keys will be uploaded without noticing by users.


Ahh yes, now that I think about it, I’ve seen this sort of implementation before:

1. Government forces you to jump through hoops with some collection of favored — sorry, I meant “authorized” — vendors who can issue you a certificate for $WTF (either paid directly or through your taxes...).

2. You are provided with the private key in some manner. Hopefully not in your email, but that’s often what happens.

3. Whenever you want to validate yourself to the service, the government website then has you upload that private key to use in their own homemade implementation of JavaScript PKI. Sometimes they actually take the key from you and send it to their server to do the work.

... I think we are both in agreement that this is pretty lousy. And if you’re seeing it in Ukraine, it’s a world-wide “security” model. Maybe someone else here on HN can explain the thinking that went into these sorts of implementations...


Where else are you seeing this, say what you want about digital signatures but I have not seen this. I guess javascript PKI is a thing though, and that will end badly with soft tokens.


That‘s why you generate a new key pair for every service.


I'm talking about keys that have certificates issued by authorized centers. Those keys have legal power. Also obtaining a certificate costs a fee.


> You'll soon be able to sign Git commits and tags with SSH

Once Git 2.34 adds the ability to do this, will Github still show its verified indicator?

https://docs.github.com/en/authentication/managing-commit-si...


Leaning on SSH to fix the problems in PGP is like trying to rebuild a bridge out of wood because the concrete is cracking. SSH keys were not designed to solve the problems PGP was; it is simply not a functional replacement. It's a stop-gap that will be monkey-patched until we either come up with a better standard, or fork and fix PGP.


This has long been possible by using the SSH key via the openssl command line, since they're available as PEM. I've relied on that occasionally in provisioning code, albeit specifically using the server key rather than a client identity. Heck, you can even use them for encryption that way.

Nevertheless, it's nice to have some more direct support.


Ethereum has standardized ways to formulate (off-chain) signatures for arbitrary messages [1] and Solidity structs [2]. Convenient command-line tooling is lacking currently, but some interesting twists to consider:

If you sign using a key that also controls cryptoassets, then you're incentivized to keep the key safe and secure indefinitely. Contrast with tendency to lose GPG and SSH keys after losing interest for a few years, changing jobs, etc.

Moreover, consider key revocation. The revocation mechanisms for GPG and SSH keys are not that effective, due to impracticality of publishing your revocation in a way that really ensures subsequent verifiers are alarmed. If only there were some sort of decentralized, permissionless, globally-replicated database which verifiers could check for that information...

More generally if you have a really important signature to publish, you can mint an NFT for it or otherwise inscribe it on the blockchain. There it will live, irrefutably notarized and timestamped, forever.

I explored these ideas in a weeklong side project [3] that only got to cumbersome proof-of-concept stage.

[1] https://eth.wiki/json-rpc/API#eth_sign

[2] https://eips.ethereum.org/EIPS/eip-712

[3] https://github.com/mlin/stakesign

Footnote: Bitcoin also had an arbitrary-message-signing mechanism -- commonly used on bitcointalk back in the day -- but I think it may now be ~defunct due to not keeping up with the newer address types introduced in recent years.


Attaching this to cryptoassets increases your operational (more mental overhead, doesnt work with simple keybearer devices, you assume people to be lazy and bad at key management) and technical (irrevocable ethereum-bugs that can only be mitigated by chain splits) complexity.

Albeit for long-term public signatures I see the benefit in spreading the sig and revocation information from the classical tools in to as many hard to modify places as possible. Popular global databases like Ethereum and similar are good condidates for that.

And of course have the verification scheme expose inconsistencies between different key-sources and tag them with their respective power structure categories. (Lime Government, Cryptocurrency-Devs, HugeCodeHostingPlatform, CompanyBehindHugeCodeHostingPlatform, etc...)


An Ethereum address is just a public key (which, as the owner, you also have the private key to). You can make one, and sign messages with it, without touching the blockchain or sending any assets to it. So added complexity is -necessary- only to the extent you wish to involve those additional ways you can interact with the blockchain (that you can't using GPG or SSH keys). I'm saying this in principle of course, granting the current lack of convenient utilities/CLIs for operating this way.

I would speculate that there are probably already more people who practice decent opsec for their Ethereum keys than for GPG & SSH keys. Soon it won't be close!


Verifying signatures is messy, because the SSH keys don't store identity information, isn't it?

So basically you know that an specific SSH key signed a file, but that's all you know. Not very useful? Who's going to maintain a file with allowed signers per key?


Correct. Linking an identity to the crypto signature is the hard part for every mechanism. Regarding the allowed signers file you have several options:

A repository only allows signed commits / merges / pushes and simply stores the file in the repo itself.

If you already rely on forges like github/gitlab/... and trust them to generate a file for you (e.g. from the users ssh keys having write access to the repo).

You maintain this file independently for yourself with a "Trust on first use" mechanism (which will follow in a future patch to git)

A git patch currently in progress will utilize the valid-after/before options that you can set on keys in this file to verify the commits/tags with keys valid at the time of the objects creation. This will allow for key rollover and still being able to verify old signatures. (Theres also the revoke file which will invalidate all signatures for a key). In addition to that a "trust on first use" patch will follow that can automatically add new keys with the committers ident to this file (unless the ident is already present with a different key of course, which should error badly).

disclaimer: i wrote the git integration for this


I wrote a tool that lets me use keys in my ssh-agent for google cloud. This way, a vm can run with minimal privileges but when I ssh in I get gcloud cmdline with full control.

It is very easy to connect to the agent and ask it to sign something.


> And if you use GitHub, or any other service that uses SSH keys for authentication, you already have an SSH key that can be used to generate signatures.

Nope. I just checked. I don't.


So you enter your username and password every time you git pull/push?


Or they use a git-credential-helper with a Personal Access Token.


Definitely not. I think I enter it about once per machine.


> Since the first three bytes of the SSH protocol signature input are different from the ssh-keygen signature input, the SSH client and ssh-keygen will never produce identical signatures. Therefore, there is no risk of cross-protocol attacks

That's not convincing to me. Does anyone have more details on this?

It does not seem right to me that a signing protocol secure for similar things would necessarily be secure against random things; A LFR over a long sequence seems like it could be different than a single feedback over random space, and sometimes that difference could be important.


Wait, could we use ssh keys as the a federated id? (OIDC?)


Cryptographically, sure, that's always been possible, and it is in fact what SSH affords: if you create an SSH keypair and drop the public half on a remote host, then the corresponding private key serves as your identifier.

The crypto part is relatively easy. Ensuring that you've got the right keys on the right hosts is the hard part.

E.g.:

- If Eve gives Bob a key Eve describes as Alice's but which is in fact Eve's, then Bob is (unwittingly, but cryptographically validly) permitting Eve access.

- If Eve can copy Alice's public key from Bob's system to one controlled by Eve, and Alice isn't scrupulous in verifying host keys, then Alice may be tricked into logging into Eve's system (and perhaps divulging further information) when she thinks she's logging into Bob's.

- There's the more common problem where Bob permits a login using Alice's key, but that key has been compromised in some fashion by Eve. The cyrptography is putatively valid,[1] but the presumption over identity is not.

The PGP "web of trust" model was designed to give some assurance that a key purporting to be Alice, or Bob, or Eve, actually was, and without relying on a central certification authority. It ... mostly kind of worked, but also mostly kind of didn't.

Trust itself isn't a cryptographic property. Aspects or indicia of trust may be cryptographically validated.

For SSH, the trust aspect has been implied in the key-delivery mechanism. Either the trusted party transmits a key directly to the recipient, or they generate the key from on the recipient's system. Further trust of that key relies on both the crypto implementation remaining valid (see again CVE-2008-0166), and control over the private key and any additional authentication factors (passphrase, physical authentication factors, etc.) remaining uncompromised. There are numerous instances in which private keys and/or passphrases have been compromised.

That said, I see some appeal in being able to use, say, SSH keys rather than passwords and other factors to authenticate to websites. In fact there's no need especially to authenticate in the case of content, I need only sign the content which would demonstrated the authenticity of 1) my having signed it and 2) it not being altered since creation. (Say, if dang were to get into the sneaky habit of surruptitiously editing HN comments by other users.)

________________________________

Notes:

1. Or perhaps not, as in the case of CVE-2008-0166, the Debian bug in which time-of-day in seconds was used in key generation resulting in a namespace of only 86,400 keys being possible, a feasibly-brute-forceable space. Those key values are now blacklisted.


Other tools that can use SSH keys for signatures include:

- Minizign: an implementation of Minisign in Zig

- Wasmsign: a tool for signing WebAssembly modules


Is it possible to encrypt something with an ssh pubkey and then decrypt with the corresponding privkey? GPG-style?



That happens as part of the ssh handshake. And is the basis of this whole scheme. No idea if there is tooling to.do.that for arbitrary messages.


this was always possible.... ssh just didn't do it. but you absolutely could use your key to sign data.


*with ssh-keygen.

I'm sure this has been a technical possibility since the dawn of ssh keys themselves.


You could also just hash the file and publish the hash on your web-site which has a HTTPS certificate. Or simply publish the file on your website - no need to sign.

My reasoning is that if your website get hacked it wont help if you have signed the file, the hacker could re-sign the files with a new public key.


Hashing only shows that a file hasn't been modified since the hash was made.

It doesn't indicate who made the hash, if a simple checksum method was used.

A cryptographic signature is a hash made using a private key, indicating that only someone with access to that key could create the hash. It asserts both integrity (the contents haven't changed) and authorship.

Without the private key, the hash merely indicates access to the content at some prior point in time (which might be otherwise asserted or recorded), but not who had that access.


For signing to work you need to have the public key of the signer beforehand. If you do not posses their public key it will be impossible to know if the one signing is really the one you think it is.

So signing only works if you already have an established relation with the one receiving the data.


You require the public key of the signer when verifying the signature. That needn't be before receiving the message, and could be at any point from now until doomsday.

The signature itself verifies:

1. That contents haven't been modified since they were signed. (Integrity.)

2. That a party had access to the private key in order to create the signature. (Authentication)

(You're not assured, of course, that others don't also have such access.)

Determining the real-world identity of the signer is ... another matter. Though an exchange of content encrypted against their public key, and returned to you, might help establish that. Process and protocol will depend on your own needs, intent, and goals.


If an "allowed signers" file is used, the public keys are known beforehand, and it will be secure.

But if the public key is required when verifying the signature, then where ever that key is requested from needs to be a trusted source and it's also the weakest link. If that source is a web site, you could just as well publish the file on that web site and the files would be just as trusted as if they where signed.

Example: Alice signs a file, and uploads the file on a public FTP server. Alice public key is published under the about section on her HN profile.

Hacker bob hacks into Alice HN account and changes her public key without Alice noticing it. Hacker bob then downloads the file from the public FTP, ads some malicious code, signs it with his own private key belonging to the public key he added to Alice HN about info. Then hacker bob sends the file to a victim.

The victim verifies the signature using the public key on Alice HN account as instructed by Alice.


Keys themselves are content that can be signed. The PGP Web of Trust is an untrusted system for distributing content that doesn't rely on trust in the system to be able to distribute trustable content (PGP public keys).

If the SSH method descried in TFA is to become widely used, it will all but certainly end up replicating a similar model.

Otherwise: trust keys you're given directly, or which have a sufficient verification and trust chain attached to them. This is a Hard Problem of all authentication-based crypto. E.g., in our mutual transactions with Hacker News, we're implicitly trusting the site's TLS cert 02:b3:a8:b0:57:06:45:1c:7c:80:fb:d6:e8:31:e3:5e issued by DigiCert. That implied trust is the basis for multiple trillion-dollar-valuation companies, online commerce, communications, control, and other transactions. It has numerous known limitations. And yet it remains used.


We've come full circle then:

https://medium.com/@chrispisano/ssh-authentication-with-gpg-...

TL;DR: Use the same key in GPG and SSH by it exporting out of GPG into SSH

    gpg --export-ssh-key


monkeysphere manages ssh keys in gpg and also communicating with ssh-agent (or gpg-agent).


This comes with a rationale for why this should be safe re-use of SSH keys, and OpenSSH provides, as you would hope, an explicit namespace mechanism so when fifty people re-use this they don't pollute each other's cryptographic context. In both cases this is unlike Filippo's age - which to me makes it a whole lot more attractive.

Its relationship to your identity, contextually ("this is my GitHub key, this is the one for $VolunteerProject servers, and this third one is for my local machines") makes more sense for this purpose than in age too. Signing a git commit with a key you use on gitlab for example.


This has literally nothing to do with age, which, by deliberate design, doesn't implement signing. What a strange and hostile thing to write.


You wrote:

> This has literally nothing to do with age, which, by deliberate design, doesn't implement signing. What a strange and hostile thing to write.

But of course I never claimed age performs signing I wrote that it re-uses SSH keys without a safety rationale. Here's what age actually says about its re-use of SSH keys:

"As a convenience feature, age also supports encrypting to ssh-rsa and ssh-ed25519 SSH public keys, and decrypting with the respective private key file." -- https://github.com/FiloSottile/age#ssh-keys

So, we see age does in fact re-use SSH keys for this unrelated purpose. And we see that, unlike the OpenSSH feature described in this article, it offers no rationale for why this is safe. Filippo talked about writing such a rationale but ultimately there isn't one provided.

Ordinary users shouldn't try to imagine for themselves why something dangerous might be safe. In the absence of a rationale for why re-using your SSH private keys to decrypt age messages is OK, don't do it.

The article provides a rationale for OpenSSH's "sign arbitrary data" feature (a briefer one is included in the OpenSSH distribution itself) so that you can assure yourself that this is a reasonable thing to do.



Quoting Filippo's blog post:

> What remains open for future work is checking for cross-protocol attacks

Yes. Yes it does.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: