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 cookiesisAttachmentDownload()– Direct/attachments/…GET requestsisGitRawOrAttachOrLFSPath()– Git operations and LFS raw filesisArchivePath()– 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(services/auth/basic.go) – HTTP Basic auth and x-oauth-basic token validationOAuth2(services/auth/oauth2.go) – OAuth 2 access tokens via query parameters or Bearer headersHTTPSign(services/auth/httpsign.go) – HMAC-signed requests for package registry operations- Group and SSPI (
services/auth/group.go,services/auth/sspi.go) – SSO integrations including Kerberos and LDAP
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
-
Header Parsing –
Basic.parseAuthBasicextracts theAuthorizationheader orx-oauth-basictoken from the request. -
Token Validation – If the credential resembles a personal access token or OAuth token,
Basic.VerifyAuthTokenvalidates it against the database usingauth_model.GetAccessTokenBySHAor callsGetOAuthAccessTokenScopeAndUserIDfor JWT access tokens. -
Fallback Authentication – When token validation fails and
setting.Service.EnableBasicAuthis true, the system falls back to username/password authentication viaUserSignIn. -
Security Checks – Two-factor authentication and WebAuthn verification occur before session creation.
-
Context Storage – Upon success, the user object is stored in the request's
DataStorewithLoginMethod = "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 (
tokenoraccess_token) Authorization: Bearer …headers- Action-specific JWT tokens
The OAuth2.userFromToken function distinguishes between token types:
-
Action JWTs – Tokens containing a dot (
.) are processed byactions.TokenToTaskIDand converted to a temporary user viaNewActionsUserWithTaskID. -
OAuth2 Access Tokens – Standard JWTs are parsed via
oauth2_provider.ParseToken, linked to anOAuth2Grant, and validated throughGetOAuthAccessTokenScopeAndUserID. -
Personal Access Tokens – If JWT parsing fails, the system falls back to
auth_model.GetAccessTokenBySHAfor 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.
Remember-Me Cookie Authentication
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:
-
Extraction –
CheckAuthTokensplits the cookie value to separate the token ID from the raw secret. -
Database Lookup – The system fetches the corresponding
AuthTokenrow from the database. -
Constant-Time Comparison – The provided secret is compared against the stored hash using a constant-time comparison to prevent timing attacks.
-
Token Rotation – Upon successful validation,
RegenerateAuthTokencreates 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
authPathDetectorinservices/auth/auth.gofilters requests to apply authentication only to API, Git, feed, and attachment endpoints. - Modular Methods – All authentication strategies implement the
auth.Methodinterface with aVerifymethod that returns a user model. - Basic Auth – Supports both username/password and token authentication via
Authorizationheaders, with fallback logic inservices/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →