feat(permissions): section-based visibility — public wiki/releases on private repos #238

Closed
opened 2026-05-30 16:41:21 +00:00 by jmiller · 1 comment
Owner

Summary

Add section-based visibility permissions so individual repository sections (wiki, releases, issues, etc.) can have different visibility levels from the codebase itself. This allows repos to keep source code private while making wiki documentation, releases, and other sections publicly accessible.

Use case

A private repository should be able to expose:

  • Wiki as public (documentation accessible to everyone)
  • Releases as public (download artifacts without repo access)
  • Issues as public or read-only (community bug reports)
  • Code remains private (source access restricted to collaborators)

This mirrors functionality available in platforms like GitLab where wiki and pages visibility can differ from repo visibility.

Current behavior

Repository visibility is all-or-nothing: a private repo hides everything (wiki, releases, issues, code). There is no way to make individual sections public while keeping the codebase private.

Proposed approach

Add per-section visibility overrides to the repository unit model. Each repo unit (code, issues, wiki, releases, packages, actions, projects) would support its own visibility setting that can override the repo-level default:

  • inherit (default): follows repo visibility
  • public: accessible to everyone regardless of repo visibility
  • private: restricted to collaborators only

Areas to investigate

  • repo_unit model and how units are currently gated
  • Anonymous access controls (there may already be partial support)
  • API permission checks per unit type
  • Web route middleware that enforces visibility
  • Git HTTP/SSH access for wiki repos (wiki is a separate git repo)
  • Template and UI changes to expose per-section visibility settings

References

  • GitLab has "Pages access control" and per-feature visibility (issues, wiki, etc.)
  • GitHub has limited support (public wiki on private repos is not supported)
  • Gitea has repo_unit with anonymous_access_mode (may be a starting point)

Created by @MokoBot - Claude Opus 4.6

## Summary Add section-based visibility permissions so individual repository sections (wiki, releases, issues, etc.) can have different visibility levels from the codebase itself. This allows repos to keep source code private while making wiki documentation, releases, and other sections publicly accessible. ### Use case A private repository should be able to expose: - **Wiki** as public (documentation accessible to everyone) - **Releases** as public (download artifacts without repo access) - **Issues** as public or read-only (community bug reports) - **Code** remains private (source access restricted to collaborators) This mirrors functionality available in platforms like GitLab where wiki and pages visibility can differ from repo visibility. ### Current behavior Repository visibility is all-or-nothing: a private repo hides everything (wiki, releases, issues, code). There is no way to make individual sections public while keeping the codebase private. ### Proposed approach Add per-section visibility overrides to the repository unit model. Each repo unit (code, issues, wiki, releases, packages, actions, projects) would support its own visibility setting that can override the repo-level default: - **inherit** (default): follows repo visibility - **public**: accessible to everyone regardless of repo visibility - **private**: restricted to collaborators only ### Areas to investigate - repo_unit model and how units are currently gated - Anonymous access controls (there may already be partial support) - API permission checks per unit type - Web route middleware that enforces visibility - Git HTTP/SSH access for wiki repos (wiki is a separate git repo) - Template and UI changes to expose per-section visibility settings ### References - GitLab has "Pages access control" and per-feature visibility (issues, wiki, etc.) - GitHub has limited support (public wiki on private repos is not supported) - Gitea has repo_unit with anonymous_access_mode (may be a starting point) --- *Created by @MokoBot - Claude Opus 4.6*
Author
Owner

Implementation Plan

Current State: More exists than expected

The data model and settings UI already exist:

  • RepoUnit has AnonymousAccessMode and EveryoneAccessMode fields (migrations v297, v318)
  • Settings page at /settings/public_access lets you configure per-unit visibility
  • Permission engine in repo_permission.go handles per-unit public access via UnitAccessMode()
  • Web/API middleware use HasAnyUnitAccessOrPublicAccess() for repo-level gating
  • Template tabs already hide/show based on Permission.CanRead(unitType)

Identified Gaps (what needs fixing)

Gap 1 (Critical): Git HTTP access for wiki repos

  • File: routers/web/repo/githttp.go:131
  • isPublicPull := repoExist && !repo.IsPrivate && isPull -- for private repos this is always false
  • Fix: check per-unit AnonymousAccessMode instead of just repo.IsPrivate

Gap 2: Repo discoverability in explore/search

  • File: models/repo/repo_list.go
  • Private repos with public units are invisible to anonymous users
  • Fix: add SQL subquery to include repos with anonymous_access_mode > 0 on any unit

Gap 3: No API for managing unit public access

  • No GET/PATCH endpoints for per-unit visibility settings

Gap 4: Home page for partial-access users

  • Anonymous user accessing private repo with public wiki sees code page (no access) instead of redirect to wiki

Phased Implementation

Phase Scope Risk Files
1 Git HTTP fix + home redirect High githttp.go, repo.go, view.go
2 Search/explore discoverability Medium repo_list.go
3 API endpoints Medium api.go, structs/repo.go
4 UI improvements (landing page, badges) Low templates
5 Tests Low integration tests

No migration needed

The anonymous_access_mode and everyone_access_mode columns already exist.


@MokoBot - Claude Opus 4.6

## Implementation Plan ### Current State: More exists than expected The data model and settings UI **already exist**: - `RepoUnit` has `AnonymousAccessMode` and `EveryoneAccessMode` fields (migrations v297, v318) - Settings page at `/settings/public_access` lets you configure per-unit visibility - Permission engine in `repo_permission.go` handles per-unit public access via `UnitAccessMode()` - Web/API middleware use `HasAnyUnitAccessOrPublicAccess()` for repo-level gating - Template tabs already hide/show based on `Permission.CanRead(unitType)` ### Identified Gaps (what needs fixing) **Gap 1 (Critical): Git HTTP access for wiki repos** - File: `routers/web/repo/githttp.go:131` - `isPublicPull := repoExist && !repo.IsPrivate && isPull` -- for private repos this is always false - Fix: check per-unit `AnonymousAccessMode` instead of just `repo.IsPrivate` **Gap 2: Repo discoverability in explore/search** - File: `models/repo/repo_list.go` - Private repos with public units are invisible to anonymous users - Fix: add SQL subquery to include repos with `anonymous_access_mode > 0` on any unit **Gap 3: No API for managing unit public access** - No GET/PATCH endpoints for per-unit visibility settings **Gap 4: Home page for partial-access users** - Anonymous user accessing private repo with public wiki sees code page (no access) instead of redirect to wiki ### Phased Implementation | Phase | Scope | Risk | Files | |-------|-------|------|-------| | **1** | Git HTTP fix + home redirect | High | githttp.go, repo.go, view.go | | **2** | Search/explore discoverability | Medium | repo_list.go | | **3** | API endpoints | Medium | api.go, structs/repo.go | | **4** | UI improvements (landing page, badges) | Low | templates | | **5** | Tests | Low | integration tests | ### No migration needed The `anonymous_access_mode` and `everyone_access_mode` columns already exist. --- *@MokoBot - Claude Opus 4.6*
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoGitea#238