6 ms·
Go modules and the domain expiry problem
- denton-scratch 3y agoForgive me, but I don't get what the issue is. Surely the "ownership" of the domain is irrelevant? The package-name is just a unique name; the only thing it refers to is the package. In particular, I don't see any reason why the package-name needs to be related to the mailing-list/bugtracker, or to the location of the canonical code repository. XML uses URLs as labels for namespaces; they are just labels. Nobody expects to find a document about the namespace, nor a schema, at the namespace URL. There's never a need to resolve a namespace URL. Why should it be necessary to resolve a Go package URL? [Edit] I honestly don't know, because I've never used in Go.
- moqmar 3y agoGo uses the package name to retrieve the pagacke source - a package named github.com/example/whatever will be downloaded by basically cloning it with git & then checking out the specified version as a tag. That's in itself a really simple system and doesn't rely on a single third party, but obviously comes with the ownership issue (unless when pinning a specific commit) - in my opinion a good compromise.
- Rygian 3y agoThere is a requirement to ensure all packages using the url-as-label are legitimate.
- opaulo 3y agoA Uniform Resource Locator (URL, RFC1738) is a name for localization and access of resources via the Internet. A Uniform Resource Name (URN, RFC8141 & RFC3986) is a name that identifies an abstract or physical resource. Your argument just favors distorting the concept of URL to use URL as URN. But if we were going to use URLs to identify abstract resources, why don't we use URNs instead?
- usrbinbash 3y ago> The package-name is just a unique name; the only thing it refers to is the package. Not quite. In go, you import 3rd party packages via a URL where a VCS can find them, eg.: import "github.com/gorilla/websocket" The package name is thus both, an unique name for the package AND a location where the toolchain can find and fetch it.
- denton-scratch 3y agoI see, thanks. Well, that's the problem, I guess. Someone famous once said "Good URLs don't change". Turns out he was pissing in the wind; nobody paid attention. And the market in DNS names guaranteed he'd be wrong.
- j1elo 3y agoThe linked post (toot?) from Tony Arcieri says this when talking about the matter of avoiding namespace squatting in Cargo: > (In Rust) there will be namespaces soon anyway, just not the kind that would require a huge paid manual review/support staff to administer everything Is he talking about Maven Central? Because using DNS prefixed packages as a means to avoid namesquatting seems to me like the best solution out there. For all its faults, Maven got a lot of package-management things right, and I'd argue DNS prefixes is one of them. I wish that solution wasn't handwaved so quickly. You just make an account at Maven Central, prove ownership of your domain name, and can then start publishing packages with your publisher credentials. If you suddenly lose your DNS name (as in the case of .ga), you'll still be able to publish packages for a while, at least until there is a new ownership verification, giving you ample time to publish new versions with deprecation warnings. But, of course, that requires people on top of the registration system, approving requests, attending issues. Claiming that the need for such staff is something to avoid, sounds to me akin to if we were in the 90s thinking how to distribute software packages in our Linux distro, and someone said the need for package maintainers would be something to avoid.
- raggi 3y agoIt's worth noting that the proxy and pinning behavior actually help with scope a fair bit. The threat is still there for new versions, but both visibility and external controls can still help.
- rollcat 3y agoI wish GOPROXY was a little more... obvious? The way it's working feels like it's trying to hide something, for whatever reason. For a long time I did not even realize that all of my Go package installations were going through Google-controlled infrastructure by default; something I'd object to had I known sooner. The cache also tends to serve the last working release, rather than the one that's actually the latest, so you sometimes don't even realize that the tip is broken. I can forgive most things, but not hiding errors, especially as I bash my head against the keyboard. On top of that, proxy.golang.org has historically not been playing nice with upstream repository servers[1]. I tend to keep GOPROXY=direct in my environment for these reasons. [1]: https://sourcehut.org/blog/2023-01-09-gomodulemirror/ https://sourcehut.org/blog/2023-01-09-gomodulemirror/
- l2dy 3y ago> And the Go module proxy will probably keep the old versions available. https://proxy.golang.org https://proxy.golang.org does not save all modules forever. See FAQ on the site.
- irrevboyyyy 3y agoYou’re technically correct, which I imagine is what you were going for, but the reasoning in the FAQ is largely irrelevant to the matter at hand.
- mirekrusin 3y agoCouldn't issue be solved by using ipfs?
- rollcat 3y agoShould IPFS support be built into the Go toolchain? Should the package authors be expected to be running an IPFS node? Should Google operate the infrastructure to access IPFS? This is an interesting proposition but it opens quite a few followup questions.
- hamdouni 3y agoI know it is not always possible but forking the repos helps mitigate the issue of original repo being "compromised". It also helps reproducible builds...
- janosdebugs 3y agoYou don't need to do that with Go, go.sum stores the checksums and you can use go mod vendor to download the dependencies to your own repo.
- hamdouni 3y agoThat is not the point. If I newly checkout my Go project and build it, it will use my forked repos instead of the orginal ones. If someone use my project, it will also use my forked repos, so it makes the builds more reproducible. That way, I'm not pushing the dependencies in my project.
- DaiPlusPlus 3y agoBut then you end up with a 50GB+ npm /node_modules/-type situation. No thanks.
- hamdouni 3y agoSorry, I don't understand. My proposition is only to change 'origibal/dependency' to 'myfork/dependency'.
- hamdouni 3y agoBy forking the dependencies, I meant having a copy of them in my namespace, not cloning them in my project...
- Kamq 3y agoSomeone help me here, but doesn't every package manager have this problem? If control of crates.io or npmjs.org change, how many rust/js projects will still build? The trade-off seems to be between distributed vs centralized. Where in the distributed case, you take on more risk that something will break for a lower chance that everything will break. And in the centralized case you have a lower chance that something will break, but if anything does, you're completely SoL. Now, I think there's a conversation to be had on that trade-off, but it doesn't feel like the article really covers it. Centralization has some really nice day to day benefits, but it's not exactly a trade-off with zero downside.
- lexicality 3y agocrates.io and npmjs.org don't rely on individuals maintaining a paid subscription for the packages to continue to exist. If my package is at example.org/pkg/mypkg and I stop paying for my domain name for any number of reasons then that package is essentially lost.
- Kamq 3y agoNeither does github. Any package at github.com/user/package (which is a lot of them) has this property. With the bonus that if github does go down, you can redirect it to another mirror of the package if the maintainer puts one up (or you can vendor early, but that's an option for everything).
- lexicality 3y agoThe article isn't talking about GitHub though. It's talking about people who self host packages on their own domain.
- Kamq 3y agoIt's talking about domains going down in general as far as I can tell. People with their own domain are just much more likely for it to happen. It seems you have two specific options. Centralize on a big company's url, which you can use in go via sticking to github.com (and a couple other domains) packages as well as js/rust/java/etc. Decentralize it and have to worry about constant low-level package rot, but not be able to have any individual domain take out all of your dependencies, which you can only really do in go (or languages like C where git submodules are a fairly standard form of dependency management). There is a tradeoff of having a single point of failure in the first example in exchange for increased reliability during normal operations, and in the second example, you're much more likely to be hit by package rot, but you're significantly less vulnerable to your entire dependency tree being wiped out. This is the tradeoff I'm talking about.
- skywhopper 3y agoIt’s good to think through the risks here for your own use case, but ultimately, as the article points out, there’s no way to entirely avoid the problem for Go or any other language. So you just have to figure out how to best manage your own risks for your own required level of assurance. Luckily the go ecosystem has a number of tools for dealing with this. You can set up a local trusted proxy of all the code you use internally and point your builds to that instead of Google’s default proxy or just doing direct pulls. Or you can vendor the code you’re using into your own repository. You can also easily alias specific libraries to point elsewhere if specific ones are problematic, without having to change the code directly.
- physicsguy 3y agoThe expiry problem is not much different to if someone deletes the package, so I’m not so concerned about that, but my main pain point is that if you’re developing Go code and your company decides to move Git provider (had this happen multiple times as companies grow, get acquired, etc) then you either have a mess of “replace” all over go.mod, or you have to point everything to a new location. It’s particularly annoying if you want to check out and build an older version of your code, because the changes to go.mod have to be cherry-picked, and by that time you’ve probably updated your dependency’s versions.
- riobard 3y agoFillipo said here (https://abyssdomain.expert/@filippo/111393097818470743 https://abyssdomain.expert/@filippo/111393097818470743) > It is IMHO the strongest security guarantee you can offer without forcing each module author to manage keys. Outsourcing the problem to DNS still forces module authors to manage keys. Not keys to sign code, but keys to sign TLS certs nonetheless. Granted, authors can further delegate managing TLS keys to other people, but you cannot escape the ultimate issue of managing control of the domain (passwords at registries at least). If we cannot get rid of key management anyway, can we split the problem into 1) Code Signing and 2) Code Distribution? Once we get the Code Signing done right, Code Distribution will be much easier with robust solutions (e.g. content addressable storage and various kinds of proxies/caches for high availability). Now code signing, lots of schools of thoughts… On the extreme end of decentralization, PGP/GPG people will say Web of Trust and Crypto/web3 people will say hardware wallets; while on the other end of centralization we seem to be getting by just fine with publishing public keys on GitHub and various social networks. Just pick a place where you Feel Good Enough™ :p
- withinboredom 3y agoCode signing certs expire though. So you basically limit any code's usefulness to some arbitrary date. Then you need to maintain that code cert, continue to pay for it, renew it, etc, which you can realistically only do until you get hit by a bus, die of old age, or just fall on hard times. This is a worse (very real) problem vs. some domain thing that probably won't ever happen for the majority of modules.
- Bognar 3y agoProvenance artifacts via something like SigStore would go a long way, since it solves both key management and the linking of artifacts to their build process. For Go where you're just publishing sources with a build necessarily, you could opt for SigStore git signing so you can at least validate the author via a 2FA auth provider's OIDC token.
- rob74 3y agoThis is a largely academic discussion - I assume over 95% of modules are hosted on some kind of "forge" (mostly GitHub nowadays), so the users don't have to worry about keys/certificates, just about the forge's continued existence and their account not being removed. Any attempt to switch to code signing would raise the barriers of contributing to the Go ecosystem quite a bit, so (if at all) it should be introduced as an alternative or supplement to the existing system, not a replacement.
- janosdebugs 3y agoI have a lot of bad things to say about Gos module system, but this ain't one of them. With this system you don't need an account somewhere to publish a package and you still get to use GitHub, Gitlab, etc. without your module URL being dependent on them. If you consider alternative systems with accounts, if you loose access to the underlying email, you may be out of luck, too. Or in the case of Rust/crates.io, if you delete/switch your Github account you can't log in anymore either.
- cookiengineer 3y agoWhat I like about the go.mod file is that it easily allows to remap go modules to local path folders. This way I can have a backup of the dependencies wherever I want, even when not using "go mod vendor" (which I like also a lot tbh). So I don't understand the critic in the article, you cannot solve this problem efficiently other than putting everything on a blockchain, which will waste a lot of hard drive space.
- IshKebab 3y agoI'm curious what bad things you have to say about it. I haven't actually used it but my impression from reading the design docs was that it's the best module design so far. Better than Rust for example.
- janosdebugs 3y agoMy main gripe with it is the missing separation between test and prod dependencies. Let's say you work on program A, which depends on library B. Library B uses library C as a test dependency. It shouldn't have any effect on A whatsoever and should not even be downloaded. Yet it is. Apart from the obvious bandwidth and storage space wasted, this is also a problem when compiling an SBOM (Software Bill of Materials) and when scanning for vulnerable dependencies. There is simply no way to tell if your Go binary is vulnerable simply by looking at the go.mod/go.sum file, you have to build and analyze the binary and hope that everything went well. Same for compiling NOTICE files for license compliance. (wink wink Apache license) This isn't an unknown or unsolved problem either, Maven solved this ages ago. There are also some minor nitpicks, such as their absolute requirement to do path-based semantic versioning from v2, but not from v1 or v0. If you change anything, but absolutely anything that's publicly visible, you must increase the minor version of the library you are publishing or you will have a really bad time. If you want to publish both a library and an application, you have to either version them with ridiculous version numbers, or you have to split the two.
- skybrian 3y agoMost of the time this will be a Github or Gitlab URL. (Or similar.) Then domain name expiration isn’t a problem, but you do need to protect your account. Using a personal domain name should probably be discouraged unless you’re sure you know what you’re doing, and even organizations might want to think hard about whether they’re really want to maintain a website indefinitely.
- janosdebugs 3y agoOne could argue that if the personal website goes away, you should be taking a hard look at that dependency anyway as it may have become unmaintained. Also, you can use vendoring if this is a concern.
- ncjcuccy6 3y agoDid the article somehow suggest GitHub.com might expire?
- janosdebugs 3y agoNo, the article suggested that when hosting a Go package on your private domain that domain might expire. However, most Go packages are published as the module name being github.com/author/packagename, in which case domain expiry is not a problem, but you need to keep a hold of the account.
- skywhopper 3y agoThe risk with GitHub is more likely that the source account of the library would be removed for any of a hundred reasons.
- mort96 3y agoI was once unable to build some Go software because some random individual's personal git hosting website was down. It's sadly not only gitlab or gitlab; at least that would've limited the amount of single points of failure.
- 3y ago
- IshKebab 3y agoThere's a reason tou need namespaces even without name squatting considerations. At least for some package systems like pip. If you are using a private registry you want to prevent dependency confusion attacks. I guess Go sidesteps this by not having a registry, and Rust seems to require you to explicitly say which registry a package comes from. But pip is vulnerable to this issue because it still doesn't have namespaces.