From: Stefan Sperling Subject: Re: Hierarchical repositories in gotsysd and gotwebd To: Anton Kasimov Cc: gameoftrees@openbsd.org Date: Wed, 14 Oct 2026 10:45:44 +0200 On Mon, Oct 12, 2026 at 11:42:07PM +0200, Anton Kasimov wrote: > Hi, > > I'd like to propose support for hierarchical repository layouts in gotsysd > and gotwebd, similar to what gotd already allows. > > This could provide a concept similar to GitHub organizations, but with > arbitrary nesting levels: > - project/repository > - team/project/repository Hi Anton, This is indeed something which has been requested before. I agree that it would be nice if gotwebd supported repositories inside subdirectories of its repository path (e.g. "/git"), such that we can display not only repositories which are at /git/foo.git but also at /git/subdir/foo.git. What I am not so sure about is whether the hierarchy should be virtual (defined only via configuration file syntax), or should mirror the actual on-disk directory hierarchy. I haven't yet settled on an approach I am 100% confident with. So far, I have considered: 1) Allowing paths inside the name of the repository "name" { ... } config syntax, and extending gotweb's summary page to crawl sub-directories of the repos_path directory for additional repositories to display. The downside of this approach is that gotwebd remains restricted to serving repositories within the repos_path, and that gotwebd.conf accepts repository "path" syntax even though gotd only accepts repository "name" syntax, which is inconsistent. The upside is that visually grouping repositories via sub-directories of the repos_path could be done intuitively by moving directories around on disk, rather than having to define grouping and hierarchy in the configuration syntax. 2) Adding support for the "path" keyword as it exists in gotd.conf, which would allow displaying repositories located at arbitrary paths in addition to the repositories found in the repos_path directory. The upside of this is consistency between gotd.conf and gotwebd.conf. The downside is that any repositories not living directly beneath the repos_path would need to be listed explicitly. Maybe both approaches could be combined, not sure. > Access rules should be configurable not only for individual repositories > but also for locations (directory prefixes), with permissions inherited by > repositories and sublocations. > > For example, I'd like to make some directories of repositories publicly > accessible for anonymous browsing and cloning, while requiring > authentication for others. > > Ideally, gotsysd would manage this hierarchy and its access rules, while > gotwebd would support browsing nested locations and enforce the > corresponding permissions. I would not support this idea for gotsysd at all, and I will explain why below. For gotwebd, maybe. Above, I considered visual grouping of repositories only. Access permissions carry additional complexity and risks. First let me point out that what you are proposing is already possible, at least to some degree. You can always run multiple instances of gotwebd exposed at different locations by the web server, with each gotwebd serving a distinct project, team, or whatever. And you can assign users to distinct groups and set access rules for the appropriate group for every repository, in both gotd.conf and gotwebd.conf. The only thing gotwebd lacks is a hierarchy of repository paths and access rules. But strictly speaking this is just added convenience for a sysadmin. It doesn't mean that hosting multiple projects within one server is impossible right now. I would argue the idea of such hierarchies is well suited for systems where user accounts are managed via a GUI or a web UI. If such systems do not support user and permission hierarchies they run into the problem where the admin has to tick hundreds of boxes. But here, we are dealing with text configuration files, not a UI. Which means sysadmin convenience can be achieved by scripting the generation of gotwebd.conf and gotd.conf. Additionally, both of these configuration files already support macros, reducing the need to edit the files in lots of places when changing any settings which are defined via macros. Now, discussing gotwebd in particular: Declaring access permissions on an intermediate directory path would require additional configuration syntax. Which is not a big deal in itself but would need to be introduced carefully in a way that is consistent with the already existing gotwebd config inheritence cascade of global context -> web server context -> repository context. Adding yet another layer to this seems quite complex, and expands the feature surface which our regression tests need to cover. While inheritance in gotwebd is already defined for toggles such as authentication on/off. there is currently no concept of inheritance for access rules, which is deliberate. In gotd, repository access rules are always declared per-repository. This design was mirrored to gotwebd for consistency and for leaving as little room as possible for mistakes such as the access rules becoming out of sync between the two. And there is an intersection with other existing features to consider. For instance, when a user becomes a member of multiple groups, with each group in a different part of the proposed project/team hierarchy, which repositories should be displayed on the summary page? At present, this page simply lists all repositories the user has access to. Which means this page would end up showing a mix of repositories which belong to distinct projects or teams if a user is a member of both. That might be what you want, but if your goal is to simulate isolated project spaces with repository groups and access rules, then this behaviour of the summary page contradicts your goal. Perhaps running one instance of gotwebd per group is the better answer? Regarding gotsysd: This tool was specifically designed to run our hosting service, where users do not want to be root on the server. They want our hosting to manage the server for them. However, we still need to enable users to do things such as creating user accounts which requires root permissions. So gotsysd was created as an intermediary and, unlike gotd and gotwebd, gotsysd has root access. Which means adding complexity to it always carries a risk of privilege escalation, where a rouge admin could do things on the system which we didn't intend them do be able to do. The tool may well work in simple self-hosted setups. But that does not seem to be what you are trying to do. You are already root on your server machine and are configuring gotd and gotwebd by hand, and you are considering hosting multiple projects and teams on this server. There are already many other automated system configuration tools available to you for managing user accounts, ssh keys, and so on. Or you could run your setup as a fleet of gotsysd VMs, like we do on our hosting service. Keeping the repository hierarchy in gotsys.conf flat is important to me because this solves a real problem. The gotsys.conf file is under version control and we must be able to produce a working system configuration from any version ever committed. For whatever reason, we might need to roll the system configuration back to an earlier gotsys.conf version on request, and this rollback must always work. If we allow users to place repositories in sub-directories then we allow for situations where different versions of the gotsys.conf file contradict each other. Consider: gotsys.conf version 1: repository "foo/bar.git" { .. } If we mirror this to an on-disk hierarchy, that means we need to: mkdir foo got init foo/bar Now assume the user decides to rename this repository (or add a new repository) in version 2: repository "foo" { .. } If we now create a repository at foo.git, it would shadow the "foo/" directory (because the .git extension is optional in incoming requests). Now we cannot update to version 2 or backdate from version 2 to version 1 without making significant changes to the on-disk layout. Which is difficult to automate without making mistakes. And this is just a very simple case. If we allow arbitrary nesting then the tree structures users would be allowed to create across multiple versions of gotsys,conf could quickly conflict in non-trivial ways. Deletion of repositories was not implemented for the same reason, to ensure that nothing will ever be deleted while we roll back to an earlier gotsys.conf version. So I don't think the extra implementation effort and complexity would be justified, especially given that your use case can already be covered by defining distinct groups of users, or even by simply running additional servers with gotsysd.