Deprecating password authentication in GitHub API
developer.github.com
developer.github.com
- Repo access is all or nothing. A read-only token is not possible, an 'issues-only' token is not possible.
- Personal access tokens are not scoped to repositories or organizations. So your personal toy project token also allows access to your super-sensitive employer's repository. On top of that, your employer is unable to prevent this, unless you start using Github Enterprise _and_ an SSH CA, which is far from trivial.
It's nice that they drop username/password access, but as long as personal access tokens have such broad permissions, it does not really add any value (you should have been using 2FA anyway).
I use deploy keys rather than a PAT as they can be scoped (single repo and can be read-only), but they are more work and are limited to git actions rather than the whole GitHub API.
The fact they clearly have the internal capability for this makes it incredibly odd they aren't exposing it for users to use, and I agree it'd be a really valuable thing to have.
This took me a second to correctly parse. Would have been better written as: “During a brownout, password authentication will temporarily fail. This is to alert users who haven't migrated their authentication calls.”
Can anyone provide more context for this deprecation strategy?
For users who pay attention (say, us) and prioritise accordingly these strategies are the same, they know the feature it going away and can plan for that.
But for users who weren't paying attention or who didn't correctly prioritise, adding a Brownout offers some final warning that helps push more people to start preparing before the final flag day happens.
It doesn't need to get everyone, if 80% of users whose business processes still depend upon password authenticated GitHub notice something went wrong, and during diagnosis discover that what went wrong is they're relying on a deprecated feature, that's a big improvement over 100% of those processes dropping dead on flag day.
Brownout is a desirable choice where you're sure that some large population will not heed the advance notice. I bet that a lot of corporate GitHub setups have all contact mail from GitHub either going to /dev/null or to some business person who hasn't the first clue what "password authentication on the GitHub API" is. Maybe they'll email the right dev person, maybe they forward to an employee who left six months ago, either way it's far from certain anybody who needs to take action will learn from an email.
With UX feature deprecation you can tell the live users of the service. But in APIs even if you notionally have a way to feed stuff back (like a "warnings" field in the results) it's probably blackholed by lazy programmers or lands in a debug log nobody reads. So "It stopped working" is the best way to get attention, but without a Brownout that's permanent. The user learns what's wrong too late to do much about it which sucks.
Brownout is something ISRG's Let's Encrypt has used, because of course Let's Encrypt is largely an API too, they publish feature changes but a huge fraction of all their subscribers aren't paying attention so the Brownout is the first they'll know anything is happening that matters to them.
Sure, the isolated period blackout (“brownout” is a bad metaphor) of the deprecated function has some obvious communicative utility compared to flag day, but once you accept shut-off for communication, it kind of immediately suggests communication methods that have a stronger guarantee of reaching the audience, like progressively frequent blackouts (or probabilistic denials) over a period of time leading to total shutoff.
So for some folks, maybe CI will be broken, or deployment automation, or even code review.
The trade-off here is to be disruptive enough that folks will notice and fix old callers of the API, while not leaving thousands of coders permanently in the lurch (they'll notice and complain, but three hours later they can get back to work, while someone fixes the infrastructure in the meantime).
Two issues:
* users will ultimately hard code the passwords in a script
* the user may have used the same password on other sites
Combine the above together and it can result in a bad situation.
It's best for a vendor (like GitHub) to encourage good security, where possible. A token which is unlinked to the password and can be revoked independently of the password adds minimises the extend of the compromise.
Ultimately similar to what github did..
That is, 2FA could be achieved via use of that certificate and a username/password.
The infrastructure edge device could communicate additional information if needed by adding headers to the original HTTP request when it's passed down to the endpoint that actually handles the request.
>> We are announcing deprecations that will improve the security of GitHub apps and APIs
[1] https://developer.github.com/changes/2019-11-05-deprecated-p...
Except that email, as described in the blog you linked to, is not a secure means of communication. What would be secure is to use a client side TLS certificate as part of the authentication process. That is, your browser/device sends it as part of the TLS connection negotiation process and then you authenticate via the username and password (via HTTP basic auth).
They're already doing something like that whenever one pushes or fetches from a git repository hosted on Github through ssh key authentication. It wouldn't be much of a stretch for Github to allow an account holder to upload a CSR and then Github signs it and makes a certificate, which the account holder can then add to the browser's or OS's certificate store.
In terms of client certs, see my response in https://news.ycombinator.com/item?id=22849985. I agree client certs would be great. However, it can be tricky to couple your app logic with transport based security. A good example of this...chrome/google introduced a crazy cool concept called “channel bound cookies” - http://www.browserauth.net/channel-bound-cookies, but it never gained any traction because of the complexity noted.
Edit: typo
In essence stop using git username globally and start supporting user names.
Not sure why you choose to look at the key as identity.
You can choose to give the public half of your key to multiple entities to allow them to verify your possesion of the private half of the key but that does not translate into multiple identities.
Can you use the same ssh key to ssh into different accounts on the same system?
The main alternative is "Machine Users"[1], which are actually normal user accounts. That means they have the same policies as regular users, like mandated 2FA for an organization. And to manage them you have to log-in as that user. That makes it a pain for a team to manage a Machine User.
GitHub really needs to have Service Accounts that belong to an organization, and can be managed by admins of the organization (without having to log-in as the Service Account). The Service Accounts should be able to have SSH keys and API tokens associated with them.
[1] https://developer.github.com/v3/guides/managing-deploy-keys/
Never heard such a restriction even mentioned, let alone enforced.
Enforced — of course not (guess why I was told), but it stands to reason that they probably won’t add a feature to facilitate TOS violation.
This becomes messy to manage, as it's not easy(as far as I know) to use the same account on your personal PC to do both personal and work work.
I wish they replaced it by tokens tied to specific repos and with scopes instead of that new Webapp Flow thing that looks a lot more complicated to implement than a curl request (I had planned to look into it this month, but obviously other worldwide events took priority).
The only way to get this data now is to paginate through all sponsors with their GraphQL interface!
I’ve always found it strange that an HTTP 401 is used to indicate two very different server-side states:
• “this resource requires authentication, and you didn’t attempt authentication”
• “as an early step in the request flow, you tried to authenticate yourself—but your authentication failed (due to e.g. having an unrecognized username; or using the wrong authentication method; or, of course, having the wrong password)”
I mean, I get it; in the end, after trying and failing to authenticate, the request-processing continues (with the “auth” field in the server’s model of the request state being nil, just like it would be if you hadn’t attempted auth); and the request you’re making at that point is still an attempt to request an authentication-required resource. You’re “not authenticated” at that point, so 401 it is.
But it really seems like auth processing should have its own “off ramp” in the HTTP request-processing lifecycle—i.e. if you ask for auth, and auth fails, you get a code and the request isn’t processed any further, so it doesn’t matter that the request you made is auth-required.
(After all, we mentally model HTTP resources, fundamentally, as URLs; and URLs put the auth stuff in the origin part, not in the request sent to the origin part. I would naively expect that an auth failure would resolve at the same stage as an unrecognized Host name!)
When you’re coding an HTTP client, it’s very hard to debug a corrupt Authorization header, because all you know, when you have anything even slightly wrong, is that the server is pretending it didn’t see it!
-----
And yeah, I know, in practice, why this isn’t the way things are. Historically, one of the first uses of the Authorization header was through Apache’s mod_auth_basic, which refers to an .htpasswd file in a directory to determine the set of valid auth credentials for all resources descending from that directory. In this model, auth is resource-specific, rather than server-specific; so it makes sense that, if you’re sending auth, and auth is unrecognized, but the specific resource you’re authing against turns out to not require auth, then the server can proceed just fine without sending you a 401.
However, I don’t think there’s any modern use-case where auth is resource-specific like that. HTTP auth “realms” are almost always per-origin these days. It makes a lot more sense to think of auth as something happening at the level of an implicit HTTP gateway between the client and the server ultimately sending the resource, where the gateway can know what server (realm) the client wants to route to—and so can auth the client on that basis, and deny the request if that auth fails—but the gateway can’t know anything about what the auth requirement policies are for individual resources on the backend it’s sitting in front of.
Whether that matters is up to you, but I get the impression most people just default to not exposing existence. There is 403 which helps split these.
It's not really that convoluted: it's just setting a header with a fixed token, which is actually simpler than HTTP auth.
Removing something that works is not, in itself, "improving" security. It is breakage in the holy name of security.
If you have broken your system in the name of security it is not a more secure system. Its just a broken system that does not do its job. It might be "more secure" when users fix api usage, in the mean time its useless and is going to cost everyone time & money to fix.
It might makes more sense in the long run to move to something with a stable api.