"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: Hierarchical repositories in gotsysd and gotwebd
To:
Anton Kasimov <kasimov.an@gmail.com>
Cc:
gameoftrees@openbsd.org
Date:
Wed, 14 Oct 2026 10:45:44 +0200

Download raw body.

Thread
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.