Documentation
¶
Overview ¶
Package iam authenticates requests using Tupic IAM (Keycloak) JWTs.
The package is generic over the service's user entity: JWT validation, claims parsing, and actor construction are shared, while user resolution (find-or-create against the service's user store) is delegated to a service-supplied UserResolver.
Token kinds ¶
Two token shapes arrive at Authenticate:
- Service-account tokens carry service_account_client_id. They produce a service actor and never touch the user store — internal machine clients have no user entity.
- User tokens produce a user actor plus the service's user entity, provisioned by the UserResolver on first sight.
Admin-role hydration ¶
Keycloak access tokens may omit realm roles. Authenticate builds the actor from whatever roles the token carries (so most requests pay nothing). Routes that actually need accurate roles — admin routes — call EnsureRoles, which fetches them from the userinfo endpoint when the actor has none. The HTTP layer wires this as an explicit middleware on the admin route group (see echo.EnsureRoles); there is no hidden per-request flag.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Authenticator ¶
type Authenticator[U any] struct { // contains filtered or unexported fields }
Authenticator validates Bearer tokens against the Tupic IAM (Keycloak) JWKS endpoint and resolves the service's user entity via the UserResolver.
func New ¶
func New[U any](cfg Config, resolver UserResolver[U], opts ...Option) *Authenticator[U]
func (*Authenticator[U]) Authenticate ¶
func (a *Authenticator[U]) Authenticate( ctx context.Context, token string, ) (*authorization.Actor, *U, error)
Authenticate verifies the token signature and claims, then builds the caller's identity from the token alone: a service actor for service-account tokens, or a user actor plus the resolved user entity for user tokens.
Realm roles are taken as-is from the token; routes that need them complete call EnsureRoles.
func (*Authenticator[U]) EnsureRoles ¶
func (a *Authenticator[U]) EnsureRoles( ctx context.Context, token string, actor *authorization.Actor, ) (*authorization.Actor, error)
EnsureRoles guarantees the actor's realm roles are populated, fetching them from the userinfo endpoint when the access token carried none. It is a no-op for actors that already have roles, for service actors, and when no userinfo endpoint is configured — so it is safe to call on any actor.
type Claims ¶
type Claims struct {
Sub string `json:"sub"`
Iss string `json:"iss"`
AuthorizedParty string `json:"azp"`
Email string `json:"email"`
PhoneNumber string `json:"phone_number"`
PreferredUsername string `json:"preferred_username"`
GivenName string `json:"given_name"`
FamilyName string `json:"family_name"`
CountryISO string `json:"country_iso"`
Locale string `json:"locale"`
Exp int64 `json:"exp"`
Scope string `json:"scope"`
RealmAccess RealmAccess `json:"realm_access"`
ServiceAccountClientID string `json:"service_account_client_id"`
}
Claims holds the parsed JWT payload fields used by Tupic services.
type Config ¶
Config carries the IAM endpoints and the service identity used for admin role detection ("admin:<service>:*").
type Option ¶
type Option func(*options)
Option customizes the authenticator. The defaults are production-ready; options exist mainly for tests and unusual network setups.
func WithHTTPClient ¶
WithHTTPClient replaces the HTTP client used for the JWKS and userinfo endpoints (e.g. an in-process round-tripper in tests).
func WithJWKSCooldown ¶
WithJWKSCooldown sets the minimum interval between JWKS refetches triggered by unknown key IDs. Zero disables the cooldown. Default: 30s.
type RealmAccess ¶
type RealmAccess struct {
Roles []string `json:"roles"`
}
RealmAccess represents the realm-level role assignments in a Keycloak JWT token.
type UserResolver ¶
UserResolver finds or provisions the service's user entity from validated token claims. Implemented by each service (e.g. find-or-upsert with domain event publication, unique-username resolution).