config

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TokenOriginKasLegacy = "kas-legacy" // Legacy KAS tokens
	TokenOriginKasSsa    = "kas-ssa"    // KAS SSA tokens
	TokenOriginKeycloak  = "keycloak"   // Keycloak tokens
	TokenOriginCustom    = "custom"     // Custom/third-party tokens (default if not specified)
)

TokenOrigin constants define the source of JWT tokens These string values correspond to what's configured in the issuer configmap

Variables

View Source
var (
	// ServiceAccountRoles are the default roles assigned to service accounts
	ServiceAccountRoles = []string{"FORGE_PROVIDER_ADMIN", "FORGE_TENANT_ADMIN"}

	// AllowedRoles is the set of valid roles that can be assigned to users.
	// Both static roles in config and dynamic roles from claims must be from this set.
	AllowedRoles = map[string]bool{
		"FORGE_TENANT_ADMIN":   true,
		"FORGE_PROVIDER_ADMIN": true,
	}
)

AllowedOrigins is the list of valid token origins for the service

View Source
var (
	// DefaultMockResponses provides standard mock responses for tests (backward compatibility)
	DefaultMockResponses = GetDefaultMockResponses()
)

Functions

func CreateMockKeycloakServer

func CreateMockKeycloakServer(config MockKeycloakServerConfig) *httptest.Server

CreateMockKeycloakServer creates a consolidated mock Keycloak server

func FilterToAllowedRoles

func FilterToAllowedRoles(roles []string) (allowed []string, err error)

FilterToAllowedRoles filters a list of roles to only include allowed roles. Returns core.ErrInvalidRole if no valid roles remain after filtering.

func GenerateExpiredTestJWT

func GenerateExpiredTestJWT(claims jwt.MapClaims) (string, error)

GenerateExpiredTestJWT generates an expired JWT for testing

func GenerateFutureTestJWT

func GenerateFutureTestJWT(claims jwt.MapClaims) (string, error)

GenerateFutureTestJWT generates a JWT that's not yet valid

func GenerateJWKSFromRSAKey

func GenerateJWKSFromRSAKey(publicKey *rsa.PublicKey, keyID string) string

GenerateJWKSFromRSAKey creates a JWKS JSON response from an RSA public key

func GenerateJWTWithWrongSignature

func GenerateJWTWithWrongSignature(claims jwt.MapClaims) (string, error)

GenerateJWTWithWrongSignature generates a JWT with wrong signature

func GenerateMalformedJWT

func GenerateMalformedJWT() string

GenerateMalformedJWT generates a malformed JWT for testing

func GenerateTestJWT

func GenerateTestJWT(claims jwt.Claims, key *rsa.PrivateKey) (string, error)

GenerateTestJWT creates a JWT token with the given claims and key

func GetConsistentTestRSAKey

func GetConsistentTestRSAKey() *rsa.PrivateKey

GetConsistentTestRSAKey returns a consistent RSA key for testing This ensures JWT tokens and JWKS responses use the same key

func GetIsServiceAccountFromContext

func GetIsServiceAccountFromContext(c echo.Context) bool

GetIsServiceAccountFromContext returns whether the request is from a service account

func GetRolesFromAttribute

func GetRolesFromAttribute(claims jwt.MapClaims, attribute string) ([]string, error)

GetRolesFromAttribute extracts roles from a nested claim attribute and filters to allowed roles. Returns nil if the attribute doesn't exist or contains no valid roles.

func IsValidRole

func IsValidRole(role string) bool

IsValidRole checks if a single role is in the AllowedRoles set.

func SetIsServiceAccountInContext

func SetIsServiceAccountInContext(c echo.Context, isServiceAccount bool)

SetIsServiceAccountInContext stores whether the request is from a service account

Types

type AuthContextKey

type AuthContextKey string

AuthContextKey is a custom type for context keys to avoid collisions

type ClaimMapping

type ClaimMapping struct {
	// OrgAttribute: JWT claim path to extract org name (e.g., "org", "data.org"). Makes this a dynamic mapping.
	OrgAttribute string `mapstructure:"orgAttribute"`
	// OrgDisplayAttribute: JWT claim path for org display name (dynamic mappings only)
	OrgDisplayAttribute string `mapstructure:"orgDisplayAttribute"`

	// OrgName: fixed organization name (static mapping). Used when OrgAttribute is empty.
	OrgName string `mapstructure:"orgName"`
	// OrgDisplayName: display name for static org mappings
	OrgDisplayName string `mapstructure:"orgDisplayName"`

	// RolesAttribute: JWT claim path to extract roles (e.g., "roles", "data.roles"). Takes precedence over Roles.
	RolesAttribute string `mapstructure:"rolesAttribute"`
	// Roles: static role list. Used when RolesAttribute is empty and IsServiceAccount is false.
	Roles []string `mapstructure:"roles"`

	// IsServiceAccount: if true, assigns admin roles (FORGE_PROVIDER_ADMIN, FORGE_TENANT_ADMIN). Ignores RolesAttribute/Roles.
	IsServiceAccount bool `mapstructure:"isServiceAccount"`
}

ClaimMapping defines how to map JWT claims to organization data. Dynamic mode: set OrgAttribute to extract org from token claims. Static mode: set OrgName for a fixed organization.

func (*ClaimMapping) GetOrgNameAndDisplayName

func (cm *ClaimMapping) GetOrgNameAndDisplayName(claims jwt.MapClaims) (orgName string, displayName string)

GetOrgNameAndDisplayName extracts org and display name from claims (dynamic mappings only).

func (*ClaimMapping) GetRoles

func (cm *ClaimMapping) GetRoles(claims jwt.MapClaims) ([]string, error)

GetRoles returns roles based on mapping config: service account roles, dynamic extraction, or static roles.

func (*ClaimMapping) IsOrgDynamic

func (cm *ClaimMapping) IsOrgDynamic() bool

IsOrgDynamic returns true if this is a valid dynamic org mapping. Dynamic mappings require all three attributes:

  • OrgAttribute: JWT claim path to extract org name (e.g., "org", "data.org")
  • OrgDisplayAttribute: JWT claim path to extract org display name (e.g., "org_display", "data.orgDisplayName")
  • RolesAttribute: JWT claim path to extract roles (e.g., "roles", "data.roles")

Service accounts are not allowed with dynamic orgs.

func (*ClaimMapping) IsOrgStatic

func (cm *ClaimMapping) IsOrgStatic() bool

IsOrgStatic returns true if using a fixed org name (OrgName set).

type JWTOriginConfig

type JWTOriginConfig struct {
	sync.RWMutex // protects concurrent access to configs and handlers maps
	// contains filtered or unexported fields
}

JWTOriginConfig holds configuration for JWT origins with multiple JWKS configs and handlers

func NewJWTOriginConfig

func NewJWTOriginConfig() *JWTOriginConfig

NewJWTOriginConfig initializes and returns a configuration object with empty maps

func (*JWTOriginConfig) AddConfig

func (jc *JWTOriginConfig) AddConfig(name, issuer, url string, origin string, serviceAccount bool, audiences []string, scopes []string)

AddConfig adds a new JWKS config with the specified name, issuer, URL, origin, and serviceAccount flag

func (*JWTOriginConfig) AddConfigWithProcessor

func (jc *JWTOriginConfig) AddConfigWithProcessor(name, issuer, url string, origin string, serviceAccount bool, audiences []string, scopes []string, processor TokenProcessor)

AddConfigWithProcessor adds a new JWKS config and processor for the specified origin

func (*JWTOriginConfig) AddJwksConfig

func (jc *JWTOriginConfig) AddJwksConfig(cfg *JwksConfig)

AddJwksConfig adds a pre-configured JwksConfig for an issuer This is the preferred method for adding configurations

func (*JWTOriginConfig) GetAllConfigs

func (jc *JWTOriginConfig) GetAllConfigs() map[string]*JwksConfig

GetAllConfigs returns all JWKS configurations

func (*JWTOriginConfig) GetConfig

func (jc *JWTOriginConfig) GetConfig(issuer string) *JwksConfig

GetConfig returns the JWKS configuration for the specified issuer

func (*JWTOriginConfig) GetConfigsByOrigin

func (jc *JWTOriginConfig) GetConfigsByOrigin(origin string) map[string]*JwksConfig

GetConfigsByOrigin returns all JWKS configurations for the specified origin

func (*JWTOriginConfig) GetFirstConfigByOrigin

func (jc *JWTOriginConfig) GetFirstConfigByOrigin(origin string) *JwksConfig

GetFirstConfigByOrigin returns the first JWKS configuration with the specified origin

func (*JWTOriginConfig) GetKasProcessor

func (jc *JWTOriginConfig) GetKasProcessor() TokenProcessor

GetKasProcessor returns the processor for KAS tokens

func (*JWTOriginConfig) GetKeycloakProcessor

func (jc *JWTOriginConfig) GetKeycloakProcessor() TokenProcessor

GetKeycloakProcessor returns the processor for Keycloak tokens

func (*JWTOriginConfig) GetProcessorByIssuer

func (jc *JWTOriginConfig) GetProcessorByIssuer(issuer string) TokenProcessor

GetProcessorByIssuer finds a processor that exactly matches the given issuer

func (*JWTOriginConfig) GetProcessorByOrigin

func (jc *JWTOriginConfig) GetProcessorByOrigin(origin string) TokenProcessor

GetProcessorByOrigin returns the processor for the specified origin

func (*JWTOriginConfig) GetSsaProcessor

func (jc *JWTOriginConfig) GetSsaProcessor() TokenProcessor

GetSsaProcessor returns the processor for SSA tokens

func (*JWTOriginConfig) IsServiceAccount

func (jc *JWTOriginConfig) IsServiceAccount(issuer string) bool

IsServiceAccount checks if the given issuer supports service account tokens

func (*JWTOriginConfig) RemoveConfig

func (jc *JWTOriginConfig) RemoveConfig(issuer string)

RemoveConfig removes the JWKS configuration for the specified issuer

func (*JWTOriginConfig) SetProcessorForOrigin

func (jc *JWTOriginConfig) SetProcessorForOrigin(origin string, processor TokenProcessor)

SetProcessorForOrigin sets a processor for the specified token origin

func (*JWTOriginConfig) SetProcessors

func (jc *JWTOriginConfig) SetProcessors(keycloakProcessor, ssaProcessor, kasProcessor TokenProcessor)

SetProcessors sets all processors at once for easier initialization

func (*JWTOriginConfig) UpdateAllJWKS

func (jc *JWTOriginConfig) UpdateAllJWKS() error

UpdateAllJWKS updates the JWKs for all configurations in the map Updates are performed in parallel for better performance with multiple issuers. Continues on individual failures - only returns error if ALL updates fail.

type JwksConfig

type JwksConfig struct {
	Name         string
	IsUpdating   uint32    // atomic flag for concurrent JWKS updates
	sync.RWMutex           // protects JWKS access
	URL          string    // JWKS endpoint URL
	Issuer       string    // expected "iss" claim value
	Origin       string    // token origin type (e.g., "kas-legacy", "kas-ssa", "keycloak", "custom")
	LastUpdated  time.Time // last JWKS update timestamp

	JWKSTimeout time.Duration // fetch timeout (default: 5s)

	Audiences []string // allowed audience values (token must have at least one)
	Scopes    []string // required scopes (token must have ALL)

	ClaimMappings []ClaimMapping // org/role mapping configuration

	// ServiceAccount enables client credentials flow (Keycloak only).
	// For custom issuers, use ClaimMapping.IsServiceAccount instead.
	ServiceAccount bool

	// ReservedOrgNames prevents dynamic org mappings from claiming statically-configured org names.
	// Populated by carbide-rest-api during initialization.
	ReservedOrgNames map[string]bool
	// contains filtered or unexported fields
}

JwksConfig holds configuration for a JWKS endpoint and token validation.

func NewJwksConfig

func NewJwksConfig(name string, url string, issuer string, origin string, serviceAccount bool, audiences []string, scopes []string) *JwksConfig

NewJwksConfig is a function that initializes and returns a configuration object for managing JWKS

func (*JwksConfig) GetClaimMappings

func (jcfg *JwksConfig) GetClaimMappings() []ClaimMapping

GetClaimMappings returns the claim mappings.

func (*JwksConfig) GetJWKS

func (jcfg *JwksConfig) GetJWKS() *core.JWKS

GetJWKS returns the enhanced JWKS with go-jose capabilities

func (*JwksConfig) GetKeyByID

func (jcfg *JwksConfig) GetKeyByID(id string) (interface{}, error)

GetKeyByID is a method that returns a JWK secret by ID with enhanced validation

func (*JwksConfig) GetOrgDataFromClaim

func (jcfg *JwksConfig) GetOrgDataFromClaim(claims jwt.MapClaims, reqOrgFromRoute string) (cdbm.OrgData, bool, error)

GetOrgDataFromClaim extracts org data for the requested org from claim mappings. This method validates org access and returns errors if:

  • core.ErrReservedOrgName: dynamic org claims a statically-configured org name
  • core.ErrInvalidConfiguration: no claim mapping configured for the requested org
  • core.ErrNoClaimRoles: no roles found for the requested org

Returns orgData, isServiceAccount, and any error.

func (*JwksConfig) GetSubjectPrefix

func (jcfg *JwksConfig) GetSubjectPrefix() string

GetSubjectPrefix returns the issuer-derived prefix for namespacing subjects.

func (*JwksConfig) HasClaimMappings

func (jcfg *JwksConfig) HasClaimMappings() bool

HasClaimMappings returns true if claim mappings are configured.

func (*JwksConfig) KeyCount

func (jcfg *JwksConfig) KeyCount() int

KeyCount returns the number of keys in the JWKS

func (*JwksConfig) MatchesIssuer

func (jcfg *JwksConfig) MatchesIssuer(issuer string) bool

MatchesIssuer checks if the given issuer exactly matches the configured issuer

func (*JwksConfig) UpdateJWKS

func (jcfg *JwksConfig) UpdateJWKS() error

UpdateJWKS fetches and validates JWKS from the configured URL. Throttled to minUpdateInterval.

func (*JwksConfig) ValidateAudience

func (jcfg *JwksConfig) ValidateAudience(claims jwt.MapClaims) error

ValidateAudience checks token has at least one configured audience. Returns nil if none configured.

func (*JwksConfig) ValidateScopes

func (jcfg *JwksConfig) ValidateScopes(claims jwt.MapClaims) error

ValidateScopes checks token has ALL configured scopes. Returns nil if none configured.

func (*JwksConfig) ValidateToken

func (jcfg *JwksConfig) ValidateToken(authHeader string, claims jwt.Claims) (*jwt.Token, error)

ValidateToken parses token from Authorization header with caller-provided claims and enhanced validation

type KeycloakConfig

type KeycloakConfig struct {
	BaseURL               string
	ExternalBaseURL       string
	ClientID              string
	ClientSecret          string
	Realm                 string
	Issuer                string
	ServiceAccountEnabled bool
	// contains filtered or unexported fields
}

KeycloakConfig represents the configuration for Keycloak authentication

func NewKeycloakConfig

func NewKeycloakConfig(baseURL, externalBaseURL, clientID, clientSecret, realm string, serviceAccountEnabled bool) *KeycloakConfig

NewKeycloakConfig creates a new KeycloakConfig instance and attempts to fetch JWKS

func (*KeycloakConfig) GetJwksConfig

func (kc *KeycloakConfig) GetJwksConfig() (*JwksConfig, error)

GetJwksConfig gets the JWKS configuration, retrying fetch if needed

type MockKeycloakServerConfig

type MockKeycloakServerConfig struct {
	Responses        TestMockResponses
	ValidCredentials map[string]string // username -> password
	ValidTokens      map[string]bool   // token -> valid
	ValidCodes       map[string]bool   // code -> valid
}

MockKeycloakServerConfig configures the mock server behavior

func DefaultMockServerConfig

func DefaultMockServerConfig() MockKeycloakServerConfig

DefaultMockServerConfig provides a standard configuration

type TestMockResponses

type TestMockResponses struct {
	AdminLogin string
	IDPs       string
	Token      string
	UserInfo   string
	JWKS       string
}

TestMockResponses contains all mock response data

func GetDefaultMockResponses

func GetDefaultMockResponses() TestMockResponses

GetDefaultMockResponses provides standard mock responses for tests This generates JWKS dynamically based on the consistent test RSA key

type TokenProcessor

type TokenProcessor interface {
	ProcessToken(c echo.Context, tokenStr string, jwksConfig *JwksConfig, logger zerolog.Logger) (*cdbm.User, *util.APIError)
}

TokenProcessor interface for processing JWT tokens

Jump to

Keyboard shortcuts

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