middleware

package
v0.11.1 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ValidationModeScope validates using the JWT scope claim directly.
	ValidationModeScope = "scope"
	// ValidationModeRole validates by expanding IDP roles into platform roles.
	ValidationModeRole = "role"
)

Variables

This section is empty.

Functions

func GetActorIdentityFromRequest

func GetActorIdentityFromRequest(r *http.Request) (string, bool)

GetActorIdentityFromRequest resolves the raw identity-provider identifier for the actor behind r, preferring the token's "sub" claim and falling back to GetUserIDFromRequest (configured-claim/user_id/sub) when sub is unavailable (e.g. non-OIDC IdPs, or test/internal callers that only set the legacy context key). ok is false only when neither source has a value — callers that must reject unauthenticated requests should treat that as 401. This mirrors the precedence used by service.IdentityService.InternalUserID; use it at call sites that need the raw id before mapping (e.g. to distinguish "claim missing" from "mapping failed").

func GetAudienceFromRequest

func GetAudienceFromRequest(r *http.Request) (string, bool)

GetAudienceFromRequest extracts the audience from the request context.

func GetEmailFromRequest

func GetEmailFromRequest(r *http.Request) (string, bool)

GetEmailFromRequest extracts the email from the request context.

func GetFirstNameFromRequest

func GetFirstNameFromRequest(r *http.Request) (string, bool)

GetFirstNameFromRequest extracts the first name from the request context.

func GetIdpOrgRefFromRequest

func GetIdpOrgRefFromRequest(r *http.Request) (string, bool)

GetIdpOrgRefFromRequest extracts the raw organization claim carried by the token (the IDP's organization id in IDP mode). Unlike the organization key — which OrganizationResolverMiddleware rewrites to the platform UUID — this always reflects the value the token asserted. Returns false when unset.

func GetLastNameFromRequest

func GetLastNameFromRequest(r *http.Request) (string, bool)

GetLastNameFromRequest extracts the last name from the request context.

func GetOrgHandleFromRequest

func GetOrgHandleFromRequest(r *http.Request) (string, bool)

GetOrgHandleFromRequest extracts the organization handle from the request context.

func GetOrgNameFromRequest

func GetOrgNameFromRequest(r *http.Request) (string, bool)

GetOrgNameFromRequest extracts the organization display name from the request context.

func GetOrganizationFromRequest

func GetOrganizationFromRequest(r *http.Request) (string, bool)

GetOrganizationFromRequest extracts the organization claim from the request context.

func GetPlatformRolesFromRequest

func GetPlatformRolesFromRequest(r *http.Request) ([]string, bool)

GetPlatformRolesFromRequest extracts platform roles from the request context.

func GetRolesFromRequest

func GetRolesFromRequest(r *http.Request) ([]string, bool)

GetRolesFromRequest parses the space-separated scope string into individual roles.

func GetScopeFromRequest

func GetScopeFromRequest(r *http.Request) (string, bool)

GetScopeFromRequest extracts the scope from the request context.

func GetSubClaimFromRequest

func GetSubClaimFromRequest(r *http.Request) (string, bool)

GetSubClaimFromRequest extracts the token's OIDC "sub" (subject) claim from the request context. This is the raw IdP subject identifier — distinct from GetUserIDFromRequest, which returns the configured-claim/user_id/sub precedence value used historically for audit columns. Prefer this for keying the internal-UUID mapping (see service.IdentityService).

func GetUserIDFromRequest

func GetUserIDFromRequest(r *http.Request) (string, bool)

GetUserIDFromRequest extracts the user ID from the request context.

func GetUsernameFromRequest

func GetUsernameFromRequest(r *http.Request) (string, bool)

GetUsernameFromRequest extracts the username from the request context.

func InitClaimsAuthz

func InitClaimsAuthz()

InitClaimsAuthz is retained for compatibility.

func InitScopeAuthz

func InitScopeAuthz()

InitScopeAuthz is retained for compatibility.

func LoadRoleScopeMap

func LoadRoleScopeMap(path string) (map[string][]string, error)

LoadRoleScopeMap reads a roles.yaml file and returns a map from IDP role name to the list of platform scopes that role grants. Each user token may carry multiple roles; the caller is expected to union the scope lists at request time.

func LocalJWTAuthMiddleware

func LocalJWTAuthMiddleware(config AuthConfig) func(http.Handler) http.Handler

LocalJWTAuthMiddleware returns a middleware for locally-issued JWT validation. Used only when IDP mode is disabled.

func NewTestContextMiddleware

func NewTestContextMiddleware(next http.Handler) http.Handler

NewTestContextMiddleware creates an http.Handler middleware for integration tests. It reads X-Test-Org and X-Test-User request headers and injects the values into the request context so that GetOrganizationFromRequest / GetUsernameFromRequest work without a real JWT. Never use this in production code.

func OrganizationResolverMiddleware

func OrganizationResolverMiddleware(resolve OrgUUIDResolver) func(http.Handler) http.Handler

OrganizationResolverMiddleware resolves the organization claim populated by the authentication middleware into the platform organization UUID, and stores that UUID back under the organization context key. Downstream handlers therefore scope their queries by the correct UUID regardless of whether the token carries the platform UUID (file-based auth) or the IDP's organization id (IDP auth).

The raw claim is preserved under a separate key (see GetIdpOrgRefFromRequest) for callers that need the original IDP reference — notably organization registration, where no organization exists yet to resolve against.

func PlatformClaimsMiddleware

func PlatformClaimsMiddleware(claimNames PlatformClaimNames) func(http.Handler) http.Handler

PlatformClaimsMiddleware extracts platform-specific values from the AuthContext set by common/authenticators.AuthMiddleware (IDP mode) and populates per-key context entries.

func RequireOrganization

func RequireOrganization(organizationParam string) func(http.Handler) http.Handler

RequireOrganization returns a middleware that aborts with 403 if the token's organization does not match the organization ID in the URL path value.

func ScopeEnforcer

func ScopeEnforcer(registry *ScopeRegistry, cfg ScopeEnforcerConfig) func(http.Handler) http.Handler

ScopeEnforcer returns a middleware that reads the required scopes for each request from the OpenAPI ScopeRegistry and enforces them.

It uses r.Pattern (set by net/http ServeMux in Go 1.22+) to identify the matched route template (e.g. "GET /api/v0.9/rest-apis/{id}"). Routes not present in the registry are passed through without a scope check.

func ValidateRoleScopeMap

func ValidateRoleScopeMap(m map[string][]string, registry *ScopeRegistry) error

ValidateRoleScopeMap checks that every scope referenced in the map is declared in the OpenAPI spec. An unrecognized scope name is almost certainly a typo that would silently deny access, so we fail fast at startup rather than at request time.

func WithOrganization

func WithOrganization(r *http.Request, org string) *http.Request

WithOrganization is a helper for tests to inject an organization into the request context.

func WithUserID

func WithUserID(r *http.Request, id string) *http.Request

WithUserID is a helper for tests to inject a user ID into the request context.

Types

type AuthConfig

type AuthConfig struct {
	SecretKey             string
	TokenIssuer           string
	SkipPaths             []string
	SkipValidation        bool
	OrganizationClaimName string
}

AuthConfig holds the configuration for the local JWT (non-IDP) authentication path.

type Authenticator

type Authenticator interface {
	// Middleware returns the ordered handler chain that validates credentials
	// and populates the request context with identity values.
	Middleware() []func(http.Handler) http.Handler
}

Authenticator abstracts credential validation. Implementations populate the request context with identity values (user_id, organization, scope, platform_roles, …) when authentication succeeds, and write an error response on failure.

type CustomClaims

type CustomClaims struct {
	Audience     string `json:"aud"`
	Email        string `json:"email"`
	FirstName    string `json:"firstName"`
	LastName     string `json:"lastName"`
	JTI          string `json:"jti"`
	Organization string `json:"organization"`
	Scope        string `json:"scope"`
	Username     string `json:"username"`
	jwt.RegisteredClaims
}

CustomClaims represents the JWT claims structure used in local JWT (non-IDP) mode.

func GetClaimsFromRequest

func GetClaimsFromRequest(r *http.Request) (*CustomClaims, bool)

GetClaimsFromRequest extracts the full CustomClaims object from the request context.

type JWTAuthenticator

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

JWTAuthenticator wraps one or more middleware functions that perform JWT validation and claims extraction behind the Authenticator interface.

func NewJWTAuthenticator

func NewJWTAuthenticator(handlers ...func(http.Handler) http.Handler) *JWTAuthenticator

NewJWTAuthenticator creates an Authenticator backed by the given middleware handlers.

func (*JWTAuthenticator) Middleware

func (a *JWTAuthenticator) Middleware() []func(http.Handler) http.Handler

type OrgUUIDResolver

type OrgUUIDResolver func(orgClaim string) (string, bool)

OrgUUIDResolver maps a token's organization claim to the platform organization UUID, returning true when a matching organization exists.

type PlatformClaimNames

type PlatformClaimNames struct {
	OrganizationClaim string
	OrgNameClaim      string
	OrgHandleClaim    string
	UserIDClaim       string
	UsernameClaim     string
	EmailClaim        string
	ScopeClaim        string
	RolesClaimPath    string
	RoleScopeMap      map[string][]string
}

PlatformClaimNames holds the JWT claim names used to extract platform-specific values.

type ScopeEnforcerConfig

type ScopeEnforcerConfig struct {
	// ValidationMode selects how authorization is enforced: "scope" (default) or "role".
	ValidationMode string
	// Enabled controls whether scope checks are enforced.
	Enabled bool
}

ScopeEnforcerConfig holds options for the ScopeEnforcer middleware.

type ScopeRegistry

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

ScopeRegistry maps (HTTP method, net/http path pattern) to the acceptable scopes for that operation. Scopes are OR-evaluated: the caller needs at least one.

func LoadScopeRegistry

func LoadScopeRegistry(specPath string) (*ScopeRegistry, error)

LoadScopeRegistry parses the OpenAPI spec at specPath and returns a ScopeRegistry populated from the standard security field on each operation. The first servers[].url is used to derive the base path prefix that maps spec paths to actual net/http route patterns (e.g. /api/v1 + /projects → /api/v1/projects).

func LoadScopeRegistryFromBytes

func LoadScopeRegistryFromBytes(data []byte) (*ScopeRegistry, error)

LoadScopeRegistryFromBytes parses an OpenAPI 3.x YAML document from in-memory bytes and returns a populated ScopeRegistry. Intended for plugins that embed their own OpenAPI spec via go:embed.

func (*ScopeRegistry) AllScopes

func (r *ScopeRegistry) AllScopes() map[string]struct{}

AllScopes returns the set of every scope name declared across all operations. Used at startup to validate that roles.yaml only references known scopes.

func (*ScopeRegistry) Lookup

func (r *ScopeRegistry) Lookup(method, path string) ([]string, bool)

Lookup returns the required scopes for the given HTTP method and path pattern (e.g. r.Method and the path portion of r.Pattern). found is false when the route is not in the OpenAPI spec, meaning no scope requirement was declared.

func (*ScopeRegistry) Merge

func (r *ScopeRegistry) Merge(other *ScopeRegistry)

Merge copies all scope entries from other into r, overwriting on key conflicts. Used to merge plugin-contributed OpenAPI specs into the main registry.

Jump to

Keyboard shortcuts

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