# How Does Authentication Work in Gitea: A Deep Dive into the Modular Auth System

> Explore how Gitea's modular authentication system works. Learn about its methods including Basic, OAuth2, and token-based strategies for secure user sessions.

- Repository: [Gitea/gitea](https://github.com/go-gitea/gitea)
- Tags: deep-dive
- Published: 2026-03-07

---

**Gitea uses a modular authentication system where an `authPathDetector` first determines if a request requires validation, then iterates through registered `auth.Method` implementations—including Basic, OAuth2, and token-based strategies—to verify credentials and establish user sessions.**

Gitea supports multiple authentication methods ranging from HTTP Basic auth to OAuth2 tokens and WebAuthn, all coordinated through a flexible interface. Understanding how authentication works in Gitea requires examining the `services/auth` package, where the platform implements a detector-based pipeline that selectively applies validation logic based on request paths and methods.

## Request-Level Detection and Path Filtering

Before any credential validation occurs, Gitea checks whether authentication is relevant for the incoming request. In [`services/auth/auth.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/auth.go), the `authPathDetector` function inspects the request URL and HTTP method to avoid unnecessary parsing for ordinary web page loads.

The detector evaluates several conditions:

- **`isAPIPath()`** – Routes starting with `/api/…`
- **`isFeedRequest()`** – RSS/Atom feeds that may lack session cookies
- **`isAttachmentDownload()`** – Direct `/attachments/…` GET requests
- **`isGitRawOrAttachOrLFSPath()`** – Git operations and LFS raw files
- **`isArchivePath()`** – Repository archive downloads at `/archive/…`
- **`isContainerPath()`** – Docker registry requests under `/v2/…`

Only when one of these conditions returns true does the authentication middleware proceed to validate credentials against the registered methods.

## The Auth Method Interface

All authentication strategies in Gitea implement the `auth.Method` interface defined in [`services/auth/interface.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/interface.go). This abstraction allows the system to chain multiple validation techniques through a common contract.

```go
type Method interface {
    Name() string
    Verify(req *http.Request, w http.ResponseWriter,
           store DataStore, sess SessionStore) (*user_model.User, error)
}

```

The `Verify` method receives the HTTP request, response writer, data store, and session store, returning either an authenticated user model or an error. Implemented methods include:

- **`Basic`** ([`services/auth/basic.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/basic.go)) – HTTP Basic auth and x-oauth-basic token validation
- **`OAuth2`** ([`services/auth/oauth2.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/oauth2.go)) – OAuth 2 access tokens via query parameters or Bearer headers
- **`HTTPSign`** ([`services/auth/httpsign.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/httpsign.go)) – HMAC-signed requests for package registry operations
- **Group and SSPI** ([`services/auth/group.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/group.go), [`services/auth/sspi.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/sspi.go)) – SSO integrations including Kerberos and LDAP

## Basic Authentication Implementation

The `Basic` method in [`services/auth/basic.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/basic.go) handles username/password credentials and token-based authentication through HTTP Basic headers.

### Token and Password Validation Flow

1. **Header Parsing** – `Basic.parseAuthBasic` extracts the `Authorization` header or `x-oauth-basic` token from the request.

2. **Token Validation** – If the credential resembles a personal access token or OAuth token, `Basic.VerifyAuthToken` validates it against the database using `auth_model.GetAccessTokenBySHA` or calls `GetOAuthAccessTokenScopeAndUserID` for JWT access tokens.

3. **Fallback Authentication** – When token validation fails and `setting.Service.EnableBasicAuth` is true, the system falls back to username/password authentication via `UserSignIn`.

4. **Security Checks** – Two-factor authentication and WebAuthn verification occur before session creation.

5. **Context Storage** – Upon success, the user object is stored in the request's `DataStore` with `LoginMethod = "basic"`.

### Git over HTTP Example

When cloning a repository via HTTPS, Git sends credentials using Basic authentication:

```bash
git clone https://username:mytoken@gitea.example.com/user/repo.git

```

The HTTP request contains `Authorization: Basic <base64(username:mytoken)>`. Gitea's `Basic.parseAuthBasic` interprets the password as a token, validates it through the database lookup, and grants repository access without establishing a persistent web session.

## OAuth2 and JWT Token Flows

The `OAuth2` method in [`services/auth/oauth2.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/oauth2.go) handles Bearer tokens and query-parameter authentication for API requests.

### Token Extraction and Parsing

`OAuth2.parseToken` extracts tokens from three sources:

- Query parameters (`token` or `access_token`)
- `Authorization: Bearer …` headers
- Action-specific JWT tokens

The `OAuth2.userFromToken` function distinguishes between token types:

1. **Action JWTs** – Tokens containing a dot (`.`) are processed by `actions.TokenToTaskID` and converted to a temporary user via `NewActionsUserWithTaskID`.

2. **OAuth2 Access Tokens** – Standard JWTs are parsed via `oauth2_provider.ParseToken`, linked to an `OAuth2Grant`, and validated through `GetOAuthAccessTokenScopeAndUserID`.

3. **Personal Access Tokens** – If JWT parsing fails, the system falls back to `auth_model.GetAccessTokenBySHA` for classic token validation.

The resolved user is stored with `LoginMethod = "oauth2"` and the token's `ApiTokenScope` is attached to the request context for authorization checks.

### API Request Example

```http
GET /api/v1/user HTTP/1.1
Authorization: token 0d4f5a7e9c3b2a1d6e8f...

```

Gitea extracts the token, validates it via `auth_model.GetAccessTokenBySHA`, updates the token's `UpdatedUnix` timestamp, and returns the authenticated user context.

## Remember-Me Cookie Authentication

For persistent web sessions, Gitea implements a secure token-based "remember me" system in [`services/auth/auth_token.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/auth_token.go).

### Token Structure and Validation

The cookie holds a value formatted as `id:rawToken`. When a request arrives with this cookie:

1. **Extraction** – `CheckAuthToken` splits the cookie value to separate the token ID from the raw secret.

2. **Database Lookup** – The system fetches the corresponding `AuthToken` row from the database.

3. **Constant-Time Comparison** – The provided secret is compared against the stored hash using a constant-time comparison to prevent timing attacks.

4. **Token Rotation** – Upon successful validation, `RegenerateAuthToken` creates a new token secret and invalidates the old one. This one-time-use property ensures that stolen tokens cannot be reused by attackers.

## Session Management and User Context

After successful authentication, [`services/auth/auth.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/auth.go) executes `handleSignIn` to establish the user session:

```go
newSess, err := session.RegenerateSession(resp, req)
sess = newSess
sess.Set("uid", user.ID)
sess.Set("uname", user.Name)

```

This function regenerates the session ID to prevent session fixation attacks, stores the user ID and username in the session, sets the user's preferred locale, and clears any stale OpenID or two-factor authentication keys from the context.

## Summary

- **Path Detection** – The `authPathDetector` in [`services/auth/auth.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/auth.go) filters requests to apply authentication only to API, Git, feed, and attachment endpoints.
- **Modular Methods** – All authentication strategies implement the `auth.Method` interface with a `Verify` method that returns a user model.
- **Basic Auth** – Supports both username/password and token authentication via `Authorization` headers, with fallback logic in [`services/auth/basic.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/basic.go).
- **OAuth2 Flow** – Handles Bearer tokens, JWT access tokens, and action-specific tokens through [`services/auth/oauth2.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/oauth2.go).
- **Security Features** – Remember-me tokens use one-time rotation via `RegenerateAuthToken`, and sessions are regenerated upon login to prevent fixation attacks.

## Frequently Asked Questions

### How does Gitea decide which authentication method to use for a request?

Gitea iterates through all registered `auth.Method` implementations in order. Each method's `Verify` function attempts to extract and validate credentials from the request. The first method that successfully returns a `*user_model.User` without an error establishes the authentication context. This occurs only after the `authPathDetector` confirms the request path requires authentication.

### What is the difference between personal access tokens and OAuth2 tokens in Gitea?

Personal access tokens are opaque SHA256 hashes stored in the database and validated via `auth_model.GetAccessTokenBySHA`. OAuth2 tokens are JWTs signed by the Gitea instance, parsed through `oauth2_provider.ParseToken`, and linked to `OAuth2Grant` records. The `OAuth2` auth method handles both types, attempting JWT parsing first before falling back to the personal access token lookup.

### How does the "remember me" feature maintain security?

The remember-me system stores a token pair (`id:rawToken`) in a cookie. On each use, `CheckAuthToken` validates the token against the database using constant-time comparison. Crucially, `RegenerateAuthToken` creates a new token secret after each successful validation, invalidating the previous one. This rotation ensures that stolen cookies cannot be reused if intercepted.

### Can Gitea authentication methods be chained or combined?

Yes, Gitea supports group-based authentication through [`services/auth/group.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/group.go), which allows multiple sources (such as LDAP, SMTP, or reverse proxy headers) to be checked in sequence. Additionally, the SSPI method ([`services/auth/sspi.go`](https://github.com/go-gitea/gitea/blob/main/services/auth/sspi.go)) integrates with Windows authentication for Kerberos/NTLM scenarios, demonstrating how the modular interface supports complex enterprise authentication requirements.