iam

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jun 14, 2026 License: MIT Imports: 15 Imported by: 0

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

type Config struct {
	Issuer      string
	JwksURL     string
	ServiceName string
}

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

func WithHTTPClient(c *http.Client) Option

WithHTTPClient replaces the HTTP client used for the JWKS and userinfo endpoints (e.g. an in-process round-tripper in tests).

func WithJWKSCooldown

func WithJWKSCooldown(d time.Duration) Option

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

type UserResolver[U any] interface {
	Resolve(ctx context.Context, c *Claims) (*U, error)
}

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).

type UserResolverFunc

type UserResolverFunc[U any] func(ctx context.Context, c *Claims) (*U, error)

UserResolverFunc adapts a plain function to the UserResolver interface.

func (UserResolverFunc[U]) Resolve

func (f UserResolverFunc[U]) Resolve(ctx context.Context, c *Claims) (*U, error)

Jump to

Keyboard shortcuts

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