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

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, 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. This abstraction allows the system to chain multiple validation techniques through a common contract.

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 Authentication Implementation

The Basic method in services/auth/basic.go handles username/password credentials and token-based authentication through HTTP Basic headers.

Token and Password Validation Flow

  1. Header ParsingBasic.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:

git clone https://username:[email protected]/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 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

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.

For persistent web sessions, Gitea implements a secure token-based "remember me" system in 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. ExtractionCheckAuthToken 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 executes handleSignIn to establish the user session:

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 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.
  • OAuth2 Flow – Handles Bearer tokens, JWT access tokens, and action-specific tokens through 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, 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) integrates with Windows authentication for Kerberos/NTLM scenarios, demonstrating how the modular interface supports complex enterprise authentication requirements.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →