go-auth
Guides

Protect application routes

A complete browser security wrapper for your own HTTP endpoints.

Protect application routes

Use Auth.Protect(pattern, handler) for authenticated application endpoints. It composes the configured rate limiter, mandatory signed double-submit and Origin/Referer checks, session authentication (including transparent refresh), and current email-verification policy. It also supplies CORS headers.

mux := http.NewServeMux()
auth.Mount(mux)

pattern := "POST /widgets/{id}/publish"
mux.Handle(pattern, auth.Protect(pattern, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    user := middleware.GetUserFromContext(r.Context())
    widgetID := r.PathValue("id")
    // Check ownership in your application before writing this user's widget.
    _ = user
    _ = widgetID
    w.WriteHeader(http.StatusNoContent)
})))

// Preflight must run before the mux selects a method-specific route.
server := &http.Server{Addr: ":8080", Handler: auth.CORS(mux)}

Import github.com/nazimdjebloun/go-auth/middleware for context access. Protect establishes identity; it cannot infer ownership of application data. The WithRateLimitRoute key uses the same pattern if a custom rate is needed. Without an override, the configured fallback rate applies. Explicitly disabled rate limits and configured exemptions are respected.

Authorization runs after authentication

pattern := "POST /reports/{id}/publish"
mux.Handle(pattern, auth.Protect(pattern,
    auth.RequireAppPermission("reports.publish")(publishReport)))

pattern = "GET /private-admin"
mux.Handle(pattern, auth.Protect(pattern, auth.RequireAdmin(adminPage)))

pattern = "POST /orgs/{orgID}/widgets"
mux.Handle(pattern, auth.ProtectOrgScope(pattern, "org.widgets.create",
    func(w http.ResponseWriter, r *http.Request, scope goauth.OrgScope) {
        // Pass scope into the repository; every query must include scope.OrgID.
        w.WriteHeader(http.StatusNoContent)
    }))

Permission and organization features must be enabled and provisioned as documented in their guides. The wrappers retain their existing live checks; Protect does not grant a role or permission. Include the authenticated user and organization in application queries rather than trusting IDs in JSON.

ProtectActiveOrgScope(pattern, key, handler) instead selects the authenticated session's active organization. Both helpers check live membership, permission role and grants, and supply the fixed owner/admin/member classification as scope.Role. A custom permission role is represented by the member classification; it does not become an owner or admin. Incomplete scope fails with 500 before the application handler runs.

For applications intentionally using fixed roles, compose auth.Protect(pattern, auth.RequireOrgScope(domain.OrgRoleMember, handler)) or RequireActiveOrgScope. Repeated authentication from the same Auth instance reuses the successful result while credentials, selected session context and identity remain unchanged. Separate requests and separate instances authenticate independently; public context setters do not bypass authentication.

Route helper reference

Protect is the complete browser route wrapper. RequireAuth is one layer: it validates the selected session, refreshes expired access credentials when possible, loads user/session context and enforces email verification. It adds no CORS, CSRF, origin or rate-limit protection and grants no application or org permission. Prefer Protect or its scoped variants for browser endpoints.

Helper on *AuthWhat it does
Protect(pattern, handler)Complete browser chain plus route matching, Pattern and path parameters. Add resource authorization inside it.
ProtectOrgScope(pattern, key, handler)Complete chain plus a live org permission check for {orgID}; passes OrgScope.
ProtectActiveOrgScope(pattern, key, handler)Complete chain plus a live permission check for the session's active org; passes OrgScope.
RequireAuth(handler)Session authentication, transparent refresh, identity context and email verification.
RequireAdmin(handler)Current app-admin authorization and required second-factor assurance; run after authentication.
RequireAppPermission(key)(handler)Live application permission check; run after authentication.
RequireOrgPermission(key)(handler)Live org permission check using {orgID}, then authorized org context; stores org ID and membership role. Run after authentication.
RequireActiveOrgPermission(key)(handler)Live org permission check using the session's active org ID; stores the live ID/role. Run after authentication.
RequireOrg(role)(handler)Membership plus minimum fixed role; reads {orgID}, falling back to org_id query. Run after authentication.
RequireActiveOrg(role)(handler)Active-session org and minimum fixed role; run after authentication.
RequireOrgScope(role, handler)Authentication plus fixed-role org checks; passes OrgScope. Add Protect for browser protections.
RequireActiveOrgScope(role, handler)Same fixed-role scope adapter for the session's active org.
RequireOrgPermissionScope(key, handler)Authentication plus live org permission checks; passes OrgScope. Prefer ProtectOrgScope for browser routes.
RequireActiveOrgPermissionScope(key, handler)Same permission scope adapter for the active org. Prefer ProtectActiveOrgScope for browser routes.
RequireCSRF(handler)Signed double-submit CSRF and Origin/Referer checks.
CORS(handler)Configured origin/credential headers and preflight handling; place outside a method-based router for application preflights.
RateLimit(handler)Configured limiter using the router's route pattern.
RateLimitWithPattern(pattern)(handler)Configured limiter with an explicit, validated pattern for custom routers.
Mount(mux)Registers enabled built-in auth routes and their middleware.
Handler(pattern)Looks up an enabled built-in wrapped handler; custom routers must populate its path parameters.
SetSessionCookies(w, r, sessionID, sessionToken, refreshToken)Issues credentials and session-bound CSRF protection after trusted session creation.
ClearSessionCookies(w, r)Clears browser credentials and issues anonymous CSRF protection; revoke the session first.
RotateCSRFToken(w, r)Replaces request CSRF protection; credential cookie helpers already rotate it.

middleware.GetUserFromContext, GetSessionFromContext, GetOrgID and GetOrgRole read values established by preceding middleware. Missing values return nil or the zero value; getters do not authorize or validate scope. For tenant-owned data, accept OrgScope and pass it explicitly to repositories.

Client flow and failures

First call GET /auth/csrf-token with credentials, then send its token as X-CSRF-Token on mutations, with credentials. Honor replacement tokens in the same response header. Keep X-GoAuth-Session: admin on every request from an independent admin client; the ordinary application uses the app context.

SituationResult
Missing, expired, or revoked credentials401; display sign-in.
Valid session whose email now requires verification403 email_not_verified; display verification, then retry using that session.
Missing/invalid double-submit token or denied Origin/Referer403 CSRF error; the business handler does not run.
Valid identity without the requested authorizationThe inner authorization wrapper's error, usually 403.
Rate budget exhausted429 with Retry-After.
Request outside the declared route404 before rate accounting.

Verification, sign-in and logout retain their built-in route policies. Do not wrap Auth.Mount routes in Protect: authentication and verification endpoints must remain reachable before the caller has full application access.

Patterns use Go ServeMux syntax. Invalid patterns or a nil handler panic during setup. On third-party routers, adapt the returned http.Handler normally and ensure OPTIONS reaches it, or put auth.CORS around the complete router. Request.Pattern and PathValue are populated by the wrapper even if the outer router does not supply them. Existing low-level middleware stays available for custom transport arrangements.

On this page