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

auth

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	GoogleGroupMembershipResolved    = "resolved"
	GoogleGroupMembershipUnavailable = "unavailable"
)
View Source
const (
	// MCPAccessTokenPrefix is a public token type marker, not a credential.
	//nolint:gosec // A fixed prefix lets the authenticator select the token verifier.
	MCPAccessTokenPrefix = "slashdocs_mcp_"
	ServiceAccountPrefix = "slashdocs_sa_"
)
View Source
const GoogleIssuer = "https://accounts.google.com"

GoogleIssuer is the OIDC issuer for Google accounts. Deployments configured with the legacy GOOGLE_OAUTH_* variables resolve to it.

Variables

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound is the canonical "principal/record not found" sentinel. The repo layer's repo.ErrNotFound wraps this so that lower-level packages (e.g. this auth package, which must not import repo to avoid an import cycle) can still detect not-found results via errors.Is.

View Source
var ErrUnauthorized = errors.New("unauthorized")

Functions

func BearerFromHeader

func BearerFromHeader(h string) string

func HashToken

func HashToken(token string) string

func LoopbackRedirectAllowed

func LoopbackRedirectAllowed(raw string) bool

func NewBearerToken

func NewBearerToken(prefix string) (string, string, error)

func NewMCPAccessToken

func NewMCPAccessToken(userID, resource, secret string, ttl time.Duration) string

func RandomURLToken

func RandomURLToken() (string, error)

func VerifyPKCES256

func VerifyPKCES256(verifier, challenge string) bool

Types

type Authenticator

type Authenticator interface {
	Authenticate(r *http.Request) (*Principal, error)
}

type DBAuthenticator

type DBAuthenticator struct {
	Resolver interface {
		TokenResolver
		UserResolver
	}
	SessionSecret string
}

func (DBAuthenticator) Authenticate

func (a DBAuthenticator) Authenticate(r *http.Request) (*Principal, error)

type LoginState

type LoginState struct {
	Mode, Redirect, CLIRedirect, CodeChallenge string
	ExpiresAt                                  time.Time
	User                                       OIDCUser
	UserID                                     string
	// MCP OAuth authorization codes reuse the same one-time, persisted code
	// store as CLI login while carrying the audience and public-client binding
	// required by OAuth 2.1.
	OAuthClientID    string
	OAuthRedirectURI string
	OAuthResource    string
	OAuthScope       string
	// WebBindingRequired marks web login states created after browser binding
	// was introduced. Its zero value preserves callbacks for states created by
	// older instances during a rolling deployment.
	WebBindingRequired bool
}

func (LoginState) MarshalJSON

func (s LoginState) MarshalJSON() ([]byte, error)

func (*LoginState) UnmarshalJSON

func (s *LoginState) UnmarshalJSON(data []byte) error

type LoginStateStore

type LoginStateStore interface {
	PutState(ctx context.Context, id string, st LoginState) error
	TakeState(ctx context.Context, id string) (LoginState, bool, error)
	PutCode(ctx context.Context, code string, st LoginState) error
	TakeCode(ctx context.Context, code string) (LoginState, bool, error)
}

type MCPAuthenticator

type MCPAuthenticator struct {
	Users         UserResolver
	ServiceTokens Authenticator
	SessionSecret string
	Resource      string
}

MCPAuthenticator authenticates the remote MCP transport. Browser session cookies are deliberately not accepted: every MCP request must carry a bearer token so identity cannot leak between clients or transport sessions.

Human access tokens are expiring, audience-bound tokens minted by the MCP OAuth flow. Existing service-account keys remain available for unattended agents and are resolved through the normal API authenticator.

func (MCPAuthenticator) Authenticate

func (a MCPAuthenticator) Authenticate(r *http.Request) (*Principal, error)

type OIDC

type OIDC struct {
	Config   *oauth2.Config
	Verifier *oidc.IDTokenVerifier
	Issuer   string
}

OIDC drives the OpenID Connect authorization-code flow for one provider. Tests may construct it directly with a fake Config; production code should go through NewOIDC, which discovers endpoints and wires JWKS verification.

func NewOIDC

func NewOIDC(ctx context.Context, cfg OIDCConfig) (OIDC, error)

NewOIDC prepares an OIDC client. Google uses its stable OAuth endpoints and a lazy remote JWKS so existing deployments do not require network access at startup. Other providers are discovered from <issuer>/.well-known/openid-configuration.

func (OIDC) AuthCodeURL

func (o OIDC) AuthCodeURL(state string, opts ...oauth2.AuthCodeOption) string

func (OIDC) ExchangeAndVerify

func (o OIDC) ExchangeAndVerify(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (OIDCUser, error)

ExchangeAndVerify redeems an authorization code and verifies the returned ID token's signature, issuer, audience, and expiry.

type OIDCConfig

type OIDCConfig struct {
	// IssuerURL is the provider's public issuer; ID tokens are validated
	// against it and browsers are sent to its authorization endpoint.
	IssuerURL string
	// InternalIssuerURL optionally names a second base URL where the server
	// reaches the same provider (split horizon, e.g. a docker-compose network
	// where the browser sees http://localhost:5556 but the server must dial
	// http://dex:5556). Discovery, token exchange, and JWKS fetches use it;
	// token `iss` claims keep being validated against IssuerURL.
	InternalIssuerURL string
	ClientID          string
	ClientSecret      string
	RedirectURL       string
}

OIDCConfig configures the connection to one OpenID Connect provider.

type OIDCSettings

type OIDCSettings struct {
	IssuerURL         string
	InternalIssuerURL string
	ClientID          string
	ClientSecret      string
	// ProviderName labels the login button ("Continue with <ProviderName>").
	ProviderName string
}

OIDCSettings is the login provider configuration resolved from environment variables.

func ResolveOIDCSettings

func ResolveOIDCSettings(getenv func(string) string) (OIDCSettings, error)

ResolveOIDCSettings resolves the generic SLASHDOCS_OIDC_* variables and the legacy GOOGLE_OAUTH_CLIENT_ID/GOOGLE_OAUTH_CLIENT_SECRET pair into one provider configuration. The Google pair keeps working as an alias for issuer https://accounts.google.com so existing deployments need no changes; mixing the two families is a configuration error. getenv is os.Getenv in production.

type OIDCUser

type OIDCUser struct{ Sub, Email, Name, PictureURL string }

OIDCUser holds the identity claims extracted from a verified ID token.

type PostgresStateStore

type PostgresStateStore struct {
	// contains filtered or unexported fields
}

func NewPostgresStateStore

func NewPostgresStateStore(db *pgxpool.Pool) *PostgresStateStore

func (*PostgresStateStore) CleanupExpired

func (s *PostgresStateStore) CleanupExpired(ctx context.Context) error

func (*PostgresStateStore) PutCode

func (s *PostgresStateStore) PutCode(ctx context.Context, code string, st LoginState) error

func (*PostgresStateStore) PutState

func (s *PostgresStateStore) PutState(ctx context.Context, id string, st LoginState) error

func (*PostgresStateStore) TakeCode

func (s *PostgresStateStore) TakeCode(ctx context.Context, code string) (LoginState, bool, error)

func (*PostgresStateStore) TakeState

func (s *PostgresStateStore) TakeState(ctx context.Context, id string) (LoginState, bool, error)

type Principal

type Principal struct {
	Type       PrincipalType `json:"type"`
	ID         string        `json:"id"`
	Email      string        `json:"email,omitempty"`
	Name       string        `json:"name,omitempty"`
	PictureURL string        `json:"picture_url,omitempty"`

	// GoogleGroupIDs and GoogleGroupMembershipState are authorization inputs,
	// not principal profile data. Excluding them from JSON prevents a
	// user's group graph (and resolution failures) from leaking through API
	// responses that serialize the authenticated principal.
	GoogleGroupIDs             []string `json:"-"`
	GoogleGroupMembershipState string   `json:"-"`
}

type PrincipalType

type PrincipalType string
const (
	PrincipalUser           PrincipalType = "user"
	PrincipalServiceAccount PrincipalType = "service_account"
	PrincipalGoogleGroup    PrincipalType = "google_group"
	// PrincipalAnyone represents "everyone who can authenticate to this
	// server". On an org deployment the login gate scopes that set to the
	// org's members. It is stored as a grant with an empty principal id.
	PrincipalAnyone PrincipalType = "anyone"
	// PrincipalAnonymous represents an unauthenticated caller. A public
	// deployment gives it to a caller without credentials on the routes that
	// read a document, where only "anyone" grants apply to it.
	PrincipalAnonymous PrincipalType = "anonymous"
)

type SessionCodec

type SessionCodec struct{ Secret []byte }

func (SessionCodec) Sign

func (s SessionCodec) Sign(userID string) string

func (SessionCodec) SignForAudience

func (s SessionCodec) SignForAudience(userID, audience string, ttl time.Duration) string

func (SessionCodec) VerifyAudience

func (s SessionCodec) VerifyAudience(v, audience string) (string, bool)

func (SessionCodec) VerifySession

func (s SessionCodec) VerifySession(v string) (string, bool)

type StateStore

type StateStore struct {
	// contains filtered or unexported fields
}

func NewStateStore

func NewStateStore() *StateStore

func (*StateStore) PutCode

func (s *StateStore) PutCode(ctx context.Context, code string, st LoginState) error

func (*StateStore) PutState

func (s *StateStore) PutState(ctx context.Context, id string, st LoginState) error

func (*StateStore) TakeCode

func (s *StateStore) TakeCode(ctx context.Context, code string) (LoginState, bool, error)

func (*StateStore) TakeState

func (s *StateStore) TakeState(ctx context.Context, id string) (LoginState, bool, error)

type TokenResolver

type TokenResolver interface {
	ResolveBearerToken(ctx context.Context, tokenHash string) (Principal, error)
}

type UserResolver

type UserResolver interface {
	ResolveUser(ctx context.Context, id string) (Principal, error)
}

Jump to

Keyboard shortcuts

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