auth

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: May 6, 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).
  • 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))

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()
ctx, err := extractor.ExtractPrincipal(req.Context(), req)
if err != nil {
    // Handle no principal found
    return
}
// Use ctx.ID and ctx.Source for logging/auditing
log.Info("principal", ctx.ID, "source", ctx.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, r *http.Request) (*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
}

DefaultExtractorConfig configures per-source ClaimRoleMappers for NewDefaultPrincipalExtractorWithConfig. Sources with a nil mapper return no roles from claims (equivalent to the zero-value behaviour of NewDefaultPrincipalExtractor).

type MockPrincipalSource

type MockPrincipalSource struct {
	MockName      string
	MockPrincipal string
	MockError     error
	MockClaims    map[string]any
	MockRoles     []string
	MockIsService bool
}

MockPrincipalSource is a test implementation of PrincipalSource

func (*MockPrincipalSource) Claims

func (m *MockPrincipalSource) Claims(_ context.Context) map[string]any

func (*MockPrincipalSource) Extract

func (*MockPrincipalSource) IsService

func (m *MockPrincipalSource) IsService(_ context.Context) bool

func (*MockPrincipalSource) Name

func (m *MockPrincipalSource) Name() string

func (*MockPrincipalSource) Roles

func (m *MockPrincipalSource) Roles(_ context.Context) []string

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

	// TenantID identifies a principal's tenant
	TenantID 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 request context.
	// Returns the principal context about the extraction, or an error if no principal found.
	ExtractPrincipal(ctx context.Context, r *http.Request) (*PrincipalContext, error)
}

PrincipalExtractor extracts the authenticated principal (user identity) from an HTTP request. 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, r *http.Request) (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 a request. Each source (JWT, OIDC, GitHub, etc.) implements this interface.

Directories

Path Synopsis
Package authz provides a unified authorization model for the dioad platform.
Package authz provides a unified authorization model for the dioad platform.
Package http provides HTTP authentication utilities and interfaces.
Package http provides HTTP authentication utilities and interfaces.
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.
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