Most of this is lame. Number representation problems aren’t part of JSON, they’re the fault of JSON parsers that just convert all numbers to doubles, just because “thats what JavaScript does”. It’s not much harder for the parser to pick an appropriate representation for each number, like using int64 unless there’s a decimal point.
Unicode has weirdnesses too, but what data formats go to the trouble of specifying in exhaustive detail exactly what forms of encoding and normalization to use? I don’t think this is a specific fault of JSON.
ProtoBuf just isn’t comparable. It’s a much more complex format that requires a schema definition to be parsed at all. It absolutely does not fit the same use cases as JSON.
Nah you don’t get to put the blame on parsers here. The problem is that JSON is under specified. Parsers aren’t doing anything wrong, it’s perfectly in line with the spec to convert all numbers to doubles. Hell, considering the history of JSON as “JavaScript Object Notation”, converting all numbers to doubles was probably the original intention behind the spec.
What is it about specs that leads to this kind of reasoning? “Either the spec is wrong, or the user is wrong, which is it?”
I’m not at retirement age, but I’ll pull the grumpy old man card and say “they’re both wrong.”
If the spec gives you a terrible option, you should criticize the spec for it. If you take the terrible option, you should also be criticized for it. There is more than enough blame for everyone to get a bit.
JSON absolutely has culpability here, because it doesn’t nail down what a compliant parser should do. The only thing approaching a defense is to say “this format was built to be used by javascript engines that can only natively represent doubles, the idea of using it elsewhere was a mistake.” But even if you went that route, why not just specify that all numbers are doubles? You’d make it much clearer what you could and couldn’t use the spec for.
If you make a bad design decision in your parser and defend it with “the spec says I’m allowed to do this” it doesn’t suddenly make it not a bad design decision!
I’m not sure how json is underspecified. json.org says “number”. It doesn’t say “float”.
The problem is that the parser output doesn’t match the parser input. i.e. print(parse(foo)) != foo
This seems like a pretty serious bug to me. Maybe I could understand the output order being changed, as json.org doesn’t specify ordering of fields. But to change the content of a field? Come on… that cannot possibly be a good decision.
But.. what is a “number”? It can’t be a number in the mathematical sense, the syntax is too constrained for that (it doesn’t allow the number 1/3, or pi etc).
And, it’s clearly not one of the “normal” numbers computers work with like ints or floats - the syntax is an arbitrary precision decimal.. is that what you mean parsers should require as input and output?
I can kind of get behind the purity of that, but it sure makes JSON a lot less convenient if you can’t say “JSON.dumps({“myval”: 1})”
Number representation problems aren’t part of JSON, they’re the fault of JSON parsers that just convert all numbers to doubles, just because “thats what JavaScript does”.
That has been explicitly part of the JSON spec for ten years. Even before then, any JSON implementation that used numbers that don’t fit in float64 was asking for trouble because there have always been JSON parsers that only support float64. Causing interop problems by using wider numbers is a bug, a failure to be conservative in what you send.
Yeah, we ran into this. Our C++ JSON parser would handle uint64 correctly. One of the consumers was JS though and would lose precision when converting the numbers to float64s (as expected), resulting in duplicated ID numbers with the JS client but not the C++ clients.
Number representation problems aren’t part of JSON, they’re the fault of JSON parsers that just convert all numbers to doubles, just because “thats what JavaScript does”. It’s not much harder for the parser to pick an appropriate representation for each number, like using int64 unless there’s a decimal point
100%. People love to give PHP shit for foot guns, but the built in json decoder will return an integer if the json value had no decimal (and fits within an integer).
But even more egregious than the “some decoders do stupid things” excuse is the “some end users do ridiculous things” excuses.
Really? People are storing license keys, credit card numbers and the like as integers? I thought we had this discussion years ago about not storing phone numbers as integers and people learnt the lesson?
I’ve got a long draft of a blog post that goes on and on about protobuf’s footguns in the same vein as this post. Sounds like you might have some material to contribute? ☠️
There’s another fun aspect to this that we ran into at work: if you happen to use JSON and accept integers which you use in a database query, make sure that you get only integers and not floats, or even bignums (if sufficiently large).
If you don’t ensure you have proper integers in an expected range, the float or bignum can cause your query to fall back to a full table scan. For instance: SELECT foo FROM large_table WHERE id=1.0 will not be able to use your carefully crafted primary key index because of the type mismatch (assuming id is a normal int or bigint). This allows attackers to slow your database down to a crawl simply by tweaking the JSON slightly.
This only (or mostly?) affects dynamically typed languages like Python (or in our case, Clojure).
It’s not much harder for the parser to pick an appropriate representation for each number, like using int64 unless there’s a decimal point.
Even better, the parser could return the original string representation of a number and let the user decide how to interpret it. This works especially well in streaming pull parsers (as opposed to parsers that produce an in-memory representation of the entire document) where the user can just call the appropriate value accessor (value<uint64_t>(), value<double>(), etc) without having to store the string representation long-term.
Number representation problems aren’t part of JSON, they’re the fault of JSON parsers that just convert all numbers to doubles, just because “thats what JavaScript does”. It’s not much harder for the parser to pick an appropriate representation for each number, like using int64 unless there’s a decimal point.
You can make a better parser, but now your JSON documents aren’t going to be compatible with the ecosystem! The original JSON use case was JavaScript web stuff, and back then, JS didn’t even have integers, it only had doubles. So you had to stay within the limits of doubles. You just had to. Just because this sucks, we can’t expect the entire JSON ecosystem to just fix itself. Much better to use a format that has a specification which is strict about what parsers must support.
I can’t even begin to imagine how services that don’t properly support diacritics process Chinese, Japanese, Korean, Arabic, Thai, …, names.
I’ve never flied before, but what happens if you’re being checked out on an airport and they cannot read your name? Do passports from countries speaking non Latin-based languages have romanisations of names written on them?
The optically-readable part at the bottom of the photo page of an IATA-compliant travel document has an ASCII-only form conforming to IATA constraints. This means that even if the name is in the Latin script, there’s an IATA ASCII version. For example Finnish ä becomes AE and ö becomes OE even though this German convention does not make sense for Finnish.
Is that really a generally applied rule? I thought that was determined by the issuer, and some countries afaik even let you specify what you want it to be (within reasonable variants of writing your name obviously)?
ICAO recommends (but does not require) that Ä be converted to A or AE (and Ö to O or OE) in the machine-readable part of a travel document. Maybe the rule is stricter for EU passports?
As the spec shows, the transliteration is algorithmic even if there are options for some characters. The options aren’t available to individuals: Finland does AE for ä without asking the passport applicant.
Not sure how much of a mess it would be to change the transliteration. (IIRC, at some point Russian passports switched from French-based transliteration to English-based transliteration. There must be some failure stories about that.)
If I remember right, Japan was an example of a country that does let the applicant specify. But of course there its a much bigger “gap” being bridged by the transliteration.
Do passports from countries speaking non Latin-based languages have romanisations of names written on them?
Yes, the important fields (name, country of citizenship, etc) are in Latin characters. A search for 「日本国 旅券 見本」 (Japanese passport sample) yields https://www.city.kishiwada.osaka.jp/uploaded/image/56222.png, which is detailed enough to get the gist.
Depending on the language of origin there can be some subtleties in how names are rendered into Latin – either the government has an official romanization scheme, or they let the preferred romanization be written into the passport application (within reason).
My wife and son‘s thai passports have their respective names in both languages, but other details in English only.
Their Thai ID cards have more details in both languages, but they also cram much more information in, and I believe the Thai ID system revolves much more around just knowing the ID number than relying on being able to read the details on the card quickly.
It is becoming much more interesting when a country has more than one official language, and Latin transliteration is different depending on which language is used for it.
Even within a single language you can still be stuck with multiple romanization schemes; for example there’s 4 or 5 in regular use with Thai, and they are all roughly equally decent if you stick with one consistently, except the main one used for road signs, which frequently renders multiple different Thai sounds with the same latin letters.
What I don’t get it is how you can be a programmer in the year twenty twenty-four and not be the tiniest bit curious about a technology that’s said to be fundamentally changing how we’ll program in the future. Absolutely, yes, that claim sounds ridiculous — but don’t you want to see for yourself?
No not really. But then again, I also didn’t want to see how “everything will use Blockchain, bruh”, and the vast majority of my work related to “cloud” services, has been migrating clients off of the over hyped circle jerk that depends on a bottomless bucket of (often VC) money to make much sense.
Now if you’ll excuse me I have to go look at the grey hairs in my beard and yell at some kids on my lawn.
True, but it’s not enough that your source code is POSIX shell. You also have to run it with a shell that’s not vulnerable! For example, this is a POSIX shell program:
x=$1
echo $(( x + 1 ))
And it’s vulnerable when you run it under bash/ksh, but not when you run it under dash, busybox ash, or OSH!
the reason that some OS’s decide that when i say “/bin/sh” what i really meant was some other shell that’s not sh is why i have trust issues. i’ve been told that it’s fine though, and to stop being pedantic.
I think this is a good reason to not use shell, or at least avoid as much as possible in any context that the user can control the inputs, because it is so easy to commit mistakes in shell, and as another commenter said below you can’t even trust that your POSIX compliant script will run in a shell that handles this (and other issues) correctly.
Broadcom CEO Hock Tan has announced his intention to divest VMware’s end-user computing and Carbon Black units, and signalled a rapid shift to subscription licenses of bigger software bundles.
Speaking on Broadcom’s Q4 2023 earnings call, Tan told investors “We are now refocusing VMware on its core business of creating private and hybrid cloud environments among large enterprises globally and divesting non-core assets.”
That was my guess as well. Even prior to Broadcom, the development pace of both (especially workstation, which is what I was using most) seemed to have slowed to the point that it’s have been hard to believe they saw much revenue potential there. And with Apple Silicon, Fusion seemed to move from a common tool (that I’d buy with every mac I purchased/approved) to a really niche thing.
It’s easy to imagine it’s a better promotion for datacenter products than standalone moneymaker, especially once you factor in a company that’s not equipped for it needing to open a channel for consumer sales.
It does make me wonder, though, why it’s always set up w/ User git and git@... . I tried reading that part of the book but I still don’t get it. I guess the config is by-Host and not by-User-&-Host? Yeah, darn. Which makes this solution all the worthwhile! since it basically gets you there
I think this git@ thing became the norm back in the early years of git because there were a few trouble spots that made it awkward to set up a multi-user repository hosting server:
there were fewer ssh server implementations, and openssh was (and is still) not very friendly to a server admin who wants to make significant changes to how it handles logging in, in particular it’s hard to decouple the username requested by the client from a unix account
provisioning a whole unix account per user means you then have to deal with crossing privilege boundaries so that multiple users can write to shared repositories without messing up the permissions; it adds lots of complexity to administrative / back-end software
tangential anecdote: my colleagues at Demon Internet told stories of when there was a countdown on the office whiteboard showing how much time they had left to re-engineer their systems to decouple customer accounts from unix accounts before they got more customers than the 16 bit UID limit on early 1990s unix…
it would be like reverting to the way source repository admin was done with CVS in the previous century, yuck
The usual solution implemented by git hosting projects such as gitosis and gitolite was to use a single git@ unix account with a monster ssh authorized_keys file that does some special things:
uses a forced command so that clients are dropped into gitolite and can’t get a shell
passes the key owner’s username to gitolite so that it can implement fine-grain access controls
I have no idea how github worked back then, but I ran a small git hosting service for a university using gitolite, and before that I ran a CVS server. Unlike CVS, with gitolite I was able to delegate user administration to whichever research groups wanted to use it, and they could (and did) give access to colleagues in other universities without me having to lift a finger. Made me happy that it supported open collaboration as I hoped it would.
Dogshit UX though, but it successfully demonstrated that there was enough demand for a university git hosting service that people would put up with a bare minimum service with <0.1FTE staffing.
There is no requirement from git itself to have the user you use for SSH be named git. In fact you can push/pull from a remote server using whatever username you want.
Most hosted git services have all users connect as an ssh user called git, and then use the incoming public key to identify the ‘user’ from the point of view of their own system (i.e. GitHub username), rather than using your username within their system (i.e. GitHub username) to connect to the SSH service for git to communicate over.
I suppose it gives them more control over things, and it makes it slightly simpler to give people instructions (i.e. you don’t need to know someone’s service username to give them a ‘guaranteed to be correct’ clone URL.
I believe this is also partly so clone instructions work uniformly. Asking people to clone with git@service is easy, asking them to clone with {replace this with your username}@service is annoying because it breaks copy and paste. If they then use submodules, it breaks entirely (you probably want to use https for public submodules and use an insteadOf rule if you have a GitHub account, but for private ones you may want to use ssh unconditionally).
A building in (very) clustered university I visited many years ago had the ground floor for the elevator set at -1. After asking around it turned out that the floors were indexed relative to a reference building. The ground floor on that building was at a lower relative elevation because of the steep hills these were built on. I think that was the point that started me mentally prefixing most anything with “is it base + offset (0) or index (1) and what’s the base?”.
In NZ and Aussie at least the ground floor of a building is zero, 1==the first floor above the ground, G being the zero of the system. There’s no reference building involved ground floor = 0, below ground floor number varies (b1,b2, I recall being common, I think I recall -1, -2 etc).
Surprisingly many buildings here in Sweden have this quirk too. Often giant hospitals planned and built in the 60s and 70s go all in on some “rational” floor numbering scheme that’s designed to confuse patients.
Having worked in a university where many buildings grew into each other and you could walk between floors 3, 5 and 6 of different buildings without ever stepping outside or changing altitude relative to your starting position, I think it sounds like a lovely idea.
I’ve gone both ways on this out of pragmatism, but I tend to prefer semi-whimsical to be honest. I prefer if the name has some loose association with what it’s doing as inspiration.
To compare the two:
I wrote a database migration runner called “Mallard” [1]
Mallard itself depends on a library imaginatively called “Koalephant Shell Script Library” [2]
The second is much more obvious what it does. But it’s so verbose it invariably ends up shortened to KSSL, which is back to being meaningless, and isn’t even pronounceable.
My approach going forward is definitely the semi-whimsical route, generally using elements from nature.
1: from the readme: Because a Mallard is a type of Duck that migrates.
2: Koalephant is the name of my consulting business.
The only thing that’s changed is I’ve leaned into whimsical names more. KSSL has been renamed, specifically because it was a fucking horrendous to read, write, or speak. So it’s now Alpinia[3]
3: from the readme: The name ‘Alpinia’ comes from a genus of plants commonly known as “shell ginger”.
IMHO, being able to export passkeys is missing the point of passkeys. They are supposed to be cheap and easy to create so you should be able to set up a passkey for your account on any device/account/browser that you use. If you use an account on a device, just create a passkey on it on demand.
Exporting passkeys would make sense if it was expensive or complex to set them up. I guess it depends on the account provider how easy or difficult they make it, but making it difficult to set up a passkey on a device seems like a great way to kill their adoption.
Expecting people to log into all online services they use and set up a new passkey for each of them when they switch devices is also a great way to kill their adoption, as is expecting them to tie all their logins to a singular account with a sync provider.
I know. That’s why I said they people can do it on an ‘as-needed’ basis, and not pay the entire setup cost up-front. When you need access to an account, log in with an email flow, then set up a passkey. If the app is designed correctly, you should be guided on this flow automatically.
Click on ‘forgot my password’ or equivalent account access alternative flow
Enter the email address associated with the account and let them send you the email
Read the email, find the 6-digit one-time token
Enter the one-time token in the account recovery screen
You are now logged in. Go to your account auth settings page, eg https://github.com/settings/security#passkeys , and create a new passkey for the new device. Optionally, delete the old passkey for the old device.
Forgot password should NEVER EVER EVER be part of the normal flow. It must always be a thing that you only need to use in emergencies. Having it be part of the normal flow leaves zero margin for error.
There are already many sites out there that default to logging in with email only. Actually, any service that studies their users’ login metrics knows that a significant number of people always use the ‘forgot password’ flow to log in to their account, because they can’t be bothered to even remember a password. They just use the path of least resistance. I’m just suggesting using that as a convenience to set up a passkey on a new device, to create an even easier and more secure auth flow.
Forgot password is a last resort. If that doesn’t work then you’re locked out. You should never need to use it unless there’s an emergency. Switching platforms absolutely does not qualify.
I’m thinking about it in terms of incidents at organizations that cause people to be woken up at night. Forgot password is an escape hatch for that level of severity.
I regard forgot password as just another means of authentication, nothing more or less. And if it was so critical, then it’s a joint that should be well oiled.
Of course ‘forgot password’ is a last resort, I never said otherwise. But users need some way to recover their accounts if they lose access. You can’t just lock them out forever. At least, no sane website is going to do that. You are going to have to offer alternative login methods, and ‘forgot password’ with an email flow happens to be the most common one, which is why I suggested repurposing that as a step towards setting up a much easier and more secure passkey auth. If you have a better alternative than ‘forgot password’ to recover access so the user can log in and set up a passkey, then of course go for it.
But users need some way to recover their accounts if they lose access. You can’t just lock them out forever.
Yes you can. Companies are already doing it. Even Google does it.
And many companies require 2FA and lock you out if you lose access to your phone number. Some don’t even allow you to setup a third factor for recovery. This is reality and chances are with passkeys it will get worse.
But having a “forgot password’ flow immediately invalidates lots of the arguments in favor of passkeys. E.g. phishing now works. E.g. present the user a fake bank website and show them a message that says “we have updated our security and your old passkey no longer works. It seems your device is unable to do that automatically, so please use the forgot password flow to do so” yadda yadda and we are back to square one.
OK, good luck being a viable business that locks out users forever when (not if) they lose their credentials. IMHO, the risk of the ‘email login’ flow is being greatly overblown when you don’t actually have passwords, only email login and passkeys. First, the malicious actor would have to go to the real bank website, enter your email address, and initiate the email login flow. Then, they would need to immediately send you another email telling you to click on the given link and enter the temporary token from the first email there. Chances are really good that if the temporary token expires in 5 minutes, the intended victim wouldn’t even open these emails in time to enter the token. And even if they did, the first (legit) email from the bank should warn them against entering the token into any other page than the bank’s. And if the attacker floods the victim with a flurry of ‘email login’ emails, anyone would be able to tell something phishy is going on.
First, the malicious actor would have to go to the real bank website, enter your email address, and initiate the email login flow. Then, they would need to immediately send you another email telling you to click on the given link and enter the temporary token from the first email there.
I think if you tie this all to a malicious link the user has followed, you can make doing all this a lot smoother. It would depend on egregious user error (entering the code in the box on the phisher’s site that it presented them and told them to post the code in, rather than following the link in the email), but egregious user error will happen some of the time.
Realistically, the “forgot password” flow is probably used extremely routinely by most users. And I kind of expect that routine use of passkey re-enrollment flows will become just as common if passkeys catch on. Which means that passkeys can’t be, in practice, any more secure than their re-enrollment flows.
If you have a passkey on your phone, and your phone gets stolen/hardware dies how do you recover if you haven’t created backup passkeys ahead of time on other devices?
Also how do you migrate passkeys to a new phone from the old one when you upgrade your phone?
In a sane world the service/site you’re trying to use would have ensured you’d created recovery codes or similar. But given we don’t live in a sane world, the option to backup/export passkeys does seem like one I’d like to have :/
Of course, the best place to store account recovery codes is in your password manager, because it should be well maintained with decent security and availability.
You log in to the account whose passkey was lost with an account recovery method like ‘log in with email’. Then you set up a new passkey on the new device. And, if the app is implemented correctly and lets you manage passkeys properly, you delete the passkey that was on the lost device.
But if you preserve that email flow as an option, you break the benefits of credentials being tied to device hardware, and are back at needing password + second factor + backup second factor.
No you’re not? You can have an email login flow and then use it to set up a passkey on the device. You don’t need password + MFA at all. But you need to offer some way for the user to recover access to their account even if you don’t have passkeys. You can’t just lock users out of their accounts if they forget their credentials. Can you?
Your objection is based on the fear that re-enrolling is going to be a horrendously complex and slow process. What I am suggesting is to make it a smooth and easy process, almost as natural and quick as logging in with a passkey and Touch ID. If you do this on an as-needed basis, the burden won’t even be noticeable.
Please don’t try to convince me that you need to access your 1000 logins on your new device immediately as soon as you get the new device because you know that’s not true 😉
Not all of them, sure, but any one of them, yes. And there is literally no way to know which of the 1000 you’ll need next. You’re describing a Kafkaesque hellscape of bullshit any time you get a new phone or laptop or something catastrophic happens to one of your OS installations or tokens. It’s completely unnecessary tedium and I hope to god that we’re somehow lucky enough that the people working on the specification actually listen to what people want instead of just being smug and argumentative like you are in the comments here.
I don’t think you need to worry so much; we are literally discussing an article which says that passkeys can be exported. The people working on the specification clearly want this. All I’m saying is that in my opinion exporting passkeys defeats the point of passkeys. If you want the burden of having to manage passkey exports (which are going to get outdated at periodic intervals), that’s on you 🤷♂️
I think it’s important that passkeys provide support for the model you’re describing, because creating private keys inside boxes you can’t remove the keys from (smart cards, HSMs, etc) is a strong security model.
That said, for most people most of the time it’s bloody inconvenient. If you require people to maintain two or more passkeys in every place that they store accounts, and you don’t allow exporting, you’re basically guaranteeing that people will lose access to some of their accounts from time to time. This is basically like backing up your data: the only thing that works for most people most of the time is something automatic like periodic backups to the cloud that they don’t have to remember to do or really manage at all. The more first class the mechanisms for passkey export and portability are, the more likely the end result is something that balances security with the reality of how people actually use their computers, as well as providing some much needed user control of their own data.
you’re basically guaranteeing that people will lose access to some of their accounts from time to time.
No; I’m calling for a model which guarantees users access to their accounts in a simple and secure way in all situations, whether they have a passkey or not, as long as they have access to an email account. Let me detail the flow again, in case it helps:
User goes to login page
Login page has script that detects user passkeys; (a) if any of them are tied to this site, prompts user to log in with one of them, or (b) if no passkeys found for this site, asks user for email address, emails an OTP code to the user with a big warning to never share this code with anyone else, user enters code successfully, then site logs the user in and immediately prompts them to create a passkey
User is now logged in
From the user’s perspective, this process is minimally intrusive, not cumbersome, while still being as secure as possible.
emails an OTP code to the user
this process is minimally intrusive, not cumbersome, while still being as secure as possible.
It’s basically the opposite of secure. “Log in via email” emails are sent in plain text out into the world. They’re generally short codes that you copy and paste, which are the thing most likely to be phished from users.
It’s also absolutely cumbersome. To log in I now have to go and find the message in my email, do something with it, delete it. I have to switch between browser tabs and generally screw around. Sometimes mail delivery is not instantaneous. Regular passwords are a thousand times better than this flagrantly user hostile experience, because at least there are mature password managers that integrate with browsers and don’t require anything but a couple of in place clicks on the login page to use.
You’re also ultimately just punting authority to the mail provider for all authentication. It would be better to just demand all websites use OpenID Connect to use your mail provider as an identity provider; at least that would be both secure and convenient for users.
The problem is most people don’t use password managers. Why do you think ‘Have I been Pwned’ exists? It’s because people keep using bad passwords and repeating them in multiple places. In light of actual user behaviours, it turns out that short-lived email tokens (which can be sent via TLS-encrypted email) is more secure than most users’ passwords.
Re: why not just use the email provider as an OIDC. Because (a) not all providers are OIDC-enabled; many people use smaller or ISP-specific emails which don’t have fancy identity provider capabilities. We would like to support them too. And (b) we are talking about email login as a fallback auth flow when you don’t have a passkey set up. Once you do have the passkey set up on the device, you can cut the reliance on any third-party service and just use the passkey.
Passkeys are already synced between e.g Apple devices for people in the Apple ecosystem. Apple may be missing the point of passkeys in your opinion, but the result of not being able to export them is that transferring passkeys between Apple devices is easy, while transferring them to non-Apple devices is impossible.
Mind you, this will only barely improve with this change; it will help people who are transitioning entirely from the Apple ecosystem to some other coherent ecosystem, but it won’t help people keep their keys in sync between their iPhone and their Windows laptop or their Mac and their Android phone. Passkeys remains an amazing tool for Apple to create ecosystem lock-in because they only sync between your iPhone and your Mac.
transferring them to non-Apple devices is impossible.
And I’m saying that allowing transferring passkeys is missing the point of passkeys, which is that they are locked inside the Trusted Platform Module and impossible to extricate, which makes them super-secure. Basically it becomes impossible to be tricked or hacked into giving up the passkey.
If you are allowed to export your passkeys, someone will find a way to trick people into exporting them en masse and leaking them. The article mentions encryption but is light on details so it’s anyone’s guess how secure it will really be.
If you need access on a new device, just set up a passkey on the new device. And possibly delete the one on the old device if that’s desired.
We’re going in circles. Passkeys are already synced between e.g Apple devices for people in the Apple ecosystem. Apple may be missing the point of passkeys in your opinion, but the result of not being able to export them is that transferring passkeys between Apple devices is easy, while transferring them to non-Apple devices is impossible.
Syncing within the Apple ecosystem is an easy problem because Apple can exhaustively enumerate the set of hardware roots of trust that will enforce the required security properties and permit key exchange only with them. This is a much harder problem when arbitrary other RoTs are involved.
You have repeated your previous comment word for word, I understood you the first time and tried to explain why your premise is incorrect (in my opinion) 🤷♂️
I repeated my previous comment word for word because it applies just as well to your response as it does to your initial comment. In other words, circles.
In general, I would recommend against repeating your comments verbatim in discussions, because it makes it look like you think the other person is an idiot who needs to be told the exact same thing over and over again. Please keep in mind that people who don’t agree with you about something are not idiots, and may have valid arguments and reasoning that you just don’t understand 🤷♂️
No, the point of passkeys is not that they’re in a TPM. The point of passkeys is to replace symmetric shared-secret auth with asymmetric auth.
Whether passkeys are stored in a TPM is an implementation detail. I use 1password which doesn’t use a TPM (but also works on every single one of my devices, which is worth much more than storing keys in a TPM.)
That’s the point for power users like you who use password managers. For ordinary people who don’t, one of the huge benefits of passkeys is that their secret keys are unreachable and so can’t be extracted through trickery.
For someone like you who uses a password manager to store your passkeys, a specification for exporting passkeys is a moot point, it doesn’t impact you either way.
I think that the increase in security that passkeys provide is large enough even without HSM backed private keys. For one you can do that still if you care about that threat model, but I’d argue for most people that trade off isn’t worth it, which is why we see these platforms focusing on sync. I have well over 300 items in my password manager, and while I have been going through and making 2 passkeys where I can, it is quite a pain. I also think the export spec isn’t just a plaintext export of the private keys, theres more too it to that to keep folks from getting tricked into exporting them.
Do you need immediate access to all of the 300 items? No? Then why make all the passkeys for them up front? Just make a passkey on an as-needed basis, when you actually log in to that service?
But this seems to rely on every site that uses passkeys implementing them correctly… whereas I’ve seen several cases where they use passkeys essentially like a password alternative: you get exactly one per account. So now you’re stuck and either need to share the passkey, only ever use that account from one device, or still need a password manager to provide a fallback option.
Yes, it’s possible that some sites don’t implement passkeys correctly. Should we really be papering over their deficiencies, or should we accept that they aren’t going to support passkeys properly and move on?
If you use an account on a device, just create a passkey on it on demand.
Without a password manager, how do you do this? I have a number of passkeys saved to my 1password, but without some other form of auth there is no way I could add a new passkey for a new device other than via a usb security key or a password manager with passkey support that lets me bring the passkey to a new machine so I can authenticate and initiate the process of creating a new passkey for that device (but why would I once I have the ability to log in?)
The same way you created the first passkey? Log in to the account with an account recovery method like ‘log in with email’, then create a new passkey once logged in.
there is no way I could add a new passkey for a new device
There is if the app is implemented correctly and lets you create new passkeys once you log in and go to the security/auth settings. Eg, https://github.com/settings/security#passkeys
but why would I once I have the ability to log in?
Because you might need to do it on a new device where you don’t already have a passkey.
ah, I’m used to dealing with the regime of “once you have a security key, you need that security key 100% of the time i.e. to add an additional security key” that is imposed by my employer
That’s how we do it too, whenever I have a say. They break, lose, forget their MFA sometimes, we require an on-site tech to verify their identity before the tech can delete the MFA and let them login and set it up again. The benefit of having 99.9% of staff on our own campuses and dedicated IT at each one.
We are excited to announce pipe: our managed pubsub service over ssh.
We are at a point where we would love to get feedback on the service to see if it resonates with the lobsters crowd. All you need to use pipe is a pico account which can be created using ssh:
ssh pico.sh
We’ve been using it internally for a few weeks now and keep coming up with new use cases. For example, we are using pipe to create a log drain for all of our services and even a way to share logs with users. You can read more about it on our blog post: https://blog.pico.sh/pubsub
Looks cool - where is the source for self hosting?
It’s always great when a managed option is provided but the usecase I have in mind where ssh would be a boon is data I don’t want to share with a 3rd party. It would be amazing if this was an option!
I agree with the sentiment, but I disagree with some of the advice.
IMO the ideal use (and implementation) of htmx would be essentially limited to automatically having the effects of hx-boost="true" on forms, and having it handle a regular Location response header the way it handles HX-Redirect.
As the post says:
HTML and HTTP have the features required
This is exactly why the ‘boost’ concept is good (where it’s appropriate). It’s insanity to me that if you want a form which also works without htmx (or without JS) the “recommended” way to use htmx is to duplicate the target url and request method everywhere.
Maybe we just need a cut down version called html.js.
I agree that would be ideal, but the note you’re referencing also describes why it’s not possible. JavaScript cannot intercept the location header when the response code is a 302/303—the browser will either automatically follow all the redirects (follow mode) or not do that but hide the location header (manual mode). So until proper method support is available in HTML, there’s no situation where a JS polyfill can automatically upgrade the forms in a way that would be forwards compatible with native browser functionality.
Can’t you use Response.redirected and Response.url from a fetch? I built my own little htmx-esque thing a while back and did that to make the form submissions work both with & without javascript enabled (I have comment in the code about it not working in Safari, but not sure if that’s still the case).
I didn’t know about that, I’ll look into it! It sounds like best case-scenario that would result in calling the final route twice though—once to finish the redirect chain and once when you direct the browser to navigate there. That could be an acceptable compromise but it is bit annoying.
Another (also less than ideal) option is to use XHR - without waiting for readystate to be XMLHttpRequest.DONE , if the responseURL property is set, and isn’t the same thing you requested, you can abort the request and then use the new URL for a client side redirect.
Along with this: don’t use booleans as “flags” in your database. Use some sort of timestamp instead. Now you know when it was set, which you’ll suddenly find useful down the line.
Dates make a lot of sense for things where a date is relevant to the actual thing - a publish date, a modification date, a “sale starts”/ “sale ends” field.
The fields where I’m using a boolean in a database, I want to be able to express two, or possibly three actual states (a nullable boolean): “on; off” or “on; off; no preference aka inherit default”.
A date gives you at best “yes, as of/until ; no or maybe inherit default”
If you want to know when some value changed, you want an audit log, which is more useful for auditing anyway because it isn’t limited to storing a the last time it was changed, and it can store who changed it, what else was changed at the same time, etc.
When you do this you use null as default and timestamp as set to not-default at timestamp or? If someone turns off a setting after turning it on you just set it back to null?
Good question, I guess it depends on what you’re using as a “flag” here, but I guess I should have specified for things you’re unlikely to toggle back. I guess once again, a kind of “status”, except not a linear status but various conditions. First one that comes to mind is a “soft delete” or an “archive”.
Why is it that every article attempting to explain how null is some unspeakable horror, includes a tale about some application somewhere comparing to the string'null' and ensuing chaos.
You might as well say “don’t use Boolean, someone might compare it with string 'false'.
Why is it that every article attempting to explain how null is some unspeakable horror, includes a tale about some application somewhere comparing to the string ‘null’ and ensuing chaos.
Dereferencing a boolean (or any other properly initialized value) won’t cause a program to crash. And comparing a boolean to a string will result in a compile-time error. I’m guessing you already know that and are trolling at this point.
Funny story. I was working at a company that was building a high-visibility student transcript system. During a code review, I saw that someone had hard-coded a default value for the last name of a student to the literal string “null”. I brought this to the attention of another developer stating that if a student actually had the last name of Null, they wouldn’t be able to use the system. He went away came back a half hour later and said, “You’re right, that’s a bug.”
That would not have been a fun bug to track down; Hoare strikes again.
Another issue, of course, is that a null sentinel allows comparing two different classes of objects to the same value. (It explicitly excludes the sentinel value from the set of values that are valid elements.)
There are many, many reasons to make software both immutable and null-hostile, which is why the industry is slowly moving in that direction.
Dereferencing a boolean (or any other properly initialized value) won’t cause a program to crash.
You haven’t answered the actual question. Why are people hardcoding a string literal 'null' when comparing to an actual null?
Also, for the record - comparing a string to a boolean is a perfectly valid operation in any number of languages. It will equate to false if you’re doing things properly. I’m guessing you already knew that and are trolling at this point.
someone had hard-coded a default value for the last name of a student to the literal string “null”
Yes, that is a bug, because they’re treating a literal null and the string null as the same thing. If your language, or database doesn’t distinguish between null and 'null', pick a better language/database before you start telling everyone else on the planet that they shouldn’t use literal null, because someone somewhere is stupid enough to compare it with a string 'null'.
As long as you have sane auditing you can always go look. In your version you know what and when. With sane auditing you get all the W’s, well perhaps not they why, unless you go ask the who ;)
It sounds like what they’re suggesting is instead of having is_active, you’d have activated_at with a timestamp instead, where it’s null | timestamp, null being not activated.
Java is still the de facto king of backwards compatibility that actually has the years to show for it. Just based on the title, that ‘title’ would go to Java in my opinion.
I would argue that it is at most as bad as with any other language, but arguably better as the ecosystem is significantly more stable than any other. (What is in the same ballpark in size are JS, and Python, neither is famous for their stability).
But of course third-party libs may decide to break their public APIs at any point, that’s irrelevant to language choice, besides “culture” — and Java’s is definitely not “going fast and breaking stuff”.
Sadly, starting with Java 9, while the core language is backwards compatible, the library situation is a nightmare. And when you’re doing an upgrade, you don’t care if it’s the core language or the library that’s changed, either way, it’s work to upgrade and ensure you don’t have regressions.
Lots of things have changed the package that they live in. In principle, this sounds like it’s not a very difficult change to accomodate, just find and replace, but it wreaks havoc when you have libraries that have to run on multiple JVM versions.
If you’re unlucky enough to be using Spring, it’s even worse. That framework has no concept of backwards compatibility, and is like a virus that spreads throughout your entire codebase.
I can’t share your experience at all. Even large jumps pre-8 to post-11 (though after like 11 they are basically trivial) are reasonably easy, and the few libraries that made use of JVM internals that got increasingly locked down (to prevent further breaking changes in the future) have largely been updated to a post-module version, so very often it’s just bumping the version numbers.
I don’t understand some of what you’re describing.
And when you’re doing an upgrade, you don’t care if it’s the core language or the library that’s changed, either way, it’s work to upgrade and ensure you don’t have regressions.
Are you saying that other languages can somehow prevent the problem of third-party libraries breaking backwards compatibility? Because, if you aren’t saying that, then the core language being stable is going to make the situation objectively better to deal with than if you have to worry about breaking changes in libraries and in the core language…
Lots of things have changed the package that they live in. In principle, this sounds like it’s not a very difficult change to accomodate, just find and replace, but it wreaks havoc when you have libraries that have to run on multiple JVM versions.
Yes, it can be tricky to write code to target multiple versions of Java at the same time, but in my experience, it’s about 100 times less tricky to do this with Java than almost any other language. JavaScript might be the only one that’s even better about running old code on newer runtimes without much problem. Are there others you consider better than Java at this? Specifically for running the SAME code on multiple versions of the language? I remember back in the day when I worked on a lot of C++, it was a nightmare to figure out what features I could use from C++11 to allow the project to build on various versions of GCC that shipped with different Linux distros (Ugh, RedHat’s ancient versions!).
Are you saying that other languages can somehow prevent the problem of third-party libraries breaking backwards compatibility? Because, if you aren’t saying that, then the core language being stable is going to make the situation objectively better to deal with than if you have to worry about breaking changes in libraries and in the core language…
I think that depending on the community, some languages have less BC issues because of libraries than others. Case in point for me was Clojure: both the core language and community have a stance of avoiding breaking compatibility, even if the language itself doesn’t offer any special mechanism for that. Quite the opposite actually, since the language is really dynamic and you can even access private functions without much difficulty.
Are you saying that other languages can somehow prevent the problem of third-party libraries breaking backwards compatibility?
Of course they can’t, and that’s not my point.
My point is that communities develop norms, and those norms include more or less careful treatment of backwards compatibility in libraries. My sense is that Haskell and JavaScript are probably the worst. Java is actually mixed, as there are a lot of libraries that do great work. Some even have a single version that runs on Java 5 through Java 21. But at my day job, we’re using Spring, and the situation is bad.
Though with regard to languages, I will say dynamic class-loading can make the situation worse. I’ve dealt with issues where the order of requests to a web server determined which version of a service provider was loaded. So 9 times out of 10, the code ran on the newer version of Java, but failed 1 time in 10.
Because, if you aren’t saying that, then the core language being stable is going to make the situation objectively better to deal with than if you have to worry about breaking changes in libraries and in the core language…
It sounds like your argument is “having two problems is worse than having one”. But two little problems are better than one big problem.
I greatly appreciate the backwards compatibility of the Java language. But I would be happier with a slightly less backwards compatible core language, if I could trade it for an ecosystem that’s much better at backwards compatibility.
My point is that communities develop norms, and those norms include more or less careful treatment of backwards compatibility in libraries. My sense is that Haskell and JavaScript are probably the worst. Java is actually mixed, as there are a lot of libraries that do great work. Some even have a single version that runs on Java 5 through Java 21. But at my day job, we’re using Spring, and the situation is bad.
Right. I understand and agree about ecosystem “culture”. But, at the end of the day, someone said Java was good with backwards compatibility because it makes it easy to write code that will continue to work “forever”.
I guess maybe your point is that the language prioritizing backwards compatibility is only necessary, but not sufficient, for developers actually getting to experience the benefit of the backwards compatibility. Would you say that’s a decent interpretation/restating? I do agree with that. And if the language itself doesn’t care about backwards compatibility, then it’s impossible for the ecosystem to have stability.
Though with regard to languages, I will say dynamic class-loading can make the situation worse. I’ve dealt with issues where the order of requests to a web server determined which version of a service provider was loaded. So 9 times out of 10, the code ran on the newer version of Java, but failed 1 time in 10.
Definitely true! Luckily, I only remember one time where I had a nightmare of a time figuring out some class or service loading bug.
It sounds like your argument is “having two problems is worse than having one”. But two little problems are better than one big problem.
Yeah, that’s exactly what I was saying. But there’s no reason to think the “one problem” (community doesn’t value backwards compat.) would be bigger or smaller for either case. So, it’s like comparing x to x + 1.
I greatly appreciate the backwards compatibility of the Java language. But I would be happier with a slightly less backwards compatible core language, if I could trade it for an ecosystem that’s much better at backwards compatibility.
I really feel like this is mostly just Spring. I hate Spring, too, so I have been fortunate enough to not have to use it in several years now. But, as for the Java libraries I am using, I honestly couldn’t tell you about their JVM version compatibility over time. But, just judging by API stability, it seems that most “general purpose” or “utility” style libraries stay pretty backward compatible (thinking of the Apache and Guava libs, etc). It’s mostly the frameworky ones (like Spring, Spark, etc) that like to rewrite big chunks of their APIs all the time.
Can you give an example of what you’re referring to?
I’m semi-active on the PHP internals mailing list (i.e. the list where development of php itself is discussed) and BC breaks are a near constant discussion point with any proposed change, so I’m kind of curious what breaking change you’re referring to here?
Well, since I’m not the person you originally asked, I obviously can’t speculate on which breaking changes they’ve actually bumped into. But, I’ve works on several long-lived PHP projects going all the way back to version 5.3 and all the way up to 8.1 or 8.2 (I don’t quite remember which), and I’ve definitely had to fix broken code from minor version bumps. Luckily, we do have those migration lists, so I learned pretty early on to read them carefully and grep through any code base to fix things on the list before even running unit tests.
But, I’m not sure what the point is. The person said that PHP introduces breaking changes in minor version bumps, and that it frustrates them. Maybe they’re misguided for being frustrated by that, but it’s objectively true.
Personally, I’m perfectly fine with breaking bug fixes in minor versions. It’s not like you’re going to accidentally or unknowingly version bump the programming language of your projects. On the other hand, many of these changes are NOT bug fixes, but just general “improvements”, like the range() changes or the “static properties in traits” change in the 8.3 list. I can see how this would be frustrating for someone who wants the bug fix changes, but doesn’t want to pay the extra “tax” of dealing with the non-essential breaking changes.
But, again, I personally don’t care. I treat PHP minor versions as a big deal. PHP 8.2 is not the same language as PHP 8.1, which is fine. But, if you care about backwards compatibility and painless upgrades, Java is pretty much the king.
It’s mostly the ripple effects into libraries and “big” frameworks. For instance, I remember a few years ago a client was on still on PHP 5.3 (I think) and his hosting provider was about to shut down this version, so he had to get his site working on newer versions. This site was built on an in-house CMS of questionable code quality, using CakePHP.
The problem I ran into was that I had to step-by-step upgrade CakePHP through some major versions because the older versions wouldn’t run in the newer PHP due to BC breakage. Eventually, I completely hit a wall when I got to one major version where I discovered in the changelog that they completely rewrote their ORM. Because of the shitty code quality of the CMS (with no tests), I had to admit defeat. The client ended up having to commission the building of a new site.
Java and Go are really great in this regard.
Every other language, including Python (which makes breaking changes from 3.12.3 -> 3.12.4!) is horrible on that front.
I think this is just an extension of the buzzword-itis our industry seems to be forever saddled with.
I don’t actually recall the last time I saw anyone use the term “devops” the way it was originally intended (i.e. infrastructure as code, using generally-accepted development practices to approach operations, etc) - it’s essentially been coopted (I think largely by HR/management types) to mean “we want our developers to understand enough Bash and AWS console to make something kinda work”.
The dangerous part to me, with the definition of SRE in the article (ops who also creates new programs) is that you’re relying on the speaker’s intention to distinguish what you mean, from the plethora of “full stack code ninja” that will happily claim to be “expert” across domains from <insert graphics editor of your choice> all the way to server-side kernel hacking, and generally ends up being a jack of all trades, master of none.
I’m not saying it’s impossible for a single person to be very good at all the things that covers. I’m just saying that it’s statistically unlikely that most who say they are experts across that whole range, actually are.
I’m not saying people can’t be good at more than one thing. I wouldn’t use the term SRE myself but most of my work falls roughly into the description the author uses. But the moment you try to codify (only a small pun intended) some idea of complimentary tech skills behind a term, it’s almost guaranteed to get used and abused to the point of being meaningless.
I’m also not saying there isn’t a place for a jack-of-all-trades types. But as your team size increases, the appeal of that skillset rapidly decreases IMO. Having 10 people who have shallow knowledge of everything is nowhere near as useful or productive as 6 really great backend-focused developers, a UI/FE dev, a sysadmin, a tester and one jack-of-all-trades.
It’s helpful to have some people who can step into a number of roles to help out. It’s not helpful to be completely reliant on people with shallow-to-medium depth knowledge/experience of everything.
This is a fascinating perspective because it’s about an emergent property of SREs rather than a definitional property. SREs never had to generalize to full-stack development, but were forced to do it as the job market went sideways over the past decade.
To me, SRE is fundamentally about systems administration without developers. A common test of this is that an SRE team should be able to classify its owned components into three bins: those actively developed by another team, those developed by SREs in collaboration with support from other teams, and those developed solely by the SREs themselves. Crucially, an SRE organization isn’t healthy unless any component in the first bin can be disowned by the organization and returned back to its active developer team. This is a systems-first way of computing; the stability of the system is more important than the ability of developers to mutate it.
Please forgive me for the “devops” tag. I felt this so much, and it’s extremely annoying to see in the wild. Heck, my own company has a separate “SRE/Ops” team that just does ops. They pride themselves in the fact that they don’t write code and they “hack stuff together with bash”. While I sit across the hallway doing actual SRE work in the Kubernetes team.
As annoying as it is to see technical terms lose their meaning, I’m sure those people don’t deserve to be called monkeys. It’s OK to be content with doing only ops.
I don’t know the author or GP commenter, but I’ve always seen the “$x monkey” term as “someone is happy doing $x in their role and isn’t concerned with outside issues” - e.g. in Jonathon Coulton’s Code Monkey: https://www.youtube.com/watch?v=v4Wy7gRGgeA
I don’t think there’s necessarily a negative connotation associated - but as I said I don’t know the author of the article, and their reference does seem to be less enthralled by someone who has chosen/is happy to specialise in ops (aka what we used to call sysadmin) so maybe my read is wrong and it was meant to be disparaging?
I’m not saying “doing $x makes the person happy regardless of other factors” I’m saying that $x is what they are happy to (read: want to) focus on in their work.
But he hates his job too. Anyway, it’s possible your meaning is the generally accepted one, just that using the song as an example isn’t backing it up.
I don’t think I can agree with that assessment, I think what you’re attributing to “hating his job” is more like frustration at not being appreciated for what he does.
This is what Jonathon said when he first released the song:
Yay, monkeys. This is not autobiographical, but I did indeed used to have a job writing software. VB! MS SQL! I affectionately referred to myself and my co-developers as code monkeys, especially when a client asked me a question that I didn’t want to answer (“What do I know? I’m just a code monkey.”).
I mean, I think it’s pretty clear from the lyrics that he hates his job - he pretty much straight-up says that he’s only there because of the receptionist (I think?) he’s in love with, and who seems to be uninterested in him. “Code Monkey have every reason to get out this place […] This job fulfilling in creative way - what a load of crap.”
But perhaps he does love coding - his horrible job aside.
(This is something I reflected a bit about in a particularly soul-crushing job, three jobs ago: I loved coding, but at that point I felt like I hated having it be my job.)
I am perfectly happy describing a job as “Rack monkey.”
And then you can describe a person by their job. “Administrator” “Devops guy” “Dev.” But everybody of course needs to understand that a person’s job does not define a person, and every job needs to be filled by somebody.
Some of these jobs of course are lower paid, partly because the gap between a competent professional and inexperienced intern can be just a few weeks of training.
Nobody is being called a monkey. When the post says “people who basically were ops monkeys.” that describes people’s preferred job, not the person.
I’m not really a python guy (I’ve made a few small patches here and there to upstream projects to scratch specific itches, nothing more) but I feel like if you’re already using a virtual env, you’re solving most of the problem containerisation solves anyway.
So, my question would not be “why are you using venv inside Docker?” my question would be “why are you using Docker?”
If you’re building web apps – which is a major use case for Python – it is virtually certain these days that your deployable artifact is a Docker container. That’s just how infrastructure works nowadays. So learning how to do things well in a Docker deployment scenario is kinda important.
I don’t know what to tell you, Docker and Kubernetes ate the world. Tooling these days is entirely optimized around the assumption you’re doing one or both, and even things that don’t necessarily look like they’re Docker/k8s often are under the hood.
I’m certainly glad mine isn’t the same as yours, given how you describe it.
Edit for clarify: I’m not nit picking about whether people use Docker specifically as the container runtime, and to be clear when I say “different worlds” I don’t mean “web apps” vs other software development.
I’m saying that while containers are a popular deployment target for server side web apps, they aren’t the only solution used in 2024.
The last time I worked someplace where Docker/k8s (as a stand-in generic term for “some type of OCI containerization and associated orchestration system”) wasn’t the way you deployed stuff was… nearly ten years ago, now, I think?
Even places that didn’t use literal explicit Dockerfile or whatever often deployed on things like Heroku or other CNB platforms (which are, surprise surprise, containers under the hood, just with a different way of writing the manifest for how to build them).
Amazon’s EC2 business would like to have a word (some of it is just ECS workers). Hashicorp Nomad would like to have a word too, as would every vendor that ships Debian packaging upstream (Grafana, Redis, Elasticsearch, Microsoft SQL Server, etc. etc.).
“Plays nicely with” is very different from “entirely optimized around the assumption you’re doing”.
At $work we deploy our webapp with golden AMIs built by Packer.
We should maybe stop always saying “Docker container” in this kind of general context though since these days I wouldn’t bet Docker is the actual runtime of most containers out there.
I feel like as a genericized term it works better than “OCI-compatible containerization system”. Even people who are explicitly not using Docker to build their containers would probably still understand that “Docker” doesn’t mean “literally only the exact command-line tool named docker”.
Feel free to feel that but I’d in those context for example say “container runtime”, if that’s what I mean. Or I might say “OCI runtime” if in the context it needs to be clear I don’t include Flatpak/bubblewrap/Snap/whatever.
Most of this is lame. Number representation problems aren’t part of JSON, they’re the fault of JSON parsers that just convert all numbers to doubles, just because “thats what JavaScript does”. It’s not much harder for the parser to pick an appropriate representation for each number, like using int64 unless there’s a decimal point.
Unicode has weirdnesses too, but what data formats go to the trouble of specifying in exhaustive detail exactly what forms of encoding and normalization to use? I don’t think this is a specific fault of JSON.
ProtoBuf just isn’t comparable. It’s a much more complex format that requires a schema definition to be parsed at all. It absolutely does not fit the same use cases as JSON.
Nah you don’t get to put the blame on parsers here. The problem is that JSON is under specified. Parsers aren’t doing anything wrong, it’s perfectly in line with the spec to convert all numbers to doubles. Hell, considering the history of JSON as “JavaScript Object Notation”, converting all numbers to doubles was probably the original intention behind the spec.
What is it about specs that leads to this kind of reasoning? “Either the spec is wrong, or the user is wrong, which is it?”
I’m not at retirement age, but I’ll pull the grumpy old man card and say “they’re both wrong.”
If the spec gives you a terrible option, you should criticize the spec for it. If you take the terrible option, you should also be criticized for it. There is more than enough blame for everyone to get a bit.
JSON absolutely has culpability here, because it doesn’t nail down what a compliant parser should do. The only thing approaching a defense is to say “this format was built to be used by javascript engines that can only natively represent doubles, the idea of using it elsewhere was a mistake.” But even if you went that route, why not just specify that all numbers are doubles? You’d make it much clearer what you could and couldn’t use the spec for.
If you make a bad design decision in your parser and defend it with “the spec says I’m allowed to do this” it doesn’t suddenly make it not a bad design decision!
I’m not sure how json is underspecified. json.org says “number”. It doesn’t say “float”.
The problem is that the parser output doesn’t match the parser input. i.e.
print(parse(foo)) != foo
This seems like a pretty serious bug to me. Maybe I could understand the output order being changed, as json.org doesn’t specify ordering of fields. But to change the content of a field? Come on… that cannot possibly be a good decision.
That’s impossible with fixed precision numbers in general.
But.. what is a “number”? It can’t be a number in the mathematical sense, the syntax is too constrained for that (it doesn’t allow the number 1/3, or pi etc).
And, it’s clearly not one of the “normal” numbers computers work with like ints or floats - the syntax is an arbitrary precision decimal.. is that what you mean parsers should require as input and output?
I can kind of get behind the purity of that, but it sure makes JSON a lot less convenient if you can’t say “JSON.dumps({“myval”: 1})”
That has been explicitly part of the JSON spec for ten years. Even before then, any JSON implementation that used numbers that don’t fit in float64 was asking for trouble because there have always been JSON parsers that only support float64. Causing interop problems by using wider numbers is a bug, a failure to be conservative in what you send.
Yeah, we ran into this. Our C++ JSON parser would handle uint64 correctly. One of the consumers was JS though and would lose precision when converting the numbers to float64s (as expected), resulting in duplicated ID numbers with the JS client but not the C++ clients.
100%. People love to give PHP shit for foot guns, but the built in json decoder will return an integer if the json value had no decimal (and fits within an integer).
But even more egregious than the “some decoders do stupid things” excuse is the “some end users do ridiculous things” excuses.
Really? People are storing license keys, credit card numbers and the like as integers? I thought we had this discussion years ago about not storing phone numbers as integers and people learnt the lesson?
I think it is! ProtoBuf is as good implementation of a schema full data format as JSON is an implementation of schema less!
I’ve got a long draft of a blog post that goes on and on about protobuf’s footguns in the same vein as this post. Sounds like you might have some material to contribute? ☠️
There’s another fun aspect to this that we ran into at work: if you happen to use JSON and accept integers which you use in a database query, make sure that you get only integers and not floats, or even bignums (if sufficiently large).
If you don’t ensure you have proper integers in an expected range, the float or bignum can cause your query to fall back to a full table scan. For instance:
SELECT foo FROM large_table WHERE id=1.0
will not be able to use your carefully crafted primary key index because of the type mismatch (assumingid
is a normalint
orbigint
). This allows attackers to slow your database down to a crawl simply by tweaking the JSON slightly.This only (or mostly?) affects dynamically typed languages like Python (or in our case, Clojure).
Even better, the parser could return the original string representation of a number and let the user decide how to interpret it. This works especially well in streaming pull parsers (as opposed to parsers that produce an in-memory representation of the entire document) where the user can just call the appropriate value accessor (
value<uint64_t>()
,value<double>()
, etc) without having to store the string representation long-term.Yeah, the Go JSON parser added an option to do this a while ago.
You can make a better parser, but now your JSON documents aren’t going to be compatible with the ecosystem! The original JSON use case was JavaScript web stuff, and back then, JS didn’t even have integers, it only had doubles. So you had to stay within the limits of doubles. You just had to. Just because this sucks, we can’t expect the entire JSON ecosystem to just fix itself. Much better to use a format that has a specification which is strict about what parsers must support.
Continuing the Christmas present build from last week.
Might try to sneak in building a little shelf for battery chargers while I’m in the shed.
Starting to build my son’s Christmas present: a flippable play table for lego/messy things (i.e. play dough, clay, etc).
I can’t even begin to imagine how services that don’t properly support diacritics process Chinese, Japanese, Korean, Arabic, Thai, …, names.
I’ve never flied before, but what happens if you’re being checked out on an airport and they cannot read your name? Do passports from countries speaking non Latin-based languages have romanisations of names written on them?
The optically-readable part at the bottom of the photo page of an IATA-compliant travel document has an ASCII-only form conforming to IATA constraints. This means that even if the name is in the Latin script, there’s an IATA ASCII version. For example Finnish ä becomes AE and ö becomes OE even though this German convention does not make sense for Finnish.
Is that really a generally applied rule? I thought that was determined by the issuer, and some countries afaik even let you specify what you want it to be (within reasonable variants of writing your name obviously)?
ICAO recommends (but does not require) that Ä be converted to A or AE (and Ö to O or OE) in the machine-readable part of a travel document. Maybe the rule is stricter for EU passports?
Relevant document of ICAO requirements and recommendations for names in travel documents: https://www.icao.int/publications/Documents/9303_p3_cons_en.pdf
Sorry about getting IATA and ICAO mixed up above.
As the spec shows, the transliteration is algorithmic even if there are options for some characters. The options aren’t available to individuals: Finland does AE for ä without asking the passport applicant.
Not sure how much of a mess it would be to change the transliteration. (IIRC, at some point Russian passports switched from French-based transliteration to English-based transliteration. There must be some failure stories about that.)
If I remember right, Japan was an example of a country that does let the applicant specify. But of course there its a much bigger “gap” being bridged by the transliteration.
Yes, the important fields (name, country of citizenship, etc) are in Latin characters. A search for 「日本国 旅券 見本」 (Japanese passport sample) yields https://www.city.kishiwada.osaka.jp/uploaded/image/56222.png, which is detailed enough to get the gist.
Depending on the language of origin there can be some subtleties in how names are rendered into Latin – either the government has an official romanization scheme, or they let the preferred romanization be written into the passport application (within reason).
Thanks, that’s informative.
I find it a little surprising that they don’t have both the romanisation and the local writing system.
It would not surprise me if there’s a limitation to freakin’ Baudot code considering the age of some air traffic systems…
My wife and son‘s thai passports have their respective names in both languages, but other details in English only.
Their Thai ID cards have more details in both languages, but they also cram much more information in, and I believe the Thai ID system revolves much more around just knowing the ID number than relying on being able to read the details on the card quickly.
It is becoming much more interesting when a country has more than one official language, and Latin transliteration is different depending on which language is used for it.
Even within a single language you can still be stuck with multiple romanization schemes; for example there’s 4 or 5 in regular use with Thai, and they are all roughly equally decent if you stick with one consistently, except the main one used for road signs, which frequently renders multiple different Thai sounds with the same latin letters.
At least for Russian, the passport transliteration is a bit of a mess
https://en.wikipedia.org/wiki/Romanization_of_Russian#Transliteration_of_names_on_Russian_passports
No not really. But then again, I also didn’t want to see how “everything will use Blockchain, bruh”, and the vast majority of my work related to “cloud” services, has been migrating clients off of the over hyped circle jerk that depends on a bottomless bucket of (often VC) money to make much sense.
Now if you’ll excuse me I have to go look at the grey hairs in my beard and yell at some kids on my lawn.
You’re telling me there’s yet another reason to stick to POSIX shell? I am shocked I tell you, shocked.
Well not really that shocked.
True, but it’s not enough that your source code is POSIX shell. You also have to run it with a shell that’s not vulnerable! For example, this is a POSIX shell program:
And it’s vulnerable when you run it under bash/ksh, but not when you run it under dash, busybox ash, or OSH!
the reason that some OS’s decide that when i say “/bin/sh” what i really meant was some other shell that’s not sh is why i have trust issues. i’ve been told that it’s fine though, and to stop being pedantic.
Yeah it’s best if
/bin/sh
is a judiciously modernized Almquist shell.I think this is a good reason to not use shell, or at least avoid as much as possible in any context that the user can control the inputs, because it is so easy to commit mistakes in shell, and as another commenter said below you can’t even trust that your POSIX compliant script will run in a shell that handles this (and other issues) correctly.
The “future investment” part seems to fly in the face of what the CEO said 11 months ago: https://www.theregister.com/2023/12/07/broadcom_q4_2023/
I would bet $100 that this is because adding a consumer checkout to the Broadcom website isn’t worth the revenue of these products.
When they bought VMWare they pushed all “consumer” purchases (i.e. Fusion) through resellers. I did it once, and it was a fucking nightmare to use.
That was my guess as well. Even prior to Broadcom, the development pace of both (especially workstation, which is what I was using most) seemed to have slowed to the point that it’s have been hard to believe they saw much revenue potential there. And with Apple Silicon, Fusion seemed to move from a common tool (that I’d buy with every mac I purchased/approved) to a really niche thing.
It’s easy to imagine it’s a better promotion for datacenter products than standalone moneymaker, especially once you factor in a company that’s not equipped for it needing to open a channel for consumer sales.
Huh. That is an interesting workaround.
It does make me wonder, though, why it’s always set up w/
User git
andgit@...
. I tried reading that part of the book but I still don’t get it. I guess the config is by-Host and not by-User-&-Host? Yeah, darn. Which makes this solution all the worthwhile! since it basically gets you thereI think this git@ thing became the norm back in the early years of git because there were a few trouble spots that made it awkward to set up a multi-user repository hosting server:
there were fewer ssh server implementations, and openssh was (and is still) not very friendly to a server admin who wants to make significant changes to how it handles logging in, in particular it’s hard to decouple the username requested by the client from a unix account
provisioning a whole unix account per user means you then have to deal with crossing privilege boundaries so that multiple users can write to shared repositories without messing up the permissions; it adds lots of complexity to administrative / back-end software
it would be like reverting to the way source repository admin was done with CVS in the previous century, yuck
The usual solution implemented by git hosting projects such as gitosis and gitolite was to use a single git@ unix account with a monster ssh
authorized_keys
file that does some special things:uses a forced command so that clients are dropped into gitolite and can’t get a shell
passes the key owner’s username to gitolite so that it can implement fine-grain access controls
I have no idea how github worked back then, but I ran a small git hosting service for a university using gitolite, and before that I ran a CVS server. Unlike CVS, with gitolite I was able to delegate user administration to whichever research groups wanted to use it, and they could (and did) give access to colleagues in other universities without me having to lift a finger. Made me happy that it supported open collaboration as I hoped it would.
Dogshit UX though, but it successfully demonstrated that there was enough demand for a university git hosting service that people would put up with a bare minimum service with <0.1FTE staffing.
There is no requirement from git itself to have the user you use for SSH be named git. In fact you can push/pull from a remote server using whatever username you want.
See https://superuser.com/questions/230694/how-can-i-push-a-git-repository-to-a-folder-over-ssh for an example of how to set this up. You need a bare git repository on the remote server, but after that you can push/pull over SSH without issues, using whatever username you want to use.
Most hosted git services have all users connect as an ssh user called
git
, and then use the incoming public key to identify the ‘user’ from the point of view of their own system (i.e. GitHub username), rather than using your username within their system (i.e. GitHub username) to connect to the SSH service for git to communicate over.I suppose it gives them more control over things, and it makes it slightly simpler to give people instructions (i.e. you don’t need to know someone’s service username to give them a ‘guaranteed to be correct’ clone URL.
I believe this is also partly so clone instructions work uniformly. Asking people to clone with git@service is easy, asking them to clone with {replace this with your username}@service is annoying because it breaks copy and paste. If they then use submodules, it breaks entirely (you probably want to use https for public submodules and use an insteadOf rule if you have a GitHub account, but for private ones you may want to use ssh unconditionally).
Or you could just give the element data-whatever attribute with the value you want, and then have css do it for you.
All this bizarre re-creating the wheel in ever more ridiculous script, just to save having a couple of lines of regular css.
A building in (very) clustered university I visited many years ago had the ground floor for the elevator set at -1. After asking around it turned out that the floors were indexed relative to a reference building. The ground floor on that building was at a lower relative elevation because of the steep hills these were built on. I think that was the point that started me mentally prefixing most anything with “is it base + offset (0) or index (1) and what’s the base?”.
In NZ and Aussie at least the ground floor of a building is zero, 1==the first floor above the ground, G being the zero of the system. There’s no reference building involved ground floor = 0, below ground floor number varies (b1,b2, I recall being common, I think I recall -1, -2 etc).
As an Australian, it’s not “floor zero”. It’s the ground floor, i.e: ground level.
My understanding is that we inherited this from the British which use the same standard.
Americans having their own standard is fine too.
What’s not OK is places where there is no agreed upon standard and thus you end up with different buildings starting at different levels.
I’m an Aussie who’s lived in the US for now more than half my life and I still can’t deal with 1 indexed floors.
Good lord that is confusing! I can only assume the buildings must be connected, and they didn’t want the floor number changing on you.
Surprisingly many buildings here in Sweden have this quirk too. Often giant hospitals planned and built in the 60s and 70s go all in on some “rational” floor numbering scheme that’s designed to confuse patients.
This was at KTH - buildings connected underground by tunnels
Having worked in a university where many buildings grew into each other and you could walk between floors 3, 5 and 6 of different buildings without ever stepping outside or changing altitude relative to your starting position, I think it sounds like a lovely idea.
Engineers, man. They’re the worst.
As I said, a year ago on https://lobste.rs/s/nqk2pm/software_component_names_should_be, discussing whimsical names for software:
The only thing that’s changed is I’ve leaned into whimsical names more. KSSL has been renamed, specifically because it was a fucking horrendous to read, write, or speak. So it’s now Alpinia[3]
3: from the readme: The name ‘Alpinia’ comes from a genus of plants commonly known as “shell ginger”.
IMHO, being able to export passkeys is missing the point of passkeys. They are supposed to be cheap and easy to create so you should be able to set up a passkey for your account on any device/account/browser that you use. If you use an account on a device, just create a passkey on it on demand.
Exporting passkeys would make sense if it was expensive or complex to set them up. I guess it depends on the account provider how easy or difficult they make it, but making it difficult to set up a passkey on a device seems like a great way to kill their adoption.
Expecting people to log into all online services they use and set up a new passkey for each of them when they switch devices is also a great way to kill their adoption, as is expecting them to tie all their logins to a singular account with a sync provider.
I know. That’s why I said they people can do it on an ‘as-needed’ basis, and not pay the entire setup cost up-front. When you need access to an account, log in with an email flow, then set up a passkey. If the app is designed correctly, you should be guided on this flow automatically.
Please define what you mean by “login with an email flow”?
Exactly - or in other words: then how is the email account protected?
Forgot password should NEVER EVER EVER be part of the normal flow. It must always be a thing that you only need to use in emergencies. Having it be part of the normal flow leaves zero margin for error.
There are already many sites out there that default to logging in with email only. Actually, any service that studies their users’ login metrics knows that a significant number of people always use the ‘forgot password’ flow to log in to their account, because they can’t be bothered to even remember a password. They just use the path of least resistance. I’m just suggesting using that as a convenience to set up a passkey on a new device, to create an even easier and more secure auth flow.
Both of those things are widespread systemic failures.
No, that’s just an unforeseen emergent property of a designed system. See also https://en.wikipedia.org/wiki/Desire_path
How so?
Forgot password is a last resort. If that doesn’t work then you’re locked out. You should never need to use it unless there’s an emergency. Switching platforms absolutely does not qualify.
I’m thinking about it in terms of incidents at organizations that cause people to be woken up at night. Forgot password is an escape hatch for that level of severity.
I regard forgot password as just another means of authentication, nothing more or less. And if it was so critical, then it’s a joint that should be well oiled.
Of course ‘forgot password’ is a last resort, I never said otherwise. But users need some way to recover their accounts if they lose access. You can’t just lock them out forever. At least, no sane website is going to do that. You are going to have to offer alternative login methods, and ‘forgot password’ with an email flow happens to be the most common one, which is why I suggested repurposing that as a step towards setting up a much easier and more secure passkey auth. If you have a better alternative than ‘forgot password’ to recover access so the user can log in and set up a passkey, then of course go for it.
Yes you can. Companies are already doing it. Even Google does it. And many companies require 2FA and lock you out if you lose access to your phone number. Some don’t even allow you to setup a third factor for recovery. This is reality and chances are with passkeys it will get worse.
But having a “forgot password’ flow immediately invalidates lots of the arguments in favor of passkeys. E.g. phishing now works. E.g. present the user a fake bank website and show them a message that says “we have updated our security and your old passkey no longer works. It seems your device is unable to do that automatically, so please use the forgot password flow to do so” yadda yadda and we are back to square one.
OK, good luck being a viable business that locks out users forever when (not if) they lose their credentials. IMHO, the risk of the ‘email login’ flow is being greatly overblown when you don’t actually have passwords, only email login and passkeys. First, the malicious actor would have to go to the real bank website, enter your email address, and initiate the email login flow. Then, they would need to immediately send you another email telling you to click on the given link and enter the temporary token from the first email there. Chances are really good that if the temporary token expires in 5 minutes, the intended victim wouldn’t even open these emails in time to enter the token. And even if they did, the first (legit) email from the bank should warn them against entering the token into any other page than the bank’s. And if the attacker floods the victim with a flurry of ‘email login’ emails, anyone would be able to tell something phishy is going on.
I think if you tie this all to a malicious link the user has followed, you can make doing all this a lot smoother. It would depend on egregious user error (entering the code in the box on the phisher’s site that it presented them and told them to post the code in, rather than following the link in the email), but egregious user error will happen some of the time.
How exactly? What’s the flow after the user follows a malicious link?
Realistically, the “forgot password” flow is probably used extremely routinely by most users. And I kind of expect that routine use of passkey re-enrollment flows will become just as common if passkeys catch on. Which means that passkeys can’t be, in practice, any more secure than their re-enrollment flows.
Related: https://lobste.rs/s/uooaw4/email_is_authentication_pattern
Exactly https://lobste.rs/s/wmu16g/new_passkey_specifications_will_let#c_ne7ag1
If you have a passkey on your phone, and your phone gets stolen/hardware dies how do you recover if you haven’t created backup passkeys ahead of time on other devices?
Also how do you migrate passkeys to a new phone from the old one when you upgrade your phone?
In a sane world the service/site you’re trying to use would have ensured you’d created recovery codes or similar. But given we don’t live in a sane world, the option to backup/export passkeys does seem like one I’d like to have :/
Recovery codes are for emergencies, when there’s been a system failure. Using another ecosystem is not an emergency.
Of course, the best place to store account recovery codes is in your password manager, because it should be well maintained with decent security and availability.
So now we again have something that can be phished.
You log in to the account whose passkey was lost with an account recovery method like ‘log in with email’. Then you set up a new passkey on the new device. And, if the app is implemented correctly and lets you manage passkeys properly, you delete the passkey that was on the lost device.
But if you preserve that email flow as an option, you break the benefits of credentials being tied to device hardware, and are back at needing password + second factor + backup second factor.
No you’re not? You can have an email login flow and then use it to set up a passkey on the device. You don’t need password + MFA at all. But you need to offer some way for the user to recover access to their account even if you don’t have passkeys. You can’t just lock users out of their accounts if they forget their credentials. Can you?
No. Please. Stop it. This is actively hostile to users.
I have over 1000 logins. I don’t want to re-enroll passkeys 1000 times per device.
Your objection is based on the fear that re-enrolling is going to be a horrendously complex and slow process. What I am suggesting is to make it a smooth and easy process, almost as natural and quick as logging in with a passkey and Touch ID. If you do this on an as-needed basis, the burden won’t even be noticeable.
Please don’t try to convince me that you need to access your 1000 logins on your new device immediately as soon as you get the new device because you know that’s not true 😉
Not all of them, sure, but any one of them, yes. And there is literally no way to know which of the 1000 you’ll need next. You’re describing a Kafkaesque hellscape of bullshit any time you get a new phone or laptop or something catastrophic happens to one of your OS installations or tokens. It’s completely unnecessary tedium and I hope to god that we’re somehow lucky enough that the people working on the specification actually listen to what people want instead of just being smug and argumentative like you are in the comments here.
I don’t think you need to worry so much; we are literally discussing an article which says that passkeys can be exported. The people working on the specification clearly want this. All I’m saying is that in my opinion exporting passkeys defeats the point of passkeys. If you want the burden of having to manage passkey exports (which are going to get outdated at periodic intervals), that’s on you 🤷♂️
I think it’s important that passkeys provide support for the model you’re describing, because creating private keys inside boxes you can’t remove the keys from (smart cards, HSMs, etc) is a strong security model.
That said, for most people most of the time it’s bloody inconvenient. If you require people to maintain two or more passkeys in every place that they store accounts, and you don’t allow exporting, you’re basically guaranteeing that people will lose access to some of their accounts from time to time. This is basically like backing up your data: the only thing that works for most people most of the time is something automatic like periodic backups to the cloud that they don’t have to remember to do or really manage at all. The more first class the mechanisms for passkey export and portability are, the more likely the end result is something that balances security with the reality of how people actually use their computers, as well as providing some much needed user control of their own data.
No; I’m calling for a model which guarantees users access to their accounts in a simple and secure way in all situations, whether they have a passkey or not, as long as they have access to an email account. Let me detail the flow again, in case it helps:
From the user’s perspective, this process is minimally intrusive, not cumbersome, while still being as secure as possible.
It’s basically the opposite of secure. “Log in via email” emails are sent in plain text out into the world. They’re generally short codes that you copy and paste, which are the thing most likely to be phished from users.
It’s also absolutely cumbersome. To log in I now have to go and find the message in my email, do something with it, delete it. I have to switch between browser tabs and generally screw around. Sometimes mail delivery is not instantaneous. Regular passwords are a thousand times better than this flagrantly user hostile experience, because at least there are mature password managers that integrate with browsers and don’t require anything but a couple of in place clicks on the login page to use.
You’re also ultimately just punting authority to the mail provider for all authentication. It would be better to just demand all websites use OpenID Connect to use your mail provider as an identity provider; at least that would be both secure and convenient for users.
The problem is most people don’t use password managers. Why do you think ‘Have I been Pwned’ exists? It’s because people keep using bad passwords and repeating them in multiple places. In light of actual user behaviours, it turns out that short-lived email tokens (which can be sent via TLS-encrypted email) is more secure than most users’ passwords.
Re: why not just use the email provider as an OIDC. Because (a) not all providers are OIDC-enabled; many people use smaller or ISP-specific emails which don’t have fancy identity provider capabilities. We would like to support them too. And (b) we are talking about email login as a fallback auth flow when you don’t have a passkey set up. Once you do have the passkey set up on the device, you can cut the reliance on any third-party service and just use the passkey.
Passkeys are already synced between e.g Apple devices for people in the Apple ecosystem. Apple may be missing the point of passkeys in your opinion, but the result of not being able to export them is that transferring passkeys between Apple devices is easy, while transferring them to non-Apple devices is impossible.
Mind you, this will only barely improve with this change; it will help people who are transitioning entirely from the Apple ecosystem to some other coherent ecosystem, but it won’t help people keep their keys in sync between their iPhone and their Windows laptop or their Mac and their Android phone. Passkeys remains an amazing tool for Apple to create ecosystem lock-in because they only sync between your iPhone and your Mac.
And I’m saying that allowing transferring passkeys is missing the point of passkeys, which is that they are locked inside the Trusted Platform Module and impossible to extricate, which makes them super-secure. Basically it becomes impossible to be tricked or hacked into giving up the passkey.
If you are allowed to export your passkeys, someone will find a way to trick people into exporting them en masse and leaking them. The article mentions encryption but is light on details so it’s anyone’s guess how secure it will really be.
If you need access on a new device, just set up a passkey on the new device. And possibly delete the one on the old device if that’s desired.
But that becomes a moot point when every service provides access via email with easily-stealable magic links or 6-digit codes.
True, but you have to give the user access to their account some other way otherwise how will they get in to make a passkey in the first place 🤷♂️
At least with links and codes you can caution users against giving them to any other party.
We’re going in circles. Passkeys are already synced between e.g Apple devices for people in the Apple ecosystem. Apple may be missing the point of passkeys in your opinion, but the result of not being able to export them is that transferring passkeys between Apple devices is easy, while transferring them to non-Apple devices is impossible.
Syncing within the Apple ecosystem is an easy problem because Apple can exhaustively enumerate the set of hardware roots of trust that will enforce the required security properties and permit key exchange only with them. This is a much harder problem when arbitrary other RoTs are involved.
1password too, ofc.
Which works cross-platform. I assume Bitwarden will get there too, if they are not already there.
You have repeated your previous comment word for word, I understood you the first time and tried to explain why your premise is incorrect (in my opinion) 🤷♂️
I repeated my previous comment word for word because it applies just as well to your response as it does to your initial comment. In other words, circles.
In general, I would recommend against repeating your comments verbatim in discussions, because it makes it look like you think the other person is an idiot who needs to be told the exact same thing over and over again. Please keep in mind that people who don’t agree with you about something are not idiots, and may have valid arguments and reasoning that you just don’t understand 🤷♂️
No, the point of passkeys is not that they’re in a TPM. The point of passkeys is to replace symmetric shared-secret auth with asymmetric auth.
Whether passkeys are stored in a TPM is an implementation detail. I use 1password which doesn’t use a TPM (but also works on every single one of my devices, which is worth much more than storing keys in a TPM.)
That’s the point for power users like you who use password managers. For ordinary people who don’t, one of the huge benefits of passkeys is that their secret keys are unreachable and so can’t be extracted through trickery.
For someone like you who uses a password manager to store your passkeys, a specification for exporting passkeys is a moot point, it doesn’t impact you either way.
I think that the increase in security that passkeys provide is large enough even without HSM backed private keys. For one you can do that still if you care about that threat model, but I’d argue for most people that trade off isn’t worth it, which is why we see these platforms focusing on sync. I have well over 300 items in my password manager, and while I have been going through and making 2 passkeys where I can, it is quite a pain. I also think the export spec isn’t just a plaintext export of the private keys, theres more too it to that to keep folks from getting tricked into exporting them.
Do you need immediate access to all of the 300 items? No? Then why make all the passkeys for them up front? Just make a passkey on an as-needed basis, when you actually log in to that service?
But this seems to rely on every site that uses passkeys implementing them correctly… whereas I’ve seen several cases where they use passkeys essentially like a password alternative: you get exactly one per account. So now you’re stuck and either need to share the passkey, only ever use that account from one device, or still need a password manager to provide a fallback option.
Yes, it’s possible that some sites don’t implement passkeys correctly. Should we really be papering over their deficiencies, or should we accept that they aren’t going to support passkeys properly and move on?
Without a password manager, how do you do this? I have a number of passkeys saved to my 1password, but without some other form of auth there is no way I could add a new passkey for a new device other than via a usb security key or a password manager with passkey support that lets me bring the passkey to a new machine so I can authenticate and initiate the process of creating a new passkey for that device (but why would I once I have the ability to log in?)
The same way you created the first passkey? Log in to the account with an account recovery method like ‘log in with email’, then create a new passkey once logged in.
There is if the app is implemented correctly and lets you create new passkeys once you log in and go to the security/auth settings. Eg, https://github.com/settings/security#passkeys
Because you might need to do it on a new device where you don’t already have a passkey.
ah, I’m used to dealing with the regime of “once you have a security key, you need that security key 100% of the time i.e. to add an additional security key” that is imposed by my employer
That’s how we do it too, whenever I have a say. They break, lose, forget their MFA sometimes, we require an on-site tech to verify their identity before the tech can delete the MFA and let them login and set it up again. The benefit of having 99.9% of staff on our own campuses and dedicated IT at each one.
Greetings!
We are excited to announce pipe: our managed pubsub service over ssh.
We are at a point where we would love to get feedback on the service to see if it resonates with the lobsters crowd. All you need to use
pipe
is a pico account which can be created using ssh:ssh pico.sh
We’ve been using it internally for a few weeks now and keep coming up with new use cases. For example, we are using
pipe
to create a log drain for all of our services and even a way to share logs with users. You can read more about it on our blog post: https://blog.pico.sh/pubsubForgot to update the spiel for Lobste.rs?
updated thanks!
Looks cool - where is the source for self hosting?
It’s always great when a managed option is provided but the usecase I have in mind where ssh would be a boon is data I don’t want to share with a 3rd party. It would be amazing if this was an option!
So we have a stripped down, “works with authenticated_keys” version here: https://github.com/picosh/pubsub/blob/main/cmd/example/main.go
The “production” entry point is here: https://github.com/picosh/pico/blob/main/pubsub/ssh.go
I agree with the sentiment, but I disagree with some of the advice.
IMO the ideal use (and implementation) of htmx would be essentially limited to automatically having the effects of
hx-boost="true"
on forms, and having it handle a regularLocation
response header the way it handlesHX-Redirect
.As the post says:
This is exactly why the ‘boost’ concept is good (where it’s appropriate). It’s insanity to me that if you want a form which also works without htmx (or without JS) the “recommended” way to use htmx is to duplicate the target url and request method everywhere.
Maybe we just need a cut down version called
html.js
.I agree that would be ideal, but the note you’re referencing also describes why it’s not possible. JavaScript cannot intercept the location header when the response code is a 302/303—the browser will either automatically follow all the redirects (
follow
mode) or not do that but hide the location header (manual
mode). So until proper method support is available in HTML, there’s no situation where a JS polyfill can automatically upgrade the forms in a way that would be forwards compatible with native browser functionality.Can’t you use
Response.redirected
andResponse.url
from a fetch? I built my own little htmx-esque thing a while back and did that to make the form submissions work both with & without javascript enabled (I have comment in the code about it not working in Safari, but not sure if that’s still the case).I didn’t know about that, I’ll look into it! It sounds like best case-scenario that would result in calling the final route twice though—once to finish the redirect chain and once when you direct the browser to navigate there. That could be an acceptable compromise but it is bit annoying.
Another (also less than ideal) option is to use XHR - without waiting for
readystate
to beXMLHttpRequest.DONE
, if theresponseURL
property is set, and isn’t the same thing you requested, you can abort the request and then use the new URL for a client side redirect.Along with this: don’t use booleans as “flags” in your database. Use some sort of timestamp instead. Now you know when it was set, which you’ll suddenly find useful down the line.
Dates make a lot of sense for things where a date is relevant to the actual thing - a publish date, a modification date, a “sale starts”/ “sale ends” field.
The fields where I’m using a boolean in a database, I want to be able to express two, or possibly three actual states (a nullable boolean): “on; off” or “on; off; no preference aka inherit default”.
A date gives you at best “yes, as of/until ; no or maybe inherit default”
If you want to know when some value changed, you want an audit log, which is more useful for auditing anyway because it isn’t limited to storing a the last time it was changed, and it can store who changed it, what else was changed at the same time, etc.
GP meant mutable state hacky flags. Not immutable boolean properties of conceptual relational entity.
If you have a boolean column and go around changing the value, you are very likely doing it wrong. Model your changes instead.
Check Rick Hickey take on how state is handled in clojure for a straight forward explanation of state vs data.
Checked around but got some ambiguous results - could you share the specific take by Rick Hickey?
https://clojure.org/about/state
It’s less detailed than I remember, but does make a good job setting values and state apart.
probably this one: https://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey/
When you do this you use
null
as default andtimestamp
asset to not-default at timestamp
or? If someone turns off a setting after turning it on you just set it back tonull
?Good question, I guess it depends on what you’re using as a “flag” here, but I guess I should have specified for things you’re unlikely to toggle back. I guess once again, a kind of “status”, except not a linear status but various conditions. First one that comes to mind is a “soft delete” or an “archive”.
Use 5th or 6th normal form and eliminate
null
altogether.https://dave.autonoma.ca/blog/2019/06/06/web-of-knowledge/
Why is it that every article attempting to explain how
null
is some unspeakable horror, includes a tale about some application somewhere comparing to the string'null'
and ensuing chaos.You might as well say “don’t use Boolean, someone might compare it with string
'false'
.Dereferencing a boolean (or any other properly initialized value) won’t cause a program to crash. And comparing a boolean to a string will result in a compile-time error. I’m guessing you already know that and are trolling at this point.
https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/
Funny story. I was working at a company that was building a high-visibility student transcript system. During a code review, I saw that someone had hard-coded a default value for the last name of a student to the literal string “null”. I brought this to the attention of another developer stating that if a student actually had the last name of Null, they wouldn’t be able to use the system. He went away came back a half hour later and said, “You’re right, that’s a bug.”
That would not have been a fun bug to track down; Hoare strikes again.
https://www.wired.com/2015/11/null/
Another issue, of course, is that a
null
sentinel allows comparing two different classes of objects to the same value. (It explicitly excludes the sentinel value from the set of values that are valid elements.)There are many, many reasons to make software both immutable and null-hostile, which is why the industry is slowly moving in that direction.
https://github.com/google/guava/wiki/UsingAndAvoidingNullExplained
You haven’t answered the actual question. Why are people hardcoding a string literal
'null'
when comparing to an actualnull
?Also, for the record - comparing a string to a boolean is a perfectly valid operation in any number of languages. It will equate to false if you’re doing things properly. I’m guessing you already knew that and are trolling at this point.
Yes, that is a bug, because they’re treating a literal null and the string null as the same thing. If your language, or database doesn’t distinguish between
null
and'null'
, pick a better language/database before you start telling everyone else on the planet that they shouldn’t use literalnull
, because someone somewhere is stupid enough to compare it with a string'null'
.As long as you have sane auditing you can always go look. In your version you know what and when. With sane auditing you get all the W’s, well perhaps not they why, unless you go ask the who ;)
so i stead of
is_active
beingtrue | false
its eithernull
(for “false”/unset) or a timestamp? am i understanding you right?It sounds like what they’re suggesting is instead of having
is_active
, you’d haveactivated_at
with a timestamp instead, where it’snull | timestamp
,null
being not activated.Which is quite the opposite of the advice given in the featured article.
PHP makes breaking changes between minor versions (when activating all errors), which is certainly great to keep developers working, but a major PITA.
After 10 years of PHP, I value the Go 1.0 compatibility promise very much…
Java is still the de facto king of backwards compatibility that actually has the years to show for it. Just based on the title, that ‘title’ would go to Java in my opinion.
Until you try out the nightmare that is upgrading the maven, ant or gradle dependencies of an old project, then sure.
I would argue that it is at most as bad as with any other language, but arguably better as the ecosystem is significantly more stable than any other. (What is in the same ballpark in size are JS, and Python, neither is famous for their stability).
But of course third-party libs may decide to break their public APIs at any point, that’s irrelevant to language choice, besides “culture” — and Java’s is definitely not “going fast and breaking stuff”.
Sadly, starting with Java 9, while the core language is backwards compatible, the library situation is a nightmare. And when you’re doing an upgrade, you don’t care if it’s the core language or the library that’s changed, either way, it’s work to upgrade and ensure you don’t have regressions.
Lots of things have changed the package that they live in. In principle, this sounds like it’s not a very difficult change to accomodate, just find and replace, but it wreaks havoc when you have libraries that have to run on multiple JVM versions.
If you’re unlucky enough to be using Spring, it’s even worse. That framework has no concept of backwards compatibility, and is like a virus that spreads throughout your entire codebase.
I can’t share your experience at all. Even large jumps pre-8 to post-11 (though after like 11 they are basically trivial) are reasonably easy, and the few libraries that made use of JVM internals that got increasingly locked down (to prevent further breaking changes in the future) have largely been updated to a post-module version, so very often it’s just bumping the version numbers.
I don’t understand some of what you’re describing.
Are you saying that other languages can somehow prevent the problem of third-party libraries breaking backwards compatibility? Because, if you aren’t saying that, then the core language being stable is going to make the situation objectively better to deal with than if you have to worry about breaking changes in libraries and in the core language…
Yes, it can be tricky to write code to target multiple versions of Java at the same time, but in my experience, it’s about 100 times less tricky to do this with Java than almost any other language. JavaScript might be the only one that’s even better about running old code on newer runtimes without much problem. Are there others you consider better than Java at this? Specifically for running the SAME code on multiple versions of the language? I remember back in the day when I worked on a lot of C++, it was a nightmare to figure out what features I could use from C++11 to allow the project to build on various versions of GCC that shipped with different Linux distros (Ugh, RedHat’s ancient versions!).
I think that depending on the community, some languages have less BC issues because of libraries than others. Case in point for me was Clojure: both the core language and community have a stance of avoiding breaking compatibility, even if the language itself doesn’t offer any special mechanism for that. Quite the opposite actually, since the language is really dynamic and you can even access private functions without much difficulty.
Of course they can’t, and that’s not my point.
My point is that communities develop norms, and those norms include more or less careful treatment of backwards compatibility in libraries. My sense is that Haskell and JavaScript are probably the worst. Java is actually mixed, as there are a lot of libraries that do great work. Some even have a single version that runs on Java 5 through Java 21. But at my day job, we’re using Spring, and the situation is bad.
Though with regard to languages, I will say dynamic class-loading can make the situation worse. I’ve dealt with issues where the order of requests to a web server determined which version of a service provider was loaded. So 9 times out of 10, the code ran on the newer version of Java, but failed 1 time in 10.
It sounds like your argument is “having two problems is worse than having one”. But two little problems are better than one big problem.
I greatly appreciate the backwards compatibility of the Java language. But I would be happier with a slightly less backwards compatible core language, if I could trade it for an ecosystem that’s much better at backwards compatibility.
Right. I understand and agree about ecosystem “culture”. But, at the end of the day, someone said Java was good with backwards compatibility because it makes it easy to write code that will continue to work “forever”.
I guess maybe your point is that the language prioritizing backwards compatibility is only necessary, but not sufficient, for developers actually getting to experience the benefit of the backwards compatibility. Would you say that’s a decent interpretation/restating? I do agree with that. And if the language itself doesn’t care about backwards compatibility, then it’s impossible for the ecosystem to have stability.
Definitely true! Luckily, I only remember one time where I had a nightmare of a time figuring out some class or service loading bug.
Yeah, that’s exactly what I was saying. But there’s no reason to think the “one problem” (community doesn’t value backwards compat.) would be bigger or smaller for either case. So, it’s like comparing x to x + 1.
I really feel like this is mostly just Spring. I hate Spring, too, so I have been fortunate enough to not have to use it in several years now. But, as for the Java libraries I am using, I honestly couldn’t tell you about their JVM version compatibility over time. But, just judging by API stability, it seems that most “general purpose” or “utility” style libraries stay pretty backward compatible (thinking of the Apache and Guava libs, etc). It’s mostly the frameworky ones (like Spring, Spark, etc) that like to rewrite big chunks of their APIs all the time.
Happy to agree with your last paragraph. It’s very close to what I think.
Hey, have you heard of Perl?
Can you give an example of what you’re referring to?
I’m semi-active on the PHP internals mailing list (i.e. the list where development of php itself is discussed) and BC breaks are a near constant discussion point with any proposed change, so I’m kind of curious what breaking change you’re referring to here?
PHP maintains change logs for every minor version. Here’s the most recent list for migrating from version 8.2 to 8.3 (a minor version bump): https://www.php.net/manual/en/migration83.incompatible.php
Yes, I’m aware of the migration lists. I was asking to try and get an example of a real world issue that’s likely to affect users.
In that migration list specifically, the vast majority of the “breaks” are fixing inconsistencies.
Yes they are technically a BC break. But part of the discussion on each RFC for PHP is the expected real-world impact if there is a BC break.
Well, since I’m not the person you originally asked, I obviously can’t speculate on which breaking changes they’ve actually bumped into. But, I’ve works on several long-lived PHP projects going all the way back to version 5.3 and all the way up to 8.1 or 8.2 (I don’t quite remember which), and I’ve definitely had to fix broken code from minor version bumps. Luckily, we do have those migration lists, so I learned pretty early on to read them carefully and grep through any code base to fix things on the list before even running unit tests.
But, I’m not sure what the point is. The person said that PHP introduces breaking changes in minor version bumps, and that it frustrates them. Maybe they’re misguided for being frustrated by that, but it’s objectively true.
Personally, I’m perfectly fine with breaking bug fixes in minor versions. It’s not like you’re going to accidentally or unknowingly version bump the programming language of your projects. On the other hand, many of these changes are NOT bug fixes, but just general “improvements”, like the
range()
changes or the “static properties in traits” change in the 8.3 list. I can see how this would be frustrating for someone who wants the bug fix changes, but doesn’t want to pay the extra “tax” of dealing with the non-essential breaking changes.But, again, I personally don’t care. I treat PHP minor versions as a big deal. PHP 8.2 is not the same language as PHP 8.1, which is fine. But, if you care about backwards compatibility and painless upgrades, Java is pretty much the king.
It’s mostly the ripple effects into libraries and “big” frameworks. For instance, I remember a few years ago a client was on still on PHP 5.3 (I think) and his hosting provider was about to shut down this version, so he had to get his site working on newer versions. This site was built on an in-house CMS of questionable code quality, using CakePHP.
The problem I ran into was that I had to step-by-step upgrade CakePHP through some major versions because the older versions wouldn’t run in the newer PHP due to BC breakage. Eventually, I completely hit a wall when I got to one major version where I discovered in the changelog that they completely rewrote their ORM. Because of the shitty code quality of the CMS (with no tests), I had to admit defeat. The client ended up having to commission the building of a new site.
Java and Go are really great in this regard. Every other language, including Python (which makes breaking changes from 3.12.3 -> 3.12.4!) is horrible on that front.
I think this is just an extension of the buzzword-itis our industry seems to be forever saddled with.
I don’t actually recall the last time I saw anyone use the term “devops” the way it was originally intended (i.e. infrastructure as code, using generally-accepted development practices to approach operations, etc) - it’s essentially been coopted (I think largely by HR/management types) to mean “we want our developers to understand enough Bash and AWS console to make something kinda work”.
The dangerous part to me, with the definition of SRE in the article (ops who also creates new programs) is that you’re relying on the speaker’s intention to distinguish what you mean, from the plethora of “full stack code ninja” that will happily claim to be “expert” across domains from <insert graphics editor of your choice> all the way to server-side kernel hacking, and generally ends up being a jack of all trades, master of none.
I’m not saying it’s impossible for a single person to be very good at all the things that covers. I’m just saying that it’s statistically unlikely that most who say they are experts across that whole range, actually are.
I’m not saying people can’t be good at more than one thing. I wouldn’t use the term SRE myself but most of my work falls roughly into the description the author uses. But the moment you try to codify (only a small pun intended) some idea of complimentary tech skills behind a term, it’s almost guaranteed to get used and abused to the point of being meaningless.
I’m also not saying there isn’t a place for a jack-of-all-trades types. But as your team size increases, the appeal of that skillset rapidly decreases IMO. Having 10 people who have shallow knowledge of everything is nowhere near as useful or productive as 6 really great backend-focused developers, a UI/FE dev, a sysadmin, a tester and one jack-of-all-trades.
It’s helpful to have some people who can step into a number of roles to help out. It’s not helpful to be completely reliant on people with shallow-to-medium depth knowledge/experience of everything.
This is a fascinating perspective because it’s about an emergent property of SREs rather than a definitional property. SREs never had to generalize to full-stack development, but were forced to do it as the job market went sideways over the past decade.
To me, SRE is fundamentally about systems administration without developers. A common test of this is that an SRE team should be able to classify its owned components into three bins: those actively developed by another team, those developed by SREs in collaboration with support from other teams, and those developed solely by the SREs themselves. Crucially, an SRE organization isn’t healthy unless any component in the first bin can be disowned by the organization and returned back to its active developer team. This is a systems-first way of computing; the stability of the system is more important than the ability of developers to mutate it.
Please forgive me for the “devops” tag. I felt this so much, and it’s extremely annoying to see in the wild. Heck, my own company has a separate “SRE/Ops” team that just does ops. They pride themselves in the fact that they don’t write code and they “hack stuff together with bash”. While I sit across the hallway doing actual SRE work in the Kubernetes team.
As annoying as it is to see technical terms lose their meaning, I’m sure those people don’t deserve to be called monkeys. It’s OK to be content with doing only ops.
Yes, you’re right. I kinda just borrowed the term from the article, but yes, nobody deserves to be called monkeys for their work. I’ll edit that out.
I don’t know the author or GP commenter, but I’ve always seen the “$x monkey” term as “someone is happy doing $x in their role and isn’t concerned with outside issues” - e.g. in Jonathon Coulton’s Code Monkey: https://www.youtube.com/watch?v=v4Wy7gRGgeA
I don’t think there’s necessarily a negative connotation associated - but as I said I don’t know the author of the article, and their reference does seem to be less enthralled by someone who has chosen/is happy to specialise in ops (aka what we used to call sysadmin) so maybe my read is wrong and it was meant to be disparaging?
The titular developer in Coulton’s song is anything but happy…
I think you’ve misunderstood what I was saying.
I’m not saying “doing $x makes the person happy regardless of other factors” I’m saying that $x is what they are happy to (read: want to) focus on in their work.
But he hates his job too. Anyway, it’s possible your meaning is the generally accepted one, just that using the song as an example isn’t backing it up.
I don’t think I can agree with that assessment, I think what you’re attributing to “hating his job” is more like frustration at not being appreciated for what he does.
This is what Jonathon said when he first released the song:
https://www.jonathancoulton.com/2006/04/14/thing-a-week-29-code-monkey/
I mean, I think it’s pretty clear from the lyrics that he hates his job - he pretty much straight-up says that he’s only there because of the receptionist (I think?) he’s in love with, and who seems to be uninterested in him. “Code Monkey have every reason to get out this place […] This job fulfilling in creative way - what a load of crap.”
But perhaps he does love coding - his horrible job aside.
(This is something I reflected a bit about in a particularly soul-crushing job, three jobs ago: I loved coding, but at that point I felt like I hated having it be my job.)
I am perfectly happy describing a job as “Rack monkey.”
And then you can describe a person by their job. “Administrator” “Devops guy” “Dev.” But everybody of course needs to understand that a person’s job does not define a person, and every job needs to be filled by somebody.
Some of these jobs of course are lower paid, partly because the gap between a competent professional and inexperienced intern can be just a few weeks of training.
Nobody is being called a monkey. When the post says “people who basically were ops monkeys.” that describes people’s preferred job, not the person.
I’m not really a python guy (I’ve made a few small patches here and there to upstream projects to scratch specific itches, nothing more) but I feel like if you’re already using a virtual env, you’re solving most of the problem containerisation solves anyway.
So, my question would not be “why are you using venv inside Docker?” my question would be “why are you using Docker?”
If you’re building web apps – which is a major use case for Python – it is virtually certain these days that your deployable artifact is a Docker container. That’s just how infrastructure works nowadays. So learning how to do things well in a Docker deployment scenario is kinda important.
Virtually certain?
I know Docker gets cargo-culted like crazy but I don’t think it’s even close to realistic to say it’s “virtually certain”.
I don’t know what to tell you, Docker and Kubernetes ate the world. Tooling these days is entirely optimized around the assumption you’re doing one or both, and even things that don’t necessarily look like they’re Docker/k8s often are under the hood.
I guess we live in different worlds.
I’m certainly glad mine isn’t the same as yours, given how you describe it.
Edit for clarify: I’m not nit picking about whether people use Docker specifically as the container runtime, and to be clear when I say “different worlds” I don’t mean “web apps” vs other software development.
I’m saying that while containers are a popular deployment target for server side web apps, they aren’t the only solution used in 2024.
The last time I worked someplace where Docker/k8s (as a stand-in generic term for “some type of OCI containerization and associated orchestration system”) wasn’t the way you deployed stuff was… nearly ten years ago, now, I think?
Even places that didn’t use literal explicit
Dockerfile
or whatever often deployed on things like Heroku or other CNB platforms (which are, surprise surprise, containers under the hood, just with a different way of writing the manifest for how to build them).Yes, I understand what you are saying, and that is why I said “I guess we live in different worlds.”.
To put it another, more explicit way: my experience does not match yours.
Amazon’s EC2 business would like to have a word (some of it is just ECS workers). Hashicorp Nomad would like to have a word too, as would every vendor that ships Debian packaging upstream (Grafana, Redis, Elasticsearch, Microsoft SQL Server, etc. etc.).
“Plays nicely with” is very different from “entirely optimized around the assumption you’re doing”.
At $work we deploy our webapp with golden AMIs built by Packer.
We should maybe stop always saying “Docker container” in this kind of general context though since these days I wouldn’t bet Docker is the actual runtime of most containers out there.
I feel like as a genericized term it works better than “OCI-compatible containerization system”. Even people who are explicitly not using Docker to build their containers would probably still understand that “Docker” doesn’t mean “literally only the exact command-line tool named
docker
”.Feel free to feel that but I’d in those context for example say “container runtime”, if that’s what I mean. Or I might say “OCI runtime” if in the context it needs to be clear I don’t include Flatpak/bubblewrap/Snap/whatever.