Help us shape the future of Go! Take the 2026 Go Developer Survey

auth

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

README

auth

CI unit tests e2e tests coverage Go Reference License

Coding agents: start at llms.txt and docs/wiki/Home.md; runnable servers are in examples/.

What it is

One Go library for login and access control: password, OIDC (incl. Keycloak) and GitHub login, server-side sessions, authorization checks, JWT and API keys, plus a forward-auth image for Traefik. Every provider produces the same auth.Identity in the request context; for password, OIDC and GitHub logins one session.Guard puts it there from a server-side session. It replaces mxcd/go-basicauth, mxcd/oidc-fwd-auth and mxcd/github-fwd-auth (migration guide).

Features

  • Password login with Argon2id, TOTP with backup codes, optional registration, bcrypt upgrade; users stay in your database.
  • OIDC code flow with PKCE and nonce, RP-initiated and front-channel logout, Keycloak Admin API enrichment, Google.
  • GitHub OAuth with allowed, admin and relevant teams, re-checked every minute.
  • Server-side sessions (memory or Redis), the cookie holds a random ID only.
  • Authorization checks over roles, groups, teams and resource permissions (builds:write), composable with All, Any, Not.
  • API keys, RS512 JWT signing and verification.
  • net/http core; gin, wide events and Prometheus in adapter packages. No logging, no goroutines.

Install

go get github.com/govengers/auth@v1

Quick start

Provider, Guard and routes, from examples/password/main.go:

	provider, err := password.New(&password.Options{
		Sessions:           store,
		Storage:            options.Storage,
		EnableRegistration: true,                                                   // POST /auth/password/register: open sign-up for the demo
		TOTP:               password.TOTPOptions{Enabled: true, Issuer: "Example"}, // optional second factor
		OnLogin:            grantRoles(options.AdministratorID),
	})
	if err != nil {
		return nil, err
	}
	guard, err := session.NewGuard(&session.GuardOptions{
		Store:      store,
		LoginURL:   "/login",                      // where RequireUI sends anonymous browsers
		Refreshers: []session.Refresher{provider}, // a deleted user loses access within a minute
	})
	if err != nil {
		return nil, err
	}

	serveMux := http.NewServeMux()
	auth.RegisterRoutes(serveMux, provider.Routes()) // the provider reads the session itself: no Guard in front
	serveMux.Handle("GET /auth/me", guard.RequireAPI()(auth.IdentityHandler()))
	serveMux.Handle("GET /api/notes", guard.RequireAPI()(http.HandlerFunc(listNotes)))
	serveMux.Handle("DELETE /api/notes", guard.RequireAPI()(authorize(authorization.IsAdmin())(http.HandlerFunc(deleteNotes))))
	serveMux.Handle("GET /{$}", guard.RequireUI()(http.HandlerFunc(home)))

Complete, tested servers: password, OIDC with Keycloak, GitHub on gin.

Packages

Package Purpose
auth Identity, Permission, context helpers, Error and the JSON error shape, Observer, Hook, Route
session server-side sessions: Store, Guard (RequireAPI, RequireUI), memory backend, refresh
session/redisbackend session backend on Redis, shared by replicas
password password login, TOTP, registration; you implement Storage
oidc OIDC login and logout
oidc/keycloak Keycloak Admin API enrichment as an OnLogin hook
github GitHub OAuth with teams and an API client for the user
apikey static and application-issued API keys
jwt RS512 Signer with JWKS, Verifier with middleware
authorization Check primitives and combinators
ginadapter net/http middleware and routes on gin, Require, wide-event Observe, RedactQuery
prometheusadapter outcome counter on your Prometheus registry
cmd/forwardauth the forward-auth binary

Forward-auth image

ghcr.io/govengers/forwardauth runs one OIDC or GitHub provider in front of any app behind Traefik, without code in the app. It answers Traefik's forwardAuth checks and can pass the identity on as a signed JWT, which Go backends verify with jwt.Verifier. Overview: docs/wiki/Forward-Auth.md; compose, TLS and Kubernetes wiring and every environment variable: docs/wiki/Forward-Auth-Configuration.md.

Documentation

Releases and changelog: GitHub Releases.

Security

Guarantees and known limits (no rate limiting, among others): docs/wiki/Security.md.

Contributing

just check runs lint, unit tests with -race and an 80 % coverage gate (total and per package), both end-to-end suites and govulncheck; just docker-build builds the image. Code follows the govengers standards with the library profile (.govengers.yml; one waived rule, DES-008, reason in the file); reviewers also apply the service rules (CFG, LAY, LOG, MET, DEP, API-001, API-002) to cmd/forwardauth and internal/forwardauth. CI, image and e2e details: docs/infrastructure-notes.md. docs/wiki is the source of the GitHub wiki; just wiki mirrors it after a docs change. Releases: push a vX.Y.Z tag; the release workflow publishes the image. After the very first push the GHCR package must be made public once by hand (package settings; there is no API for it).

License

Apache 2.0

Documentation

Overview

Package auth holds what every provider of the module shares: the Identity a request acts as, the context helpers that carry it, the refusal errors with their one JSON response shape, the outcomes providers report to an optional Observer, the login and logout hook types, and the Route type providers return their endpoints as.

The package works on net/http and context.Context only, never logs and never starts goroutines. Its functions and handlers are safe for concurrent use; an Identity is shared read-only or cloned.

Example (ApplicationUser)

Example_applicationUser replaces go-basicauth's UserTransformer: an OnLogin hook provisions the application user, and a middleware after the Guard loads it per request.

package main

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/google/uuid"

	"github.com/govengers/auth"
)

// User is the application's own user record; UserRepository stands in for its table.
type User struct {
	ID     uuid.UUID
	Name   string
	Active bool
}

type UserRepository map[uuid.UUID]*User

var errUserNotFound = errors.New("user not found")

// ByID returns the user with id.
func (users UserRepository) ByID(_ context.Context, id uuid.UUID) (*User, error) {
	user, found := users[id]
	if !found {
		return nil, errUserNotFound
	}
	return user, nil
}

type userKey struct{}

// WithUser loads the application user of the authenticated identity and refuses inactive users. Mount it
// after the Guard.
func WithUser(users UserRepository) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
			identity := auth.IdentityFrom(request.Context())
			if identity == nil {
				auth.WriteError(writer, &auth.Error{Kind: auth.ErrUnauthenticated})
				return
			}
			user, err := users.ByID(request.Context(), identity.UserID)
			if err != nil {
				auth.WriteError(writer, err) // plain errors answer 500
				return
			}
			if !user.Active {
				auth.WriteError(writer, &auth.Error{Kind: auth.ErrForbidden, Reason: "inactive user"})
				return
			}
			next.ServeHTTP(writer, request.WithContext(context.WithValue(request.Context(), userKey{}, user)))
		})
	}
}

// UserFrom returns the user WithUser stored, or nil.
func UserFrom(ctx context.Context) *User {
	user, _ := ctx.Value(userKey{}).(*User)
	return user
}

// provisionHook is the OnLogin hook of an OIDC or GitHub provider: it finds or creates the application
// user and returns a copy of the identity carrying its ID.
func provisionHook(users UserRepository) auth.Hook {
	return func(_ context.Context, identity *auth.Identity) (*auth.Identity, error) {
		provisioned := identity.Clone() // hooks must not mutate their argument
		provisioned.UserID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(identity.Provider+"/"+identity.Subject))
		if _, found := users[provisioned.UserID]; !found {
			users[provisioned.UserID] = &User{ID: provisioned.UserID, Name: identity.Username, Active: true}
		}
		return provisioned, nil
	}
}

// Example_applicationUser replaces go-basicauth's UserTransformer: an OnLogin hook provisions the
// application user, and a middleware after the Guard loads it per request.
func main() {
	users := UserRepository{}
	identity, err := provisionHook(users)(context.Background(), &auth.Identity{Provider: "keycloak", Subject: "user-1", Username: "ada", Active: true})
	if err != nil {
		fmt.Println(err)
		return
	}
	profile := WithUser(users)(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		_, _ = fmt.Fprintln(writer, "hello", UserFrom(request.Context()).Name) // the recorder never fails a write
	}))

	for _, active := range []bool{true, false} {
		users[identity.UserID].Active = active
		// the Guard puts the session's identity into the context; WithIdentity stands in for it here
		request := httptest.NewRequestWithContext(auth.WithIdentity(context.Background(), identity), http.MethodGet, "/profile", nil)
		recorder := httptest.NewRecorder()
		profile.ServeHTTP(recorder, request)
		fmt.Print(recorder.Code, " ", recorder.Body.String())
	}
}
Output:
200 hello ada
403 {"code":"forbidden","message":"access denied"}

Index

Examples

Constants

View Source
const (
	ProviderPassword = "password"
	ProviderGitHub   = "github"
	ProviderAPIKey   = "apikey"
	ProviderJWT      = "jwt"     // a JWT verifier's outcomes; its identities keep the provider they were signed for
	ProviderSession  = "session" // the Guard's outcomes when it finds no identity
)

The fixed provider names (Identity.Provider, Outcome.Provider); an OIDC provider uses its own Name, which must not be one of them.

View Source
const AllResources = "*"

AllResources is the Permission resource that matches every resource.

View Source
const ReasonInactive = "inactive"

ReasonInactive is the Reason of the ErrForbidden refusal of an inactive identity, shared by every authorization check and jwt.Signer.Sign.

View Source
const RoleAdmin = "admin"

RoleAdmin is the application role that authorization.IsAdmin requires. The GitHub provider grants it to AdminTeams members.

Variables

View Source
var (
	ErrUnauthenticated = errors.New("unauthenticated") // 401
	ErrForbidden       = errors.New("forbidden")       // 403
	ErrInvalidRequest  = errors.New("invalid request") // 400
	ErrConflict        = errors.New("conflict")        // 409
)

The four kinds of refusal. Callers branch on them with errors.Is; ResponseFor maps each to its status.

Functions

func IdentityHandler

func IdentityHandler() http.Handler

IdentityHandler answers 200 with the IdentityResponse of the identity in the request context and 401 without one. Mount it behind a Guard (recommended path "/auth/me"). It is safe for concurrent use.

Example
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/govengers/auth"
)

func main() {
	serveMux := http.NewServeMux()
	auth.RegisterRoutes(serveMux, []auth.Route{
		{Method: http.MethodGet, Path: "/auth/me", Handler: auth.IdentityHandler()},
	})
	ctx := auth.WithIdentity(context.Background(), &auth.Identity{Provider: "github", Subject: "42", Active: true})
	request := httptest.NewRequestWithContext(ctx, http.MethodGet, "/auth/me", nil)
	recorder := httptest.NewRecorder()

	serveMux.ServeHTTP(recorder, request)

	fmt.Print(recorder.Code, " ", recorder.Body.String())
}
Output:
200 {"provider":"github","subject":"42","active":true,"roles":[]}

func RegisterRoutes

func RegisterRoutes(serveMux *http.ServeMux, routes []Route)

RegisterRoutes registers each route on serveMux as the Go 1.22 pattern "<Method> <Path>". Like http.ServeMux.Handle it panics on a pattern that conflicts with one already registered, which is a wiring mistake at startup.

func WithIdentity

func WithIdentity(ctx context.Context, identity *Identity) context.Context

WithIdentity returns a copy of ctx carrying identity.

func WriteError

func WriteError(writer http.ResponseWriter, err error)

WriteError writes ResponseFor(err) as JSON with Cache-Control: no-store.

Types

type Access

type Access string

Access is what a Permission allows on its resource. AccessWrite includes AccessRead.

const (
	AccessRead  Access = "read"
	AccessWrite Access = "write"
)

The closed set of access levels.

func AccessForMethod

func AccessForMethod(method string) Access

AccessForMethod returns the access an HTTP method needs: AccessRead for GET, HEAD and OPTIONS, AccessWrite for every other method.

type Action

type Action string

Action names what a provider was asked to do.

const (
	ActionLogin              Action = "login" // redirect start (oidc, github) or credential check (password)
	ActionCallback           Action = "callback"
	ActionLogout             Action = "logout"
	ActionFrontChannelLogout Action = "frontchannel_logout"
	ActionRegister           Action = "register"
	ActionTOTPVerify         Action = "totp_verify"
	ActionTOTPStatus         Action = "totp_status" // password GET {prefix}/totp
	ActionTOTPSetup          Action = "totp_setup"
	ActionTOTPEnable         Action = "totp_enable"
	ActionTOTPDisable        Action = "totp_disable"
	ActionRefreshTeams       Action = "refresh_teams"       // github route
	ActionAuthenticate       Action = "authenticate"        // per request: Guard, apikey, jwt verifier
	ActionRefresh            Action = "refresh"             // Guard calling a Refresher
	ActionImpersonationStart Action = "impersonation_start" // session.Impersonator; Identity is the impersonating one on success
	ActionImpersonationStop  Action = "impersonation_stop"
)

The actions providers report.

type Error

type Error struct {
	Kind   error
	Code   string
	Reason string
	Err    error
}

Error is a refusal. Kind is one of the four sentinels; Code is the stable client-facing code (empty means the Kind's default code); Reason is server-side detail for the wide event and is never sent to a client (it may name a missing role); Err is an optional cause.

func (*Error) Error

func (e *Error) Error() string

Error returns "<kind>[: <code>][: <reason>][: <cause>]".

func (*Error) Unwrap

func (e *Error) Unwrap() []error

Unwrap returns the non-nil of Kind and Err, so errors.Is(err, ErrForbidden) matches.

type ErrorResponse

type ErrorResponse struct {
	Code    string `json:"code"`
	Message string `json:"message"` // fixed per kind, safe to show; never err.Error()
}

ErrorResponse is the one JSON error shape of every library response.

func ResponseFor

func ResponseFor(err error) (int, ErrorResponse)

ResponseFor maps an error to its status and body. The Kind of the outermost *Error decides status and message, its Code replaces the default code; a bare sentinel maps by errors.Is; anything else is a 500 with code "internal". Reason and causes never reach the body.

Example
package main

import (
	"fmt"

	"github.com/govengers/auth"
)

func main() {
	refusal := &auth.Error{Kind: auth.ErrForbidden, Reason: "missing role admin"}

	status, response := auth.ResponseFor(fmt.Errorf("open report: %w", refusal))

	fmt.Println(status, response.Code, response.Message)
}
Output:
403 forbidden access denied

type Hook

type Hook func(ctx context.Context, identity *Identity) (*Identity, error)

Hook maps an identity. OnLogin hooks run after the provider authenticated the user and before a session exists: the returned identity is stored; an error aborts the login (an *Error answers with its status, anything else 500; providers wrap it with %w, so the kind survives) and no session is created; a nil identity without error is a failure (500). Hooks must not mutate the argument; return identity.Clone() with changes. Providers may call a hook from concurrent requests.

type Identity

type Identity struct {
	Provider        string              `json:"provider"`           // provider instance: "password", "github", "apikey" or an OIDC provider Name; a verified JWT keeps the provider it was signed for
	Subject         string              `json:"subject"`            // stable ID at the provider: OIDC sub, GitHub numeric user ID, password user UUID, API key name
	UserID          uuid.UUID           `json:"userId"`             // application user ID; uuid.Nil until the password provider or an OnLogin hook sets it
	Username        string              `json:"username,omitempty"` // preferred_username, GitHub login, password username, API key name
	Name            string              `json:"name,omitempty"`
	Email           string              `json:"email,omitempty"`
	Picture         string              `json:"picture,omitempty"`         // OIDC picture claim, GitHub avatar_url
	Active          bool                `json:"active"`                    // providers set true at login; hooks may set false
	Roles           []string            `json:"roles,omitempty"`           // application roles (RoleAdmin)
	OIDCRoles       []string            `json:"oidcRoles,omitempty"`       // Keycloak realm roles
	OIDCClientRoles []string            `json:"oidcClientRoles,omitempty"` // Keycloak client roles of the configured client
	Groups          []string            `json:"groups,omitempty"`          // OIDC groups (path or name, per IdP mapper)
	Teams           []string            `json:"teams,omitempty"`           // GitHub "org/team-slug", lower-case
	Permissions     []Permission        `json:"permissions,omitempty"`     // resource permissions, text form in JSON ("builds:write"); from API keys, JWTs or hooks
	Attributes      map[string][]string `json:"attributes,omitempty"`      // Keycloak user attributes
	Claims          map[string]any      `json:"claims,omitempty"`          // OIDC ID token claims, or all claims of a verified JWT
	Data            map[string]any      `json:"data,omitempty"`            // application data from hooks and resolvers; JSON round trip (numbers become float64)
	Impersonator    *Identity           `json:"impersonator,omitempty"`    // the real identity while it impersonates this one; nil otherwise
}

Identity is who a request acts as, whichever provider authenticated it. It is a value type: providers build it, hooks may return a modified copy, the session stores it as JSON (the tags are a persistence format; never rename them). An Identity is not synchronized: share it read-only, or Clone it.

func IdentityFrom

func IdentityFrom(ctx context.Context) *Identity

IdentityFrom returns the identity in ctx, or nil.

Example
package main

import (
	"context"
	"fmt"

	"github.com/govengers/auth"
)

func main() {
	identity := &auth.Identity{Provider: "password", Subject: "ada", Active: true}

	ctx := auth.WithIdentity(context.Background(), identity)

	fmt.Println(auth.IdentityFrom(ctx).Subject)
}
Output:
ada

func (*Identity) Clone

func (i *Identity) Clone() *Identity

Clone returns a deep copy: slices (Permissions included), Attributes and the Impersonator chain are copied; Claims and Data are copied one level (values shared). Nil-safe.

Example
package main

import (
	"fmt"

	"github.com/govengers/auth"
)

func main() {
	identity := &auth.Identity{Provider: "github", Subject: "42", Roles: []string{"reader"}}

	promoted := identity.Clone()
	promoted.Roles = append(promoted.Roles, auth.RoleAdmin)

	fmt.Println(identity.Roles, promoted.Roles)
}
Output:
[reader] [reader admin]

func (*Identity) Permits

func (i *Identity) Permits(resource string, access Access) bool

Permits reports whether one of the identity's Permissions grants access on resource. It looks at Permissions only (not Active, not the Impersonator) and is false for a nil identity.

func (*Identity) Real

func (i *Identity) Real() *Identity

Real returns the identity that authenticated: the Impersonator while impersonating, the receiver otherwise. Nil-safe (nil in, nil out).

type IdentityResponse

type IdentityResponse struct {
	Provider        string            `json:"provider"`
	Subject         string            `json:"subject"`
	UserID          string            `json:"userId,omitempty"` // empty for uuid.Nil
	Username        string            `json:"username,omitempty"`
	Name            string            `json:"name,omitempty"`
	Email           string            `json:"email,omitempty"`
	Picture         string            `json:"picture,omitempty"`
	Active          bool              `json:"active"`
	Roles           []string          `json:"roles"` // never null
	OIDCRoles       []string          `json:"oidcRoles,omitempty"`
	OIDCClientRoles []string          `json:"oidcClientRoles,omitempty"`
	Groups          []string          `json:"groups,omitempty"`
	Teams           []string          `json:"teams,omitempty"`
	Permissions     []Permission      `json:"permissions,omitempty"` // text form: ["builds:write"]
	Impersonator    *IdentityResponse `json:"impersonator,omitempty"`
}

IdentityResponse is the public view of an Identity: Claims, Attributes and Data are never exposed.

func NewIdentityResponse

func NewIdentityResponse(identity *Identity) IdentityResponse

NewIdentityResponse returns the public view of identity, sharing no slice with it. A nil identity gives an empty view.

type LogoutHook

type LogoutHook func(ctx context.Context, identity *Identity)

LogoutHook runs after a session was ended (all providers, RP-initiated and front-channel logout). It cannot fail the logout and has no access to the response. Providers may call it from concurrent requests.

type Observer

type Observer func(ctx context.Context, outcome Outcome)

Observer receives outcomes synchronously, at most once per action per request, with the request context. It must not block and must be safe for concurrent use. nil Observer options mean no reporting.

type Outcome

type Outcome struct {
	Provider string // provider instance name; "session" when the Guard finds no identity
	Action   Action
	Result   Result
	Err      error
	Identity *Identity // the identity concerned, nil when unknown
}

Outcome is one authentication decision. Err is the refusal for denied, the failure for error, and a handled failure for a degraded success (e.g. GitHub token revocation failed, legacy hash upgrade failed).

type Permission

type Permission struct {
	Resource string
	Access   Access
}

Permission grants Access on one resource, or on every resource when Resource is AllResources. Its text form "<resource>:<access>" (e.g. "builds:write", "*:read") is also its JSON form.

func ParsePermission

func ParsePermission(text string) (Permission, error)

ParsePermission parses the text form "<resource>:<access>". Both parts are case-sensitive: the resource is AllResources or matches [a-z0-9][a-z0-9._-]{0,63}, the access is "read" or "write".

Example
package main

import (
	"fmt"
	"net/http"

	"github.com/govengers/auth"
)

func main() {
	permission, err := auth.ParsePermission("builds:write")
	if err != nil {
		fmt.Println(err)
		return
	}

	identity := &auth.Identity{Provider: "apikey", Subject: "ci", Active: true, Permissions: []auth.Permission{permission}}

	fmt.Println(permission.Grants("builds", auth.AccessRead), identity.Permits("deployments", auth.AccessRead))
	fmt.Println(auth.AccessForMethod(http.MethodDelete))
}
Output:
true false
write

func (Permission) Grants

func (p Permission) Grants(resource string, access Access) bool

Grants reports whether the permission grants access on resource: the resource matches exactly or the permission covers AllResources, and AccessWrite includes AccessRead. An invalid permission, an empty or invalid resource, or an access other than read or write grants nothing. This is the only place the matching rule lives.

func (Permission) MarshalText

func (p Permission) MarshalText() ([]byte, error)

MarshalText encodes the text form; an invalid permission is an error.

func (Permission) String

func (p Permission) String() string

String returns the text form "<resource>:<access>".

func (*Permission) UnmarshalText

func (p *Permission) UnmarshalText(text []byte) error

UnmarshalText decodes the text form with ParsePermission.

func (Permission) Validate

func (p Permission) Validate() error

Validate reports whether the permission has a valid resource and access.

type Result

type Result string

Result is how an action ended.

const (
	ResultSuccess   Result = "success"
	ResultChallenge Result = "challenge" // password step done, second factor or enrollment pending
	ResultDenied    Result = "denied"    // a refusal (*Error) was answered
	ResultError     Result = "error"     // an internal failure was answered (500)
)

The results of an action.

type Route

type Route struct {
	Method  string
	Path    string
	Handler http.Handler
}

Route is one endpoint a provider serves. Path is absolute from the server root and includes the provider prefix.

Directories

Path Synopsis
Package apikey authenticates requests that present an API key, independent of any login provider.
Package apikey authenticates requests that present an API key, independent of any login provider.
Package authorization decides whether the identity in a request context may proceed.
Package authorization decides whether the identity in a request context may proceed.
cmd
forwardauth command
Command forwardauth is the forward-auth server for Traefik: it authenticates browsers through one OIDC or GitHub provider into a server-side session, accepts static API keys, and answers Traefik's forwardAuth checks with 200 and, optionally, the identity as a signed JWT for the upstream service.
Command forwardauth is the forward-auth server for Traefik: it authenticates browsers through one OIDC or GitHub provider into a server-side session, accepts static API keys, and answers Traefik's forwardAuth checks with 200 and, optionally, the identity as a signed JWT for the upstream service.
examples
github command
Command github is a minimal gin server with GitHub OAuth login and team checks: sessions in memory, a JSON API behind session.Guard.RequireAPI, a page behind RequireUI that starts the login, an admin-only route for AdminTeams members, logout, and outcomes recorded on the request's wide event.
Command github is a minimal gin server with GitHub OAuth login and team checks: sessions in memory, a JSON API behind session.Guard.RequireAPI, a page behind RequireUI that starts the login, an admin-only route for AdminTeams members, logout, and outcomes recorded on the request's wide event.
oidc command
Command oidc is a minimal server with OpenID Connect login (net/http), optionally enriched from the Keycloak Admin API: sessions in memory, a JSON API behind session.Guard.RequireAPI, a page behind RequireUI that starts the login, a route for one realm role, and logout at the IdP. Register <EXTERNAL_URL>/auth/oidc/sso/callback as redirect URI at the IdP. Replace the memory session backend with redisbackend before you run more than one replica.
Command oidc is a minimal server with OpenID Connect login (net/http), optionally enriched from the Keycloak Admin API: sessions in memory, a JSON API behind session.Guard.RequireAPI, a page behind RequireUI that starts the login, a route for one realm role, and logout at the IdP. Register <EXTERNAL_URL>/auth/oidc/sso/callback as redirect URI at the IdP. Replace the memory session backend with redisbackend before you run more than one replica.
password command
Command password is a minimal server with password login (net/http): users in password.MemoryStorage, sessions in memory, a JSON API behind session.Guard.RequireAPI, a page behind RequireUI, an admin-only route and logout.
Command password is a minimal server with password login (net/http): users in password.MemoryStorage, sessions in memory, a JSON API behind session.Guard.RequireAPI, a page behind RequireUI, an admin-only route and logout.
Package ginadapter integrates the module with gin and the wide-event logger: it runs the net/http middleware of the providers in a gin chain, registers their routes on a gin router, gates routes with authorization checks, and records authentication outcomes on the request's wide event.
Package ginadapter integrates the module with gin and the wide-event logger: it runs the net/http middleware of the providers in a gin chain, registers their routes on a gin router, gates routes with authorization checks, and records authentication outcomes on the request's wide event.
Package github is the GitHub OAuth provider: login with PKCE (S256) and a state bound to the server-side session, team checks (AllowedTeams, AdminTeams, RelevantTeams), logout with best-effort token revocation, a team refresh route, a session.Refresher and session.Revoker, and an HTTP client that calls the GitHub API with the session's token.
Package github is the GitHub OAuth provider: login with PKCE (S256) and a state bound to the server-side session, team checks (AllowedTeams, AdminTeams, RelevantTeams), logout with best-effort token revocation, a team refresh route, a session.Refresher and session.Revoker, and an HTTP client that calls the GitHub API with the session's token.
internal
backendtest
Package backendtest is the conformance suite every session.Backend implementation of the module runs in its tests: put, get, pop, compare and swap, revoke, per-value TTLs, revocation markers, atomic Pop and CompareAndSwap, and revocation racing a Put.
Package backendtest is the conformance suite every session.Backend implementation of the module runs in its tests: put, get, pop, compare and swap, revoke, per-value TTLs, revocation markers, atomic Pop and CompareAndSwap, and revocation racing a Put.
dependency
Package dependency turns the errors of third-party packages into errors of this module and keeps the module's own HTTP calls from following redirects.
Package dependency turns the errors of third-party packages into errors of this module and keeps the module's own HTTP calls from following redirects.
failure
Package failure classifies a failed action for the Outcome a provider reports, and answers and reports a provider's requests.
Package failure classifies a failed action for the Outcome a provider reports, and answers and reports a provider's requests.
fakeprovider
Package fakeprovider holds in-process fakes of the identity providers the library talks to (an OIDC issuer with the Keycloak admin API, and GitHub) for unit and end-to-end tests.
Package fakeprovider holds in-process fakes of the identity providers the library talks to (an OIDC issuer with the Keycloak admin API, and GitHub) for unit and end-to-end tests.
fetchmetadata
Package fetchmetadata reads the Fetch Metadata request headers (Sec-Fetch-*) browsers send.
Package fetchmetadata reads the Fetch Metadata request headers (Sec-Fetch-*) browsers send.
forwardauth
Package forwardauth is the server of the forward-auth binary (cmd/forwardauth): the gin engine with the forward-auth checks Traefik calls, the provider routes, JWKS, identity, health and readiness endpoints, wide events and HTTP metrics on every request, and the graceful run of the public and the metrics listener.
Package forwardauth is the server of the forward-auth binary (cmd/forwardauth): the gin engine with the forward-auth checks Traefik calls, the provider routes, JWKS, identity, health and readiness endpoints, wide events and HTTP metrics on every request, and the graceful run of the public and the metrics listener.
hook
Package hook runs the application hooks the providers call.
Package hook runs the application hooks the providers call.
httpjson
Package httpjson decodes strict JSON request bodies and writes JSON responses.
Package httpjson decodes strict JSON request bodies and writes JSON responses.
impersonation
Package impersonation writes a refreshed real identity back into an identity that may be impersonating another one.
Package impersonation writes a refreshed real identity back into an identity that may be impersonating another one.
oauthlogin
Package oauthlogin keeps the state of one redirect login (state, nonce, PKCE verifier, return path) in the server-side session, so the callback verifies it exactly once on any replica sharing the session backend.
Package oauthlogin keeps the state of one redirect login (state, nonce, PKCE verifier, return path) in the server-side session, so the callback verifies it exactly once on any replica sharing the session backend.
random
Package random generates unguessable tokens for session IDs, login state and nonces.
Package random generates unguessable tokens for session IDs, login state and nonces.
redirect
Package redirect validates where the library may send a browser or a credential and where it serves routes: same-origin return paths, login locations carrying a return path, configured external URLs and redirect targets, the endpoints of identity providers and route path prefixes.
Package redirect validates where the library may send a browser or a credential and where it serves routes: same-origin return paths, login locations carrying a return path, configured external URLs and redirect targets, the endpoints of identity providers and route path prefixes.
sessiontest
Package sessiontest sets up session states for the tests of packages that build on package session.
Package sessiontest sets up session states for the tests of packages that build on package session.
tokenendpoint
Package tokenendpoint turns the errors of an OAuth token request (golang.org/x/oauth2) into errors of this module that carry none of the endpoint's free text.
Package tokenendpoint turns the errors of an OAuth token request (golang.org/x/oauth2) into errors of this module that carry none of the endpoint's free text.
Package jwt mints and verifies the RS512 JSON Web Tokens that carry an auth.Identity from the forward-auth server to the backends behind it.
Package jwt mints and verifies the RS512 JSON Web Tokens that carry an auth.Identity from the forward-auth server to the backends behind it.
Package oidc is the OpenID Connect provider: authorization code flow with PKCE (S256) and nonce, state bound to the server-side session, RP-initiated logout through the discovered end_session_endpoint and front-channel logout.
Package oidc is the OpenID Connect provider: authorization code flow with PKCE (S256) and nonce, state bound to the server-side session, RP-initiated logout through the discovered end_session_endpoint and front-channel logout.
keycloak
Package keycloak enriches OIDC identities from the Keycloak Admin API: composite realm roles, client roles of one client, group paths and user attributes, and refuses users without the required roles or groups.
Package keycloak enriches OIDC identities from the Keycloak Admin API: composite realm roles, client roles of one client, group paths and user attributes, and refuses users without the required roles or groups.
Package password is the password login provider: JSON endpoints over net/http for login by username or email, an optional TOTP second factor with backup codes, optional self-registration (off by default) and logout.
Package password is the password login provider: JSON endpoints over net/http for login by username or email, an optional TOTP second factor with backup codes, optional self-registration (off by default) and logout.
Package prometheusadapter counts authentication outcomes as Prometheus metrics, on a registry the caller passes in.
Package prometheusadapter counts authentication outcomes as Prometheus metrics, on a registry the caller passes in.
Package session keeps server-side sessions for every provider of the module and authenticates requests with them.
Package session keeps server-side sessions for every provider of the module and authenticates requests with them.
redisbackend
Package redisbackend implements session.Backend on Redis, so that sessions work across replicas.
Package redisbackend implements session.Backend on Redis, so that sessions work across replicas.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL