auth

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

README

dioad/auth

Authentication and authorization helpers for Go services, including OIDC client utilities, JWT validation helpers, HTTP middleware, and TLS configuration helpers.

Packages

  • oidc: OpenID Connect client, token sources, and validation helpers (Keycloak, GitHub Actions, AWS, Fly.io). See Auth Debug Utility for a tool to inspect tokens on these platforms.
  • jwt: Token validation helpers and claim predicates, plus composable multi-validator support.
  • http: HTTP authentication middleware for Basic, GitHub App, and HMAC signatures, plus JWT/OIDC wiring helpers.
  • tls: TLS configuration helpers for clients and servers (cert loading, client auth).

OIDC quick start (token validation)

endpoint, _ := oidc.NewEndpoint("https://issuer.example")
client := oidc.NewClient(
    endpoint,
    oidc.WithKeyFunc(func(ctx context.Context) (interface{}, error) {
        return &publicKey, nil
    }),
)

claims, err := client.ValidateToken(ctx, tokenString, []string{"audience"})

HTTP middleware quick start

handler, _ := authhttp.NewHandler(&authhttp.ServerConfig{
    HMACAuthConfig: hmac.Config{Secret: "shared-secret"},
})

http.Handle("/secure", handler.Wrap(myHandler))

Browser OIDC shared configuration

For interactive browser login flows, use http/middleware/oidc.BrowserConfig as a reusable config contract.

browser := oidcmw.BrowserConfig{
    Issuer:       "https://issuer.example",
    ClientID:     "console-ui",
    ClientSecret: "redacted",
    RedirectURI:  "https://console.example/auth/callback",
    CookieSecure: true,
}
if err := browser.Validate(); err != nil {
    panic(err)
}

oidcClient, err := oidc.NewClientFromConfig(new(browser.ToClientConfig()))
if err != nil {
    panic(err)
}

mw := oidcmw.NewHandler(oidcClient, browser.ToOIDCConfig(), zerolog.Nop())
http.Handle("/ui/", mw.Wrap(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
})))

BrowserConfig.Validate enforces secure cookie use for authenticated browser sessions.

OIDC configuration ownership (one way to do it)

  • Use oidc.ClientConfig for OIDC client/token exchange configuration.
  • Use http/middleware/oidc.BrowserConfig for browser login/session flows.
  • http/oidc.Config remains for backward compatibility and is deprecated in favor of oidc.Config.

This keeps provider/client concerns in oidc and browser-session concerns in middleware, with adapter methods (ToClientConfig, ToOIDCConfig) making the secure path the easy path.

Testability seams

The OIDC package provides explicit seams for fast, deterministic tests:

  • WithHTTPClient to inject a custom HTTPDoer for outbound requests.
  • WithClock to control time-dependent behavior.
  • WithKeyFunc/WithJWKSProvider to control verification keys without live JWKS endpoints.
  • NewTokenSourceFromConfigWithFactories to inject token source factories and a TokenStore implementation.

Documentation

Overview

Package auth provides server-side identity and authorization logic.

Principal Extraction

The PrincipalExtractor interface provides centralized principal (user identity) extraction from HTTP requests. This is the single source of truth for determining "who" is making a request.

Architecture:

  • Single interface (PrincipalExtractor) for all principal extraction
  • Multiple sources implement PrincipalSource interface
  • Fallback chain: Fly.io → GitHub Actions → AWS → generic OIDC → JWT → GitHub
  • Returns principal context with identifier, source metadata, and any errors

Usage Example:

extractor := auth.NewDefaultPrincipalExtractor()
pc, err := extractor.ExtractPrincipal(req.Context())
if err != nil {
    // Handle no principal found
    return
}
// Use pc.ID and pc.Source for logging/auditing
log.Info("principal", pc.ID, "source", pc.Source)

Adding New Sources:

To add a new principal source (e.g., mTLS certificates):

  1. Implement the PrincipalSource interface
  2. Add to the sources slice in NewDefaultPrincipalExtractor
  3. Update tests to cover the new source

Testing:

Use mock extractors in tests to avoid needing real authentication:

type mockExtractor struct{ principal string }
func (m *mockExtractor) ExtractPrincipal(ctx context.Context) (*PrincipalContext, error) {
    return &PrincipalContext{ID: m.principal, Source: "mock"}, nil
}

Index

Constants

View Source
const (
	// AttrEmail is the primary/verified email address.
	AttrEmail = "primary_email"

	// AttrEmailVerified indicates whether the email address has been verified.
	AttrEmailVerified = "primary_email_verified"

	// AttrUsername is the login name or username for the principal.
	AttrUsername = "username"

	// AttrPreferredUsername is the display name or preferred username.
	AttrPreferredUsername = "preferred_username"

	// AttrUserPrincipalName is the user principal name (UPN), used by Azure AD.
	AttrUserPrincipalName = "user_principal_name"

	// AttrOrganisations is the organisations or tenant names associated with the principal.
	AttrOrganisations = "organisations"
)

Canonical attribute key constants for PrincipalContext.Attributes.

These names normalise cross-provider identity fields so that application code and ClaimRoleMapper rules can reference common fields without knowing which IdP issued the token.

Provider-specific claims (e.g. "repository", "app_name") are also present in Attributes under their raw JWT claim names.

Variables

View Source
var (
	ErrNoPrincipalFound = errors.New("no principal found")
)

Functions

func ContextWithPrincipalContext

func ContextWithPrincipalContext(ctx context.Context, principalCtx *PrincipalContext) context.Context

ContextWithPrincipalContext stores a PrincipalContext in the request context.

Types

type ClaimRoleMapper

type ClaimRoleMapper = mapper.Mapper

ClaimRoleMapper maps a claims map to a list of roles. See mapper.Mapper for details.

func NewClaimRoleMapper

func NewClaimRoleMapper(mappings []ClaimRoleMapping) ClaimRoleMapper

NewClaimRoleMapper creates a ClaimRoleMapper from a list of ClaimRoleMapping rules. Returns nil if mappings is empty.

type ClaimRoleMapping

type ClaimRoleMapping = mapper.ClaimRoleMapping

ClaimRoleMapping maps a set of claim predicates to an internal role. All predicates must match (AND semantics). See mapper.ClaimRoleMapping for details.

type DefaultExtractorConfig

type DefaultExtractorConfig struct {
	// FlyioMapper maps Fly.io OIDC claims to internal roles.
	FlyioMapper ClaimRoleMapper
	// GithubActionsMapper maps GitHub Actions OIDC claims to internal roles.
	GithubActionsMapper ClaimRoleMapper
	// AWSMapper maps AWS OIDC claims to internal roles.
	AWSMapper ClaimRoleMapper
	// OIDCMapper maps generic OIDC claims (e.g. Dex/Keycloak user tokens) to
	// internal roles.
	OIDCMapper ClaimRoleMapper
	// JWTMapper maps generic JWT claims stored by auth middleware to internal
	// roles.
	JWTMapper ClaimRoleMapper
}

DefaultExtractorConfig configures per-source ClaimRoleMappers for NewDefaultPrincipalExtractorWithConfig. A nil mapper disables only mapped-role additions; provider-native source roles are still returned by each source.

type PrincipalContext

type PrincipalContext struct {
	// ID identifies the principal
	ID string

	// Source identifies which authentication method was used (e.g., "jwt", "oidc", "github")
	Source string

	// Attributes contains additional authentication data for debugging/logging
	Attributes map[string]any

	// Roles contains a list of roles associated with the principal
	Roles []string

	// IsService indicates if the principal represents a service / system
	IsService bool
}

PrincipalContext contains metadata about how a principal was extracted. This is useful for debugging, logging, and auditing authentication decisions.

func PrincipalContextFromContext

func PrincipalContextFromContext(ctx context.Context) *PrincipalContext

PrincipalContextFromContext retrieves a PrincipalContext from the request context.

func (*PrincipalContext) HasRole

func (c *PrincipalContext) HasRole(role string) bool

type PrincipalExtractor

type PrincipalExtractor interface {
	// ExtractPrincipal attempts to extract a principal from the context.
	// Returns the principal context about the extraction, or an error if no principal found.
	ExtractPrincipal(ctx context.Context) (*PrincipalContext, error)
}

PrincipalExtractor extracts the authenticated principal (user identity) from the request context. This is the central service for all principal/identity resolution in the server.

The extractor tries multiple sources in priority order and returns the first successful match, along with metadata about how the principal was determined.

func NewAllowAllPrincipalExtractor

func NewAllowAllPrincipalExtractor() PrincipalExtractor

NewAllowAllPrincipalExtractor creates a PrincipalExtractor that accepts all requests as unauthenticated. Useful for testing and development environments where authorization is disabled.

func NewDefaultPrincipalExtractor

func NewDefaultPrincipalExtractor() PrincipalExtractor

NewDefaultPrincipalExtractor creates a PrincipalExtractor with the standard fallback chain: 1. Fly.io OIDC token 2. GitHub Actions OIDC token 3. AWS OIDC token 4. Generic OIDC token (Keycloak, etc.) 5. JWT token 6. GitHub user info (lowest priority)

This matches the existing behavior of the system.

func NewDefaultPrincipalExtractorWithConfig

func NewDefaultPrincipalExtractorWithConfig(cfg DefaultExtractorConfig) PrincipalExtractor

NewDefaultPrincipalExtractorWithConfig creates a PrincipalExtractor with the standard fallback chain and per-source ClaimRoleMappers from cfg.

func NewPrincipalExtractor

func NewPrincipalExtractor(sources ...PrincipalSource) PrincipalExtractor

NewPrincipalExtractor creates a PrincipalExtractor with the provided sources, in order

type PrincipalSource

type PrincipalSource interface {
	// Extract attempts to extract a principal from this source.
	// Returns the principal identifier or empty string if not available.
	Extract(ctx context.Context) (string, error)

	// Name returns the identifier for this source (e.g., "jwt", "oidc", "github")
	Name() string

	// Claims returns additional authentication data for debugging/logging
	Claims(ctx context.Context) map[string]any

	// Roles return the roles asserted by this source, or nil if unavailable.  This is used for role-based privilege assignment.
	Roles(ctx context.Context) []string

	// IsService returns if the source is a service identity
	IsService(ctx context.Context) bool
}

PrincipalSource represents a single method of extracting a principal from the context. Each source (JWT, OIDC, GitHub, etc.) implements this interface.

Directories

Path Synopsis
Package authctx defines context keys and accessor functions for credentials stored in a request context by authentication middleware.
Package authctx defines context keys and accessor functions for credentials stored in a request context by authentication middleware.
Package authz provides a unified authorization model for the dioad platform.
Package authz provides a unified authorization model for the dioad platform.
Package claimrolemapping provides shared configuration types and constructor functions for building a PrincipalExtractor from claim-based role mapping rules.
Package claimrolemapping provides shared configuration types and constructor functions for building a PrincipalExtractor from claim-based role mapping rules.
cmd
auth-debug command
examples
oidc-auth command
Package http provides HTTP authentication utilities and interfaces.
Package http provides HTTP authentication utilities and interfaces.
authz/principal
Package principal provides principal-based authorization middleware.
Package principal provides principal-based authorization middleware.
basic
Package basic provides HTTP Basic authentication middleware and utilities.
Package basic provides HTTP Basic authentication middleware and utilities.
github
Package github provides GitHub-based authentication middleware.
Package github provides GitHub-based authentication middleware.
hmac
Package hmac provides HMAC-based authentication middleware.
Package hmac provides HMAC-based authentication middleware.
oidc
Package oidc provides HTTP authentication using OpenID Connect via goth.
Package oidc provides HTTP authentication using OpenID Connect via goth.
server
Package server provides auth-specific ServerOption factories for github.com/dioad/net/http servers.
Package server provides auth-specific ServerOption factories for github.com/dioad/net/http servers.
Package jwt provides helpers for validating JSON Web Tokens (JWT) and composing claim predicates.
Package jwt provides helpers for validating JSON Web Tokens (JWT) and composing claim predicates.
Package mapper provides claim-based role mapping for PrincipalSource implementations.
Package mapper provides claim-based role mapping for PrincipalSource implementations.
Package oidc provides an OpenID Connect (OIDC) client and utilities for token validation and management.
Package oidc provides an OpenID Connect (OIDC) client and utilities for token validation and management.
aws
Package aws provides functionality to retrieve OIDC tokens from AWS STS GetWebIdentityToken API.
Package aws provides functionality to retrieve OIDC tokens from AWS STS GetWebIdentityToken API.

Jump to

Keyboard shortcuts

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