# https://github.com/go-gitea/gitea Project Manual

Generated at: 2026-07-06 18:29:48 UTC

## Table of Contents

- [Gitea Overview & System Architecture](#page-overview)
- [Data Models & Database Layer](#page-backend)
- [Actions / CI-CD System](#page-actions)
- [Organizations, Teams & Repository Management](#page-orgs)

<a id='page-overview'></a>

## Gitea Overview & System Architecture

### Related Pages

Related topics: [Data Models & Database Layer](#page-backend), [Actions / CI-CD System](#page-actions)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [main.go](https://github.com/go-gitea/gitea/blob/main/main.go)
- [cmd/web.go](https://github.com/go-gitea/gitea/blob/main/cmd/web.go)
- [cmd/main.go](https://github.com/go-gitea/gitea/blob/main/cmd/main.go)
- [routers/init.go](https://github.com/go-gitea/gitea/blob/main/routers/init.go)
- [routers/web/web.go](https://github.com/go-gitea/gitea/blob/main/routers/web/web.go)
- [routers/install/install.go](https://github.com/go-gitea/gitea/blob/main/routers/install/install.go)
</details>

# Gitea Overview & System Architecture

## 1. Purpose & Scope

Gitea is a self-hosted, single-binary Git service written in Go. It provides repository hosting, user and organization management, issue and pull-request workflows, package registries, wiki pages, and a built-in CI/CD subsystem compatible with the GitHub Actions syntax. The project is a community-driven fork inspired by Gogs, evolving toward a "Gitea-hosted Gitea" model where development moves onto its own infrastructure. Source: [main.go:1-30]().

The platform supports multiple databases (SQLite, MySQL, PostgreSQL, MSSQL) and runs as a Go module distributed as a single static binary with embedded templates and assets. It exposes both server-rendered HTML and a versioned JSON/REST API, plus experimental federation concepts referenced in long-running community issues like #1612. The latest tagged line is `v1.27.0-rc0`, reflecting active development of features such as reusable workflows (PR #37478) and hardened Content-Security-Policy nonces (PR #37232).

## 2. Application Bootstrap & Entry Points

The process begins in `main.go`, which performs minimal setup and defers all real work to subcommands registered under the `cmd/` package. It calls into `cmd.Execute()` to dispatch based on CLI arguments. Source: [main.go:25-60]().

The `cmd/main.go` file defines the root command, global flags, and the registration of every subcommand (`web`, `serv`, `hook`, `admin`, `doctor`, `dump`, `restore`, `cmd`, `migrate`, etc.). Each subcommand is implemented in its own file under `cmd/`. Source: [cmd/main.go:1-80]().

`cmd/web.go` is the canonical web-server entry point. It:
1. Loads the global configuration via `setting.LoadFromCommonConf()`.
2. Installs graceful-shutdown signal handlers.
3. Calls `routers.NormalRoutes()` (or `routers.RootRoutes()`) to mount the HTTP mux.
4. Starts the listener on `[::]:PORT` with optional TLS termination. Source: [cmd/web.go:40-180]().

The `serv` subcommand (`cmd/serv.go`) and `hook` subcommand (`cmd/hook.go`) handle git-protocol "smart HTTP", SSH, and server-side webhook callbacks, allowing a single binary to serve both the website and the git transport layer. The `gitea doctor` and `gitea admin` subcommands provide in-place maintenance and CLI-based user/repository management.

## 3. Router Initialization & Web Layer

`routers/init.go` is the central glue between configuration, database, and the HTTP layer. It initializes XORM database sessions, sets up the storage layer (local filesystem, object storage, or S3-compatible), registers the global panic recovery and logging middlewares, and prepares the template renderer. Source: [routers/init.go:1-90]().

The HTTP dispatch is split into two trees, both defined in `routers/web/web.go`:
- **Global routes** (`NormalRoutes`) – mounted at `/` for HTML, asset, avatars, and session-bound UI pages.
- **API routes** (`RootRoutes` / `APIRoutes`) – mounted at `/api/v1` for the REST API.
- **Installation routes** – mounted only when `setting.InstallLock` is `false`, redirecting requests to the first-run installer. Source: [routers/web/web.go:1-120]().

The router uses `chi` (formerly `macaron`) as the underlying HTTP router. Per-request context flows via `g` (a `macaron.Context`-equivalent), supplying the logged-in user, CSRF token, flash messages, and a per-request XORM session. Middlewares enforce `webauthn`-based 2FA, `X-Forwarded-For` honoring, and reverse-proxy header rewriting.

## 4. Installation Flow & Configuration Bootstrap

On a fresh database, Gitea routes every request through `routers/install/install.go`. This handler renders the multi-step install form (database type, site title, admin account, SMTP, repository root), validates each step with server-side checks, and finally writes `app.ini` plus the initial schema via XORM migrations. Source: [routers/install/install.go:1-150]().

Once the install lock is set, the same code paths are no longer reachable — `GlobalInit()` removes those routes from the mux to prevent re-enable. The installer has been an integration touchpoint for community features that demand new schema columns (e.g., subgroups in #1872, federation keys in #1612, Actions runners in #13539), because any new persistence requirement typically begins here before being surfaced through the regular routers.

A representative request lifecycle is shown below.

```mermaid
flowchart LR
  A[main.go] --> B[cmd/web.go]
  B --> C[routers/init.go<br/>GlobalInit]
  C --> D{routing<br/>policy}
  D -->|InstallLock=false| E[routers/install/install.go]
  D -->|InstallLock=true| F[routers/web/web.go<br/>NormalRoutes]
  D -->|path /api/*| G[routers/api<br/>v1 endpoints]
  E --> H[(XORM DB)]
  F --> H
  G --> H
```

## 5. Core Architectural Layers

Although the listed bootstrap files orchestrate only the entry, they reveal the layered design used throughout the codebase:

| Layer | Responsibility | Entry file(s) |
|-------|----------------|---------------|
| CLI / process | Parse args, dispatch subcommand | `main.go`, `cmd/main.go` |
| Web command | Load config, start listener | `cmd/web.go` |
| Init / wiring | DB, storage, templates, locales | `routers/init.go` |
| HTTP dispatch | URL → handler mapping, middlewares | `routers/web/web.go` |
| First-run install | Schema migration, initial admin | `routers/install/install.go` |
| Services & models | Domain logic, persistence | `models/`, `services/` |
| Templates | Server-rendered HTML | `templates/` (embedded) |

Source: [cmd/main.go:1-80](), [routers/init.go:1-90](), [routers/web/web.go:1-120](), [routers/install/install.go:1-150](), [cmd/web.go:40-180]().

This separation lets Gitea ship a single binary that can act as a web server, a git smart-HTTP backend, an SSH force-command (`gitea serv`), a webhook receiver (`gitea hook`), or a CLI maintenance tool (`gitea admin`, `gitea doctor`), all sharing the same models, migrations, and configuration loader. New features — whether community-proposed like reusable workflows (recently promoted to breaking change in v1.27) or stricter privacy controls (e.g., PR #38145 hiding private-org membership) — plug into this routing skeleton without modifying the bootstrap chain, keeping the entry points stable as the platform grows.

---

<a id='page-backend'></a>

## Data Models & Database Layer

### Related Pages

Related topics: [Gitea Overview & System Architecture](#page-overview), [Organizations, Teams & Repository Management](#page-orgs)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [models/db/engine.go](https://github.com/go-gitea/gitea/blob/main/models/db/engine.go)
- [models/db/context.go](https://github.com/go-gitea/gitea/blob/main/models/db/context.go)
- [models/migrations/migrations.go](https://github.com/go-gitea/gitea/blob/main/models/migrations/migrations.go)
- [models/unittest/testdb.go](https://github.com/go-gitea/gitea/blob/main/models/unittest/testdb.go)
- [models/repo/repo.go](https://github.com/go-gitea/gitea/blob/main/models/repo/repo.go)
- [models/user/user.go](https://github.com/go-gitea/gitea/blob/main/models/user/user.go)
</details>

# Data Models & Database Layer

Gitea's persistent layer is built on top of the [XORM](https://xorm.io/) ORM and exposes a unified API to the rest of the application. The layer covers engine bootstrapping, request-scoped contexts, schema migrations, testing utilities, and the domain models (user, repository, organization, issue, action, etc.) that map onto relational tables. It supports PostgreSQL, MySQL/MariaDB, MSSQL, and SQLite — a multi-DB requirement that surfaces repeatedly in community feedback (e.g., issue #693 where users report issues across all three open-source backends).

## Purpose and Scope

The data models and database layer form the persistence backbone of Gitea. Its responsibilities are:

- Bootstrapping a single `*xorm.Engine` instance and resolving the dialect at runtime.
- Providing a `context.Context`-aware façade (`db.Context`, `db.Engine`) so handlers, services, and CLI commands share consistent transaction and cancellation semantics.
- Performing schema evolution through a numbered migration list, keeping upgrades idempotent across supported databases.
- Offering a deterministic test harness so unit and integration tests run against an in-memory or temporary SQLite database.

Source: [models/db/engine.go:1-120]() and [models/db/context.go:1-80]().

## Engine, Dialect, and Connection Management

`models/db/engine.go` centralizes engine construction. It detects the configured `Database.Type` (postgres, mysql, mssql, sqlite3) and applies dialect-specific options such as parameter style, charset, and SSL mode. The engine is created lazily and cached globally; subsequent calls reuse the same session pool.

Key patterns observed in the file:

- A single `Engine` interface is defined that wraps `*xorm.Engine` plus helper methods (`Insert`, `Get`, `Find`, `Exec`, `Begin`).
- `InitEngine`, `NewEngine`, and `DumpDatabase` cover the lifecycle: connection, health-check, and diagnostics.
- `Database-Type` selection drives DSN assembly, allowing the same binary to target multiple backends. This design is what enables the cross-database compatibility the community tracks (issue #693 lists PostgreSQL, MySQL, and SQLite simultaneously).

Source: [models/db/engine.go:60-200]().

## Context, Transactions, and Query Patterns

`models/db/context.go` introduces `db.Context` and `db.Engine`, thin context-aware wrappers around the XORM engine. They propagate the standard `context.Context` so queries can be cancelled by HTTP deadlines, and they surface a `WithTx` helper for explicit transactions.

The typical call pattern from a service layer looks like:

```go
ctx, committer, err := db.TxContext(db.DefaultContext)
if err != nil { return err }
defer committer.Close()

if _, err := db.GetEngine(ctx).Where("id = ?", id).Get(&repo); err != nil {
    return err
}
return committer.Commit()
```

This pattern guarantees that every mutating call either commits as a unit or rolls back, which is critical for operations like repository transfers, organization membership changes, and the subgroup-style hierarchies requested in issue #1872.

Source: [models/db/context.go:40-180]().

## Schema Migrations

`models/migrations/migrations.go` declares the migration registry. Each migration is a `Migration` struct with an `ID` (a monotonically increasing integer) and `Migrate` / `Rollback` functions. The list is consulted at startup; unapplied IDs are executed in order, and the resulting version is stored in a `version` table.

Highlights:

- New migrations append to the slice; IDs are never reused or reordered.
- Each migration must be safe to re-run after a partial failure, since the runner skips already-applied IDs on the next boot.
- The system stores migration state per database, which is why forum-reported migration glitches in issue #693 (e.g., users stuck mid-upgrade on SQLite) can be diagnosed by inspecting the `version` table.

Source: [models/migrations/migrations.go:1-150]().

## Testing Harness

`models/unittest/testdb.go` provides `MainTest`, `GetTestEngine`, and fixtures loading. Tests typically call:

```go
unittest.MainTest(m, path_to_tests, "fixtures.yml")
```

This function initializes a fresh engine (usually SQLite in-memory), applies the migration set, and loads YAML fixtures. The harness deliberately mirrors production initialization so that the same migration code paths are exercised in CI.

Source: [models/unittest/testdb.go:1-160]().

## Core Domain Models

Although Gitea has dozens of model packages, the two referenced here illustrate the conventions used everywhere.

`models/user/user.go` defines `User`, `EmailAddress`, and the authentication-related structures. It exposes typed finder methods (`GetUserByID`, `GetUserByName`, `GetUserByEmail`) and embeds permission checks directly on the struct. Cross-cutting concerns (e.g., `IsOrganization`, `IsActive`) are computed properties that drive UI authorization.

`models/repo/repo.go` defines `Repository` along with related entities such as `Collaborator`, `Unit`, and `Watch`. It demonstrates how Gitea composes models through XORM's relationship tags (`xorm:"extends"`, `belongs_to`) and how it denormalizes counters (e.g., `NumForks`, `NumStars`) for query efficiency.

Both packages rely on `db.GetEngine(ctx)` rather than a package-level engine, reinforcing the context-propagation rule discussed above. This convention enables the federated scenarios sketched in issue #1612: future federation code can run inside a single transaction that spans user, repository, and organization tables without ad-hoc engine threading.

Source: [models/user/user.go:1-120]() and [models/repo/repo.go:1-140]().

## Architectural Snapshot

```mermaid
flowchart TD
  A[Service Layer / Handlers] --> B[db.Context / db.Engine]
  B --> C[xorm.Engine]
  C --> D[(PostgreSQL / MySQL / MSSQL / SQLite)]
  E[models/migrations] --> C
  F[models/unittest] --> C
  G[models/user, models/repo, ...] --> B
```

The diagram shows the layering: domain models and services never reach XORM directly; they go through the context-aware façade, which in turn delegates to the singleton engine. Migrations and test fixtures operate on the same engine layer, ensuring schema and code stay synchronized across releases.

---

<a id='page-actions'></a>

## Actions / CI-CD System

### Related Pages

Related topics: [Gitea Overview & System Architecture](#page-overview)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [modules/actions/jobparser/jobparser.go](https://github.com/go-gitea/gitea/blob/main/modules/actions/jobparser/jobparser.go)
- [modules/actions/workflows.go](https://github.com/go-gitea/gitea/blob/main/modules/actions/workflows.go)
- [modules/actions/workflowpattern/workflow_pattern.go](https://github.com/go-gitea/gitea/blob/main/modules/actions/workflowpattern/workflow_pattern.go)
- [models/actions/run.go](https://github.com/go-gitea/gitea/blob/main/models/actions/run.go)
- [models/actions/runner.go](https://github.com/go-gitea/gitea/blob/main/models/actions/runner.go)
- [models/actions/task.go](https://github.com/go-gitea/gitea/blob/main/models/actions/task.go)
</details>

# Actions / CI-CD System

## Purpose and Scope

The Actions subsystem is Gitea's internal CI/CD platform, originally proposed in discussion #13539 as a GitHub-Actions-compatible engine. It allows repositories to declare pipelines in YAML files under `.gitea/workflows/*.yml`, trigger them on Git events (push, pull request, tag, schedule, manual), and dispatch jobs to self-hosted or hosted runners. Source: [modules/actions/workflows.go](https://github.com/go-gitea/gitea/blob/main/modules/actions/workflows.go).

Unlike an external CI service, Gitea Actions embeds the workflow runner protocol directly into the same Go process tree as the Gitea server. Workflow files are detected by the Git hook handler, parsed into runs, and persisted as `ActionRun` rows. Self-hosted runners connect to Gitea over HTTP(S), poll for `ActionTask` rows, and post back step logs and job results. Source: [models/actions/task.go](https://github.com/go-gitea/gitea/blob/main/models/actions/task.go).

The subsystem's core responsibilities are:

- Discover and parse `.gitea/workflows/**` YAML on push events.
- Evaluate GitHub-style `on:` filters with the same branch/tag/path semantics.
- Expand reusable workflows and matrix strategies into individual jobs.
- Queue jobs, hand them to runners, and persist their log output.

## Workflow Parsing and Job Generation

The parser pipeline lives in `modules/actions/jobparser` and `modules/actions/workflowpattern`.

`workflowpattern` implements a mini evaluator for the GitHub filter grammar (`branches`, `tags`, `paths`, `types`). It supports `*`, `**`, `?`, `+`, character classes, leading `!` negation, and comparisons such as `branches: [main, 'release/**']`. Source: [modules/actions/workflowpattern/workflow_pattern.go](https://github.com/go-gitea/gitea/blob/main/modules/actions/workflowpattern/workflow_pattern.go).

`jobparser` loads the YAML using `gopkg.in/yaml.v3` and walks the document tree with a stateful recursive iterator. Each `jobs.<id>` block is materialized into a `Job` struct holding `Steps`, `Needs`, `RunsOn`, `Container`, `Services`, `Strategy`, `Outputs`, `Env`, and `If`. The parser applies sane defaults (e.g., `shell: bash` on Linux, `timeout-minutes: 360`) and validates required keys. Reusable workflow references (`uses: org/repo/.gitea/workflow.yml@ref`) are resolved and their jobs are merged in, matching GitHub's behavior. Source: [modules/actions/jobparser/jobparser.go](https://github.com/go-gitea/gitea/blob/main/modules/actions/jobparser/jobparser.go).

Detected workflows are picked up in `DetectWorkflows` and `DetectMatchedWorkflows`, which compare the commit's added/modified files against `.gitea/workflows/`. Matched files are loaded, parsed with `jobparser`, and returned as `Workflows` whose `Event` payload describes when and why they ran. Source: [modules/actions/workflows.go](https://github.com/go-gitea/gitea/blob/main/modules/actions/workflows.go).

## Run, Task, and Runner Model

Persistence is modeled around three primary entities under `models/actions/`:

| Entity | Purpose | Key Fields |
|--------|---------|------------|
| `ActionRun` | A single triggered execution of a workflow | `RepoID`, `TriggerEvent`, `Status`, `Started`, `Stopped`, `CommitSHA`, `EventPayload` |
| `ActionRunner` | A registered runner (hosted or self-hosted) | `UUID`, `Name`, `OwnerID`, `Token`, `Version`, `LastActive`, `Labels` |
| `ActionTask` | A unit of work assigned to one runner | `Job`, `Attempt`, `RunnerID`, `Status`, `Started`, `Stopped`, `Context` |

A run fans out into one or more jobs (tasks). Each task carries the serialized job spec (`Needs`, `RunsOn`, `Steps`, matrix, secrets placeholder) that the runner will reconstruct at dispatch time. Source: [models/actions/task.go](https://github.com/go-gitea/gitea/blob/main/models/actions/task.go).

The `ActionRunner` model represents the daemon side of the equation: when a runner registers, Gitea mints a token and stores labels (`["self-hosted", "linux", "x64"]`) used for `runs-on:` matching. The `FetchRun()` and `UpdateRun()` methods define the polling/job-state API surface. Source: [models/actions/runner.go](https://github.com/go-gitea/gitea/blob/main/models/actions/runner.go).

`ActionRun` aggregates task statuses; the server rolls them up into a final run status and exposes the result via the web UI, REST API, and runner callbacks. Source: [models/actions/run.go](https://github.com/go-gitea/gitea/blob/main/models/actions/run.go).

## Execution Flow

```
Git push / PR / schedule
   ↓ (webhook / hook task)
modules/actions/workflows.go     (DetectMatchedWorkflows)
   ↓
modules/actions/jobparser        (parse YAML → Jobs[])
   ↓
modules/actions/workflowpattern  (filter by branches/tags/paths)
   ↓
models/actions/run.go            (insert ActionRun)
   ↓
models/actions/task.go           (one ActionTask per job)
   ↓
HTTP  /api/actions/runs          (runner pulls)
   ↓ (inline logs via POST)
models/actions/runner.go         (UpdateRun / complete)
```

When the server receives a push, the post-receive handler enumerates changed files, calls `DetectWorkflows`, filters them with `workflowpattern`, parses each with `jobparser`, and writes matching jobs as `ActionTask` rows linked to a parent `ActionRun`. Self-hosted runners perform a long-poll `FetchTask` request; the server returns the first queued task whose `RunsOn` labels intersect the runner's labels. As the runner executes steps, it streams `output` line batches back to the server, which appends them to per-step log files and updates the `ActionTask.Status`. Source: [models/actions/task.go](https://github.com/go-gitea/gitea/blob/main/models/actions/task.go).

## Operational Notes

- **Reusable workflows** landed in v1.27 via breaking improvement #37478; `jobparser` resolves `uses:` references recursively.
- **Runner labels** gate the assignment of a task: a job requesting `runs-on: [self-hosted, gpu]` is invisible to runners without both.
- **Concurrency** is controlled per run via `concurrency:` keys in the YAML, honored by the server when creating `ActionTask` rows.
- **Security**: in v1.27.0-rc0, OAuth introspection was tightened (#38042) and the Actions endpoints inherit the same policy when runners authenticate via user or repository scoped tokens.

Community discussion #13539 frames the long-running design intent (compat with GitHub `yaml`, action plugins, conditional `checkout`); most of the items in that proposal are now reflected in the jobparser, reusable workflows, and matrix support implemented across the modules above.

---

<a id='page-orgs'></a>

## Organizations, Teams & Repository Management

### Related Pages

Related topics: [Data Models & Database Layer](#page-backend), [Gitea Overview & System Architecture](#page-overview)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [models/organization/org.go](https://github.com/go-gitea/gitea/blob/main/models/organization/org.go)
- [models/organization/team.go](https://github.com/go-gitea/gitea/blob/main/models/organization/team.go)
- [models/unit/unit.go](https://github.com/go-gitea/gitea/blob/main/models/unit/unit.go)
- [models/perm/access_mode.go](https://github.com/go-gitea/gitea/blob/main/models/perm/access_mode.go)
- [services/org/org.go](https://github.com/go-gitea/gitea/blob/main/services/org/org.go)
- [services/org/team.go](https://github.com/go-gitea/gitea/blob/main/services/org/team.go)
- [models/repo/repo.go](https://github.com/go-gitea/gitea/blob/main/models/repo/repo.go)
- [models/perm/access/repo_permission.go](https://github.com/go-gitea/gitea/blob/main/models/perm/access/repo_permission.go)
- [routers/web/org/org.go](https://github.com/go-gitea/gitea/blob/main/routers/web/org/org.go)
- [routers/web/org/teams.go](https://github.com/go-gitea/gitea/blob/main/routers/web/org/teams.go)

</details>

# Organizations, Teams & Repository Management

## Purpose and Scope

Gitea implements a three-tier collaboration model: Users own repositories either personally or through Organizations, and Organizations group users into Teams that share access to subsets of those repositories. This page documents the data model, the unit-based permission system, and the repository access flow that underpin these subsystems in the `models/organization`, `services/org`, and `routers/web/org` packages.

## Data Model: Organizations and Teams

Organizations are first-class user records with org-specific fields such as visibility, max repo count, and member policies. The `Organization` struct lives in `models/organization/org.go` and is distinguished from regular `User` records by the `Type` field. Source: [models/organization/org.go:1-50]().

A Team belongs to exactly one Organization and is composed of:

- **Members** — a set of Users persisted through the `TeamUser` join table
- **Repositories** — granted via the `TeamRepo` join table with a per-repo access mode
- **Units** — a list of repository capabilities the team can exercise, each carrying its own access mode

Every Organization has a built-in **Owners** team with `AccessModeAdmin` on every Unit; it is created automatically when an org is established and cannot be removed. Source: [models/organization/team.go:1-80]().

## Units, Access Modes, and Permission Resolution

Capabilities within a repository are decomposed into discrete Units so that read/write access can be granted granularly. The Unit type and its constants are defined in `models/unit/unit.go`, with examples such as `UnitCode`, `UnitIssues`, `UnitPullRequests`, `UnitReleases`, `UnitWiki`, `UnitProjects`, `UnitPackages`, and `UnitActions`. Source: [models/unit/unit.go:1-80]().

Access intensities are encoded by the `AccessMode` enum in `models/perm/access_mode.go`:

| Access Mode | Numeric Value | Typical Effect |
|---|---|---|
| `AccessModeNone` | 0 | No access |
| `AccessModeRead` | 1 | View, clone, comment |
| `AccessModeWrite` | 2 | Push branches, open PRs, manage issues |
| `AccessModeAdmin` | 3 | Settings, transfer, delete, manage members |

Teams store per-unit mappings (`TeamUnit` records), while repositories declare their own `RepoUnit` records with a default access mode. Source: [models/perm/access_mode.go:1-30]().

When a user requests access to an org-owned repository, permission evaluation in the `services/org` package follows a chain of checks:

1. If the user is the repository owner, grant full permissions.
2. If the user is a member of the Organization's Owners team, grant full permissions.
3. For each team the user belongs to that has a `TeamRepo` entry for this repo, intersect the team's Unit access modes with the repo's Unit grants.
4. The effective permission is the maximum permitted `AccessMode` for each Unit after evaluation. Source: [services/org/org.go:1-120](), [services/org/team.go:1-200]().

The web layer at `routers/web/org/org.go` and `routers/web/org/teams.go` exposes management endpoints for these operations, including team creation, member invitation, and assigning repo-to-team grants. Source: [routers/web/org/teams.go:1-150]().

## Known Limitations and Community Context

Long-running community discussions highlight areas where the current organization architecture does not yet extend:

- **Subgroups** (Issue #1872, 129 comments): Gitea organizations are flat — there is no parent/child inheritance between organizations. GitLab-style subgroups would require schema changes in `models/organization/org.go` and additional service-layer logic. Source: Community Issue #1872.
- **Federation** (Issue #1612, 43 comments): Cross-instance sharing of organizations, repositories, or users is not implemented; organizations cannot span multiple Gitea instances. Source: Community Issue #1612.
- **Private membership exposure** (v1.27.0-rc0, Fix #38145): Recent security hardening ensures private org membership is not leaked via `public_members` endpoints, reflecting ongoing attention to permission boundary correctness. Source: [models/perm/access_mode.go:1-30]().

These issues have remained open for years, indicating that organization hierarchy and cross-instance federation are intentionally out of scope for the current architecture and would represent major schema migrations if introduced. For day-to-day operations, the existing flat-org + team + per-repo grant model covers the vast majority of multi-user repository management scenarios documented in the community.

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: go-gitea/gitea

Summary: Found 15 structured pitfall item(s), including 1 high/blocking item(s). Top priority: Security or permission risk - Security or permission risk requires verification.

## 1. Security or permission risk - Security or permission risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/20716

## 2. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/37531

## 3. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/go-gitea/gitea

## 4. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/4842

## 5. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/37128

## 6. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/go-gitea/gitea

## 7. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/go-gitea/gitea

## 8. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/go-gitea/gitea

## 9. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/38270

## 10. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/36792

## 11. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/22275

## 12. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/27468

## 13. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/go-gitea/gitea/issues/36755

## 14. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/go-gitea/gitea

## 15. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/go-gitea/gitea

<!-- canonical_name: go-gitea/gitea; human_manual_source: deepwiki_human_wiki -->
