> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

> **Themelio compatibility reference.** This page describes the retained Themelio implementation or its historical design. Check the [parallel-operation guide](/compatibility/index.md) before applying it to the current platform.

# GitLab Groups, Subgroups & Visibility

This document describes how Themelio uses GitLab groups and subgroups to organize repositories ([models](/terms/model.md), [datasets](/terms/dataset.md), [spaces](/terms/space.md)), and the visibility rules that govern access.

## Group Hierarchy

Repositories are organized by resource type first, then by Waldur project slug:

```
/{type}/{project-slug}/{repo-name}
```

For example:

```
models/
├── pharos-nlp/                (Waldur project namespace)
│   ├── bert-greek             (private project)
│   └── gpt-el                 (public project)
├── climate-ai/
│   └── weather-forecast-v2    (internal project)
datasets/
├── pharos-nlp/
│   └── greek-corpus           (public project)
├── climate-ai/
│   └── era5-subset            (private project)
spaces/
├── pharos-nlp/
│   └── bert-greek-demo        (public project)
```

Each Waldur project maps to a subgroup under every top-level type group. When a Waldur proposal is accepted and a project is created, the corresponding subgroups are provisioned automatically.

## Visibility Rules

GitLab enforces a strict visibility hierarchy: **a child cannot be more visible than its parent**.

| Level      | Who can see                          |
| ---------- | ------------------------------------ |
| `private`  | Explicit project/group members only  |
| `internal` | Any authenticated GitLab user        |
| `public`   | Anyone, including anonymous visitors |

For a repository to support all three visibility levels, both its parent subgroup and grandparent group must be `public`. This is why:

- **Top-level groups** (`models`, `datasets`, `spaces`) are created as **public**.
- **Project subgroups** (e.g., `models/pharos-nlp`) are created as **public**.
- **Individual repositories** can then be set to `private`, `internal`, or `public` by the project members with sufficient permissions.

## Namespace Provisioning

When a Waldur proposal is accepted, the GitLab site agent provisions the namespace:

1. **Create a public subgroup** under each top-level type group, named after the Waldur project slug (e.g., `models/pharos-nlp`, `datasets/pharos-nlp`, `spaces/pharos-nlp`).
2. **Sync membership** from Waldur to GitLab. Project owners get GitLab Owner role (50) on the subgroup; project members get Developer role (30).
3. **Add all platform users as Guest** to the top-level groups, so they can browse public and internal repositories across all namespaces.

Waldur is authoritative for membership — the membership sync pod overwrites any GitLab-side role changes.

## Access Control Summary

| Resource                                     | Role               | Effect                                                             |
| -------------------------------------------- | ------------------ | ------------------------------------------------------------------ |
| Top-level group (`models`)                   | Guest              | Can browse public/internal repositories across all namespaces      |
| Own project subgroup (`models/pharos-nlp`)   | Owner              | Full control: create repositories, manage members, change settings |
| Other project subgroup (`models/climate-ai`) | Guest (inherited)  | Can see public/internal repositories, no write access              |
| Repositories within own project              | Owner or Developer | Can set visibility, push, rename, delete (based on role)           |

## Operator Notes

### Initial Setup

Top-level groups are created by `gitops/scripts/create-top-level-groups.sh` during deployment. This script requires:

- `GITLAB_ORIGIN`: The GitLab instance URL
- `ROOT_PAT`: A root user personal access token with `api` scope

### About "Internal" Visibility

GitLab's `internal` visibility means any authenticated user on the GitLab instance can see the resource. Since Themelio authenticates all users through Keycloak/[MyAccessID](/terms/myaccessid.md), `internal` effectively means "visible to all platform users but not to anonymous visitors". This can be useful for repositories that should be shared within the platform but not indexed publicly.

<details class="page-source"><summary>Page source</summary>

<a href="/source/docs/content/product/architecture/gitlab-groups-and-visibility.md.txt">Source snapshot</a> · Revision `f928834c8`.

</details>
