authn

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package authn cached.go — cache decorator for Authenticator + TokenService.

CachedClient wraps an Authenticator + TokenService pair with a shared cachex-backed cache. Both Authenticate and VerifyToken share the same cache key for a given token, so a token verified via VerifyToken will be served from cache on the next Authenticate call (and vice versa) — important when middleware authenticates via Authenticator.Authenticate but business code calls TokenService.VerifyToken explicitly.

Cache semantics:

  • Hit: return cached Principal without calling the inner provider.
  • Miss: call inner provider, cache result on success.
  • Invalidate(ctx, token): remove entry; call from RevokeToken, LogoutURL, and any path that invalidates a session.

Cache key: "authn:token:" + sha256_hex(token). We hash the token so cache dumps (Redis MONITOR, MEMORY USAGE, etc.) do not leak live bearer tokens.

TTL: min(cfg.ttl, token_exp - now). A token that expires in 30s is cached for at most 30s even if cfg.ttl is 5m. This prevents serving a cached principal for an already-expired token.

Best-effort: if cache.Get/Set/Del fails, the wrapper falls through to the inner provider. A cache outage never blocks authn.

Limitations:

  • The cache does NOT enforce revocation. If a token is revoked at the IdP but Invalidate is not called, the cache will keep returning the cached Principal until the TTL expires. Callers that need revocation semantics must maintain a separate blacklist AND call Invalidate on revoke.
  • The cache assumes the inner provider's verification is deterministic for a given token within the TTL window. This is true for JWT-based providers (Casdoor, OIDC) but may not be true for introspection-based providers that check a server-side session table. For those, set TTL=0 or do not wrap.

Package authn defines Kernel's authentication and identity-management boundary.

The package is intentionally provider-neutral while the platform defaults to a Casdoor-first deployment. Casdoor/OIDC/JWKS and trusted gateway headers adapt into these contracts. Business code should depend on Principal, Authenticator and the small capability interfaces here; it should not import concrete provider SDKs.

Request authentication flow:

  1. HTTP/gRPC middleware extracts a credential or trusted gateway metadata.
  2. Authenticator verifies it and returns Principal.
  3. Principal is stored in context.
  4. Business code uses authz.Authorizer for permissions.

Provider/token flow:

  1. LoginService builds a hosted Casdoor/OIDC login URL.
  2. TokenService is a thin wrapper around the provider OAuth/OIDC flow when a service must perform callback exchange or token verification. Kernel does not become a token issuer or token store.
  3. ProfileService can enrich Principal with user/group/application data.

Identity provisioning flow:

  1. Kernel IAM DB creates the platform organization/application/group.
  2. UserAdmin/GroupAdmin/IdentityAdmin sync identity-provider projections, e.g. Casdoor users and groups.
  3. authz.RelationshipWriter projects owner/member relationships to SpiceDB.

Casdoor-first identity flow:

  1. User/password, MFA, refresh tokens, logout and browser sessions remain in Casdoor, including Casdoor's local username/password provider.
  2. UserAdmin/GroupAdmin call Casdoor APIs through the adapter; Kernel does not store users as source of truth or manage password hashes.
  3. SessionDirectory reads Casdoor sessions for display, such as online-user dashboards. It does not create or validate sessions.

Package authn defines Kernel's provider-neutral authentication contracts.

authn owns the question "who is the caller?". It deliberately does not decide whether the caller can access a business resource; that belongs to authz. Casdoor, OIDC, JWT, mTLS and API-key implementations should all adapt into these interfaces.

Index

Constants

View Source
const (
	CodeMissingCredential       = errorx.Code("AUTHN_MISSING_CREDENTIAL")
	CodeInvalidCredential       = errorx.Code("AUTHN_INVALID_CREDENTIAL")
	CodeUnauthenticated         = errorx.Code("AUTHN_UNAUTHENTICATED")
	CodeInvalidTokenRequest     = errorx.Code("AUTHN_INVALID_TOKEN_REQUEST")
	CodeIdentityBackendFailed   = errorx.Code("AUTHN_IDENTITY_BACKEND_FAILED")
	CodeIdentityObjectNotFound  = errorx.Code("AUTHN_IDENTITY_OBJECT_NOT_FOUND")
	CodeIdentityObjectConflict  = errorx.Code("AUTHN_IDENTITY_OBJECT_CONFLICT")
	CodeUnsupportedIdentityFlow = errorx.Code("AUTHN_UNSUPPORTED_IDENTITY_FLOW")
)
View Source
const (
	DefaultPrincipalJWTHeader = "X-Aisphere-Principal-JWT"
	CredentialPrincipalJWT    = "principal_jwt"
	PrincipalJWTType          = "aisphere-principal"
)
View Source
const (
	SessionStatusActive  = "active"
	SessionStatusExpired = "expired"
	SessionStatusRevoked = "revoked"
)
View Source
const (
	TrustedHeaderVerified    = "X-Aisphere-Auth-Verified"
	TrustedHeaderSubject     = "X-Aisphere-Subject"
	TrustedHeaderSubjectType = "X-Aisphere-Subject-Type"
	TrustedHeaderProvider    = "X-Aisphere-Provider"
	TrustedHeaderExternalID  = "X-Aisphere-External-ID"
	TrustedHeaderIssuer      = "X-Aisphere-Issuer"
	TrustedHeaderAudience    = "X-Aisphere-Audience"
	TrustedHeaderOwner       = "X-Aisphere-Owner"
	TrustedHeaderOrgID       = "X-Aisphere-Org-ID"
	TrustedHeaderAppID       = "X-Aisphere-App-ID"
	TrustedHeaderUsername    = "X-Aisphere-Username"
	TrustedHeaderName        = "X-Aisphere-Name"
	TrustedHeaderEmail       = "X-Aisphere-Email"
	TrustedHeaderGroups      = "X-Aisphere-Groups"
	TrustedHeaderRoles       = "X-Aisphere-Roles"
	TrustedHeaderScopes      = "X-Aisphere-Scopes"
)
View Source
const (
	SubjectTypeUser      = "user"
	SubjectTypeService   = "service"
	SubjectTypeAgent     = "agent"
	SubjectTypeWorkflow  = "workflow"
	SubjectTypeWorkload  = "workload"
	SubjectTypeAnonymous = "anonymous"
)
View Source
const (
	AuthMethodOAuth    = "oauth"
	AuthMethodOIDC     = "oidc"
	AuthMethodJWT      = "jwt"
	AuthMethodAPIKey   = "api_key"
	AuthMethodMTLS     = "mtls"
	AuthMethodSession  = "session"
	AuthMethodDevToken = "dev_token"
	AuthMethodNone     = "none"
)
View Source
const (
	CredentialBearer = "bearer"
	CredentialBasic  = "basic"
	CredentialAPIKey = "api_key"
	CredentialMTLS   = "mtls"
	CredentialCode   = "authorization_code"
)
View Source
const (
	// Casdoor group types. A user can belong to one Physical group and multiple Virtual groups.
	GroupTypePhysical = "Physical"
	GroupTypeVirtual  = "Virtual"
)
View Source
const CredentialGatewayTrusted = "gateway_trusted"
View Source
const (
	// InternalServiceTokenHeader is the default Gateway -> backend service
	// shared-secret header. It proves the request crossed the trusted Gateway
	// boundary; it does not identify the end user. User identity is still carried
	// by the Gateway-injected X-Aisphere-* Principal headers.
	InternalServiceTokenHeader = "X-Aisphere-Internal-Token"
)

Variables

This section is empty.

Functions

func ContextWithPrincipal

func ContextWithPrincipal(ctx context.Context, principal Principal) context.Context

func ErrIdentityBackendFailed

func ErrIdentityBackendFailed(message string, cause error) error

func ErrInvalidCredential

func ErrInvalidCredential(message string) error

func ErrInvalidTokenRequest

func ErrInvalidTokenRequest(message string) error

func ErrMissingCredential

func ErrMissingCredential(message string) error

func ErrUnauthenticated

func ErrUnauthenticated(message string) error

func InjectInternalServiceToken added in v0.2.4

func InjectInternalServiceToken(headers map[string]string, cfg InternalServiceTokenConfig)

InjectInternalServiceToken injects the configured Gateway-to-backend token.

func InjectTrustedHeaders added in v0.2.4

func InjectTrustedHeaders(headers map[string]string, p Principal)

InjectTrustedHeaders writes a normalized Principal to Gateway-controlled headers for downstream services configured in gateway_trusted mode.

func SignPrincipalJWT added in v0.3.0

func SignPrincipalJWT(p Principal, cfg PrincipalJWTConfig) (string, error)

func StripGatewayControlledHeaders added in v0.2.4

func StripGatewayControlledHeaders(headers map[string]string, internalTokenHeader string)

StripGatewayControlledHeaders removes every header that can only be set by Gateway after it has verified the external Casdoor/OIDC JWT. Call this at the edge before injecting trusted Principal headers and the internal service token.

func StripInternalServiceToken added in v0.2.4

func StripInternalServiceToken(headers map[string]string, headerName string)

StripInternalServiceToken removes the Gateway-to-backend shared secret header. Gateways must call this before injecting their own value so clients cannot smuggle a forged internal token through the edge.

func StripTrustedHeaders added in v0.2.4

func StripTrustedHeaders(headers map[string]string)

StripTrustedHeaders removes identity headers that must only be set by a trusted Gateway after token verification. It intentionally does not remove the internal-service-token header; use StripGatewayControlledHeaders at the edge before injecting both trusted identity and internal-call headers.

func TrustedHeaderNames added in v0.2.4

func TrustedHeaderNames() []string

TrustedHeaderNames returns all identity headers controlled by Gateway. Any inbound client-supplied values for these headers must be stripped before a verified principal is injected.

func ValidateApplication

func ValidateApplication(app Application) error

func ValidateAuthCodeExchangeRequest

func ValidateAuthCodeExchangeRequest(req AuthCodeExchangeRequest) error

func ValidateGroup

func ValidateGroup(group Group) error

func ValidateOrganization

func ValidateOrganization(org Organization) error

Types

type Application

type Application struct {
	ID             string
	ExternalID     string
	OrgID          string
	Name           string
	DisplayName    string
	ClientID       string
	ClientSecret   string
	RedirectURIs   []string
	GrantTypes     []string
	Scopes         []string
	Providers      []string
	EnablePassword bool
	EnableSignup   bool
	Attributes     AttributeSet
}

Application represents a login client/application in the identity provider.

type ApplicationAdmin

type ApplicationAdmin interface {
	CreateApplication(ctx context.Context, req CreateApplicationRequest) (Application, error)
	GetApplication(ctx context.Context, orgID, appID string) (Application, error)
	UpdateApplication(ctx context.Context, req UpdateApplicationRequest) (Application, error)
	DeleteApplication(ctx context.Context, req DeleteApplicationRequest) error
}

ApplicationAdmin manages identity-provider applications / OAuth clients.

type AssignUserToGroupRequest

type AssignUserToGroupRequest struct {
	OrgID    string
	GroupID  string
	UserID   string
	Metadata map[string]string
}

type AttributeSet

type AttributeSet map[string]any

AttributeSet carries provider-specific claims or admin metadata. Values should be JSON-serializable when they are persisted or sent to remote systems.

type AuthCodeExchangeRequest

type AuthCodeExchangeRequest struct {
	Code         string
	State        string
	RedirectURI  string
	CodeVerifier string
	OrgID        string
	AppID        string
	Metadata     map[string]string
}

AuthCodeExchangeRequest is the provider-neutral shape for OAuth code exchange.

type Authenticator

type Authenticator interface {
	Authenticate(ctx context.Context, credential Credential) (Principal, error)
}

Authenticator verifies a transport credential and returns a normalized Principal.

type CachedAuthenticator added in v0.2.4

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

CachedAuthenticator caches verified Principals for bearer JWTs.

It caches the *verification result*, not any decrypted secret. JWTs are not encrypted here; they are signed. Cache keys are SHA-256 hashes of the raw token and TTL is capped by the token's exp claim, so an expired token is never accepted from cache.

func NewCachedAuthenticator added in v0.2.4

func NewCachedAuthenticator(inner Authenticator, cache cachex.Cache, opts ...CachedAuthenticatorOption) *CachedAuthenticator

func (*CachedAuthenticator) Authenticate added in v0.2.4

func (c *CachedAuthenticator) Authenticate(ctx context.Context, credential Credential) (Principal, error)

type CachedAuthenticatorOption added in v0.2.4

type CachedAuthenticatorOption func(*CachedAuthenticator)

func WithAuthenticatorCacheTTL added in v0.2.4

func WithAuthenticatorCacheTTL(ttl time.Duration) CachedAuthenticatorOption

type CachedClient added in v0.0.3

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

CachedClient wraps an Authenticator + TokenService + LogoutService with a shared cache.

Construction:

client := casdoor.New(cfg)              // implements all three interfaces
cached := authn.NewCachedClient(client, client, client, cache,
    authn.WithCachedTTL(5*time.Minute))
_ = authn.Authenticator(cached)         // usable as Authenticator
_ = authn.TokenService(cached)          // usable as TokenService
_ = authn.LogoutService(cached)         // usable as LogoutService

All three of `auth`, `tokens` and `logout` may point to the same object (typical for the casdoor Client which implements all three). They are accepted separately so callers can mix providers (e.g. JWT verifier for Authenticate, introspection endpoint for TokenService) if needed.

func NewCachedClient added in v0.0.3

func NewCachedClient(auth Authenticator, tokens TokenService, logout LogoutService, cache cachex.Cache, opts ...CachedOption) *CachedClient

NewCachedClient wraps an Authenticator + TokenService + LogoutService with a cache.

If cache is nil, the returned CachedClient delegates every call to the inner providers without any caching. This lets callers always go through CachedClient (no nil checks) even when caching is disabled.

The `logout` parameter is accepted separately from `auth` and `tokens` so callers can mix providers. For the typical casdoor Client which implements all three, pass the same client for all three parameters.

func (*CachedClient) Authenticate added in v0.0.3

func (c *CachedClient) Authenticate(ctx context.Context, credential Credential) (Principal, error)

Authenticate verifies the credential and returns the cached Principal on hit, or delegates to the inner Authenticator on miss.

func (*CachedClient) BuildLogoutURL added in v0.2.4

func (c *CachedClient) BuildLogoutURL(ctx context.Context, req LogoutURLRequest) (LogoutURL, error)

BuildLogoutURL delegates to the inner LogoutService without caching. Logout URLs are one-shot redirect targets that include per-request state and should not be cached.

func (*CachedClient) ExchangeCode added in v0.0.3

ExchangeCode is a one-shot operation — never cached. Delegates directly.

func (*CachedClient) Invalidate added in v0.0.3

func (c *CachedClient) Invalidate(ctx context.Context, token string) error

Invalidate removes a token's cached Principal. Call this from revocation flows that bypass RevokeToken (e.g. hub's local-blacklist fallback when the IdP's RevokeToken is UNIMPLEMENTED) so the next Authenticate/VerifyToken re-queries the inner provider (or, more usefully, the hub blacklist layer rejects the call before it reaches the cache).

func (*CachedClient) RefreshToken added in v0.0.3

func (c *CachedClient) RefreshToken(ctx context.Context, req RefreshTokenRequest) (TokenSet, error)

RefreshToken is a one-shot operation — never cached. Delegates directly.

func (*CachedClient) RevokeToken added in v0.0.3

func (c *CachedClient) RevokeToken(ctx context.Context, req RevokeTokenRequest) error

RevokeToken delegates to the inner TokenService and, on success, removes the token from the cache. On failure, the cache entry is left untouched (the inner provider may have rejected the request, in which case there is nothing to invalidate; or the inner provider is UNIMPLEMENTED, in which case the caller — typically a hub-level repo — should call Invalidate explicitly after updating its own blacklist).

func (*CachedClient) VerifyToken added in v0.0.3

func (c *CachedClient) VerifyToken(ctx context.Context, req VerifyTokenRequest) (Principal, error)

VerifyToken verifies the token and returns the cached Principal on hit, or delegates to the inner TokenService on miss.

type CachedOption added in v0.0.3

type CachedOption func(*CachedClient)

CachedOption configures a CachedClient.

func WithCachedTTL added in v0.0.3

func WithCachedTTL(ttl time.Duration) CachedOption

WithCachedTTL sets the maximum cache TTL. The effective TTL for a given token is min(this, token_exp - now). Default is 5 minutes. Set to 0 to effectively disable caching (every call goes to the inner provider).

type CallbackRequest

type CallbackRequest struct {
	Code          string
	State         string
	ExpectedState string
	RedirectURI   string
	OrgID         string
	AppID         string
	Metadata      map[string]string
}

CallbackRequest is the provider-neutral OAuth/OIDC callback payload.

type CallbackResult

type CallbackResult struct {
	Tokens    TokenSet
	Principal Principal
	State     string
	Provider  string
}

CallbackResult is the result of a successful browser callback flow.

type CompositeAuthenticator added in v0.2.4

type CompositeAuthenticator struct {
	Primary   Authenticator
	Secondary Authenticator
}

CompositeAuthenticator tries Primary first and falls back to Secondary only when the primary credential is missing/invalid for migration-friendly hybrid modes. Avoid using this as a long-term production default; prefer one clear authn mode per service.

func (CompositeAuthenticator) Authenticate added in v0.2.4

func (a CompositeAuthenticator) Authenticate(ctx context.Context, cred Credential) (Principal, error)

type CreateApplicationRequest

type CreateApplicationRequest struct {
	Application    Application
	IdempotencyKey string
	Metadata       map[string]string
}

type CreateGroupRequest

type CreateGroupRequest struct {
	Group          Group
	IdempotencyKey string
	Metadata       map[string]string
}

type CreateOrganizationRequest

type CreateOrganizationRequest struct {
	Organization   Organization
	IdempotencyKey string
	Metadata       map[string]string
}

type CreateUserRequest added in v0.2.4

type CreateUserRequest struct {
	User           User
	IdempotencyKey string
	Metadata       map[string]string
}

CreateUserRequest creates an identity-provider user without exposing any concrete provider SDK type. Password credentials, MFA and hosted login state are owned by the backing identity provider such as Casdoor.

type Credential

type Credential struct {
	Scheme   string
	Token    string
	Metadata map[string]string
}

Credential is authentication input extracted by HTTP/gRPC middleware.

func BearerCredential

func BearerCredential(header string) (Credential, bool)

type DeleteApplicationRequest

type DeleteApplicationRequest struct {
	AppID    string
	OrgID    string
	Hard     bool
	Metadata map[string]string
}

type DeleteGroupRequest

type DeleteGroupRequest struct {
	OrgID     string
	GroupID   string
	Recursive bool
	Metadata  map[string]string
}

type DeleteOrganizationRequest

type DeleteOrganizationRequest struct {
	OrgID    string
	Hard     bool
	Metadata map[string]string
}

type DeleteUserRequest added in v0.2.4

type DeleteUserRequest struct {
	OrgID    string
	UserID   string
	Hard     bool
	Metadata map[string]string
}

DeleteUserRequest deletes or disables an identity-provider user.

type Group

type Group struct {
	ID          string
	ExternalID  string
	OrgID       string
	ParentID    string
	Name        string
	DisplayName string
	Type        string
	Path        string
	Users       []string
	Attributes  AttributeSet
}

Group models Casdoor's organization tree/groups without coupling Kernel to Casdoor names. Group.Type can be physical, virtual, team, etc.

type GroupAdmin

type GroupAdmin interface {
	CreateGroup(ctx context.Context, req CreateGroupRequest) (Group, error)
	GetGroup(ctx context.Context, orgID, groupID string) (Group, error)
	ListGroups(ctx context.Context, filter GroupFilter) ([]Group, error)
	UpdateGroup(ctx context.Context, req UpdateGroupRequest) (Group, error)
	DeleteGroup(ctx context.Context, req DeleteGroupRequest) error
	AssignUserToGroup(ctx context.Context, req AssignUserToGroupRequest) error
	RemoveUserFromGroup(ctx context.Context, req AssignUserToGroupRequest) error
}

GroupAdmin manages app/org group trees. Casdoor maps this naturally to organization groups with ParentGroup.

type GroupFilter

type GroupFilter struct {
	OrgID    string
	ParentID string
	Type     string
	UserID   string
	Limit    int
	Offset   int
}

type IdentityAdmin

IdentityAdmin is the external identity-provider management surface expected from adapters such as Casdoor. It is deliberately not Kernel's canonical IAM storage API.

Use IdentityAdmin only in IAM provisioning/sync adapters after platform-level authorization has already been checked. Business services and domain code should depend on iamx.Service/iamx.Directory for users, organizations, groups and memberships. That split keeps provider-side projections separate from the Kernel IAM control-plane facts.

func NoopAdmin

func NoopAdmin() IdentityAdmin

NoopAdmin returns an IdentityAdmin that reports unsupported operations. Use it as a safe default when identity provisioning is explicitly disabled.

type IdentityProfile

type IdentityProfile struct {
	Principal Principal

	// User is the canonical user projection from the identity provider when it
	// can be read. It may be zero when only token claims were available.
	User User

	// Groups contains expanded group objects. Principal.Groups and User.Groups
	// are usually only group IDs/names; this slice carries display names, parent
	// IDs and group type when available.
	Groups []Group

	// CurrentApplication is the login/OIDC application used by the current flow.
	// A user does not usually "belong" to an application in the same way they
	// belong to a group; the application here means the OAuth client that issued
	// the token or handled the login.
	CurrentApplication Application

	Warnings   []string
	Attributes AttributeSet
}

IdentityProfile is the normalized post-login identity snapshot used by handlers, middleware and Kernel IAM sync logic.

func (IdentityProfile) GroupIDs

func (p IdentityProfile) GroupIDs() []string

func (IdentityProfile) HasFullUser

func (p IdentityProfile) HasFullUser() bool

func (IdentityProfile) IsPartial

func (p IdentityProfile) IsPartial() bool

type IdentityProfileRequest

type IdentityProfileRequest struct {
	Principal  Principal
	Token      string
	Credential Credential

	OrgID string
	AppID string

	IncludeUser               bool
	IncludeGroups             bool
	IncludeCurrentApplication bool

	// AllowPartial returns Principal plus whatever profile data can be read when
	// admin/read APIs fail. This is useful for normal request paths where token
	// authentication must not fail only because optional profile enrichment is
	// unavailable.
	AllowPartial bool

	Metadata map[string]string
}

IdentityProfileRequest controls how much identity-provider data should be loaded after login or token verification.

For request handling, pass Principal when you already have one from Authenticate/VerifyToken. For test tools and middleware, pass Token or Credential and the implementation will authenticate first.

type InternalServiceTokenConfig added in v0.2.4

type InternalServiceTokenConfig struct {
	Enabled    bool   `json:"enabled" yaml:"enabled"`
	HeaderName string `json:"header" yaml:"header"`
	Token      string `json:"token" yaml:"token"`
}

InternalServiceTokenConfig configures the simple first-phase Gateway -> backend trust boundary.

It is intentionally a shared-secret mechanism for MVP deployments. Production can later add NetworkPolicy and mTLS without changing the authn/accessx contract.

func (InternalServiceTokenConfig) Header added in v0.2.4

func (InternalServiceTokenConfig) Normalized added in v0.2.4

func (InternalServiceTokenConfig) ValidateToken added in v0.2.4

func (c InternalServiceTokenConfig) ValidateToken(got string) bool

type LoginService

type LoginService interface {
	BuildLoginURL(ctx context.Context, req LoginURLRequest) (LoginURL, error)
	HandleCallback(ctx context.Context, req CallbackRequest) (CallbackResult, error)
}

LoginService is the provider-neutral browser login contract used by HTTP handlers, examples and application boot code. Implementations can use Casdoor/OIDC SDKs internally, but callers only depend on Kernel authn types.

type LoginURL

type LoginURL struct {
	URL         string
	RedirectURI string
	State       string
	Scope       string
	Provider    string
	OrgID       string
	AppID       string
}

LoginURL is the safe redirect target returned by LoginService.

type LoginURLRequest

type LoginURLRequest struct {
	RedirectURI string
	State       string
	Scope       string
	OrgID       string
	AppID       string
	Metadata    map[string]string
}

LoginURLRequest asks an identity provider for a hosted login URL.

type LogoutService added in v0.0.7

type LogoutService interface {
	BuildLogoutURL(ctx context.Context, req LogoutURLRequest) (LogoutURL, error)
}

LogoutService builds identity-provider hosted logout (end-session) URLs.

Implementations construct the provider-specific end-session endpoint URL with the required OIDC RP-Initiated Logout parameters (id_token_hint, post_logout_redirect_uri, state, client_id). The returned LogoutURL.URL is the full redirect target for a 302 response.

type LogoutURL added in v0.0.7

type LogoutURL struct {
	URL                   string
	PostLogoutRedirectURI string
	State                 string
	Provider              string
	OrgID                 string
	AppID                 string
}

LogoutURL is the safe redirect target returned by LogoutService.

type LogoutURLRequest added in v0.0.7

type LogoutURLRequest struct {
	PostLogoutRedirectURI string
	IDTokenHint           string
	State                 string
	OrgID                 string
	AppID                 string
	Metadata              map[string]string
}

LogoutURLRequest asks an identity provider for a hosted logout (end-session) URL.

type ManagementProvider added in v0.1.16

type ManagementProvider interface {
	Provider
	IdentityAdmin
}

ManagementProvider extends Provider with user/organization/application/group administration. It is intended for IAM control-plane code and provisioning, not normal business request handlers.

Kernel's default implementation is authn/casdoor.Client. Business packages should not import the Casdoor SDK directly.

type Organization

type Organization struct {
	ID          string
	ExternalID  string
	Name        string
	DisplayName string
	OwnerID     string
	ParentID    string
	Tags        []string
	Enabled     bool
	Attributes  AttributeSet
}

Organization is Kernel's identity-side organization projection. Kernel IAM DB can store richer business org metadata; this type is for authn provider sync.

type OrganizationAdmin

type OrganizationAdmin interface {
	CreateOrganization(ctx context.Context, req CreateOrganizationRequest) (Organization, error)
	GetOrganization(ctx context.Context, orgID string) (Organization, error)
	UpdateOrganization(ctx context.Context, req UpdateOrganizationRequest) (Organization, error)
	DeleteOrganization(ctx context.Context, req DeleteOrganizationRequest) error
}

OrganizationAdmin manages identity-provider organizations.

type Principal

type Principal struct {
	SubjectID   string
	SubjectType string

	Provider   string
	ExternalID string
	Issuer     string
	Audience   []string

	TenantID  string
	OrgID     string
	AppID     string
	ProjectID string

	Username string
	Name     string
	Email    string
	Phone    string

	Roles  []string
	Groups []string
	Scopes []string

	// AuthMethod records how the subject authenticated. It is intentionally a
	// string instead of an enum type so adapters can preserve provider-specific
	// methods while still using the AuthMethod* constants above.
	AuthMethod string

	Attributes AttributeSet
	IssuedAt   time.Time
	ExpiresAt  time.Time
}

Principal is the normalized identity passed to business code.

SubjectID must be stable inside Kernel. For Casdoor this should normally map from the Casdoor user's stable UUID when available, not only owner/name.

func Anonymous

func Anonymous() Principal

func MustPrincipal

func MustPrincipal(ctx context.Context) (Principal, error)

func PrincipalFromContext

func PrincipalFromContext(ctx context.Context) (Principal, bool)

func PrincipalFromTrustedHeaders added in v0.2.4

func PrincipalFromTrustedHeaders(headers map[string]string) (Principal, bool)

PrincipalFromTrustedHeaders reconstructs a Principal that was already verified by Gateway. It must only be used on traffic that cannot bypass the trusted Gateway boundary.

func (Principal) Attribute

func (p Principal) Attribute(key string) any

func (Principal) Expired

func (p Principal) Expired(now time.Time) bool

func (Principal) HasGroup

func (p Principal) HasGroup(group string) bool

func (Principal) HasRole

func (p Principal) HasRole(role string) bool

func (Principal) HasScope

func (p Principal) HasScope(scope string) bool

func (Principal) IsAnonymous

func (p Principal) IsAnonymous() bool

func (Principal) IsAuthenticated

func (p Principal) IsAuthenticated() bool

func (Principal) Normalize

func (p Principal) Normalize() Principal

type PrincipalJWTAuthenticator added in v0.3.0

type PrincipalJWTAuthenticator struct{ Config PrincipalJWTConfig }

func (PrincipalJWTAuthenticator) Authenticate added in v0.3.0

func (a PrincipalJWTAuthenticator) Authenticate(ctx context.Context, cred Credential) (Principal, error)

type PrincipalJWTClaims added in v0.3.0

type PrincipalJWTClaims struct {
	jwt.RegisteredClaims
	Type        string   `json:"typ,omitempty"`
	SubjectType string   `json:"subject_type,omitempty"`
	Provider    string   `json:"provider,omitempty"`
	ExternalID  string   `json:"external_id,omitempty"`
	TenantID    string   `json:"tenant_id,omitempty"`
	OrgID       string   `json:"org_id,omitempty"`
	AppID       string   `json:"app_id,omitempty"`
	ProjectID   string   `json:"project_id,omitempty"`
	Username    string   `json:"username,omitempty"`
	Name        string   `json:"name,omitempty"`
	Email       string   `json:"email,omitempty"`
	Phone       string   `json:"phone,omitempty"`
	Roles       []string `json:"roles,omitempty"`
	Groups      []string `json:"groups,omitempty"`
	Scopes      []string `json:"scopes,omitempty"`
	AuthMethod  string   `json:"auth_method,omitempty"`
}

func (PrincipalJWTClaims) Principal added in v0.3.0

func (c PrincipalJWTClaims) Principal() Principal

type PrincipalJWTConfig added in v0.3.0

type PrincipalJWTConfig struct {
	Enabled   bool          `json:"enabled" yaml:"enabled"`
	Header    string        `json:"header" yaml:"header"`
	Secret    string        `json:"secret" yaml:"secret"`
	Issuer    string        `json:"issuer" yaml:"issuer"`
	Audience  []string      `json:"audience" yaml:"audience"`
	TTL       time.Duration `json:"ttl_ns" yaml:"ttl_ns"`
	ClockSkew time.Duration `json:"clock_skew_ns" yaml:"clock_skew_ns"`
}

func (PrincipalJWTConfig) Normalized added in v0.3.0

func (c PrincipalJWTConfig) Normalized() PrincipalJWTConfig

type ProfileService

type ProfileService interface {
	GetIdentityProfile(ctx context.Context, req IdentityProfileRequest) (IdentityProfile, error)
}

ProfileService enriches an authenticated Principal with identity-provider profile data. It is intentionally provider-neutral: callers should not have to know whether the backing system is Casdoor, OIDC, LDAP, SCIM, etc.

type Provider added in v0.1.16

Provider is Kernel's default runtime authentication surface.

Business code must depend on this interface (or one of its smaller sub-interfaces), not on concrete identity providers such as Casdoor. Casdoor/OIDC/JWT implementations live behind this contract.

type ProviderSet added in v0.1.16

type ProviderSet struct {
	Runtime    Provider
	Management ManagementProvider

	// Optional identity-provider backed read models. In Casdoor-first deployments
	// this is implemented by the Casdoor adapter and is used only for display
	// surfaces such as online-user/session dashboards.
	Sessions SessionDirectory
}

ProviderSet names the Kernel authn capabilities that boot/server wiring can expose without leaking a concrete provider implementation.

func (ProviderSet) Authenticator added in v0.1.16

func (p ProviderSet) Authenticator() Authenticator

func (ProviderSet) IdentityAdmin added in v0.1.16

func (p ProviderSet) IdentityAdmin() IdentityAdmin

func (ProviderSet) Login added in v0.1.16

func (p ProviderSet) Login() LoginService

func (ProviderSet) Logout added in v0.2.4

func (p ProviderSet) Logout() LogoutService

func (ProviderSet) SessionDirectory added in v0.2.4

func (p ProviderSet) SessionDirectory() SessionDirectory

func (ProviderSet) Tokens added in v0.1.16

func (p ProviderSet) Tokens() TokenService

type RefreshTokenRequest

type RefreshTokenRequest struct {
	RefreshToken string
	Scope        string
	OrgID        string
	AppID        string
	Metadata     map[string]string
}

type RevokeTokenRequest

type RevokeTokenRequest struct {
	Token     string
	TokenType string
	OrgID     string
	AppID     string
	Metadata  map[string]string
}

type Session added in v0.2.4

type Session struct {
	ID                string
	Provider          string
	ProviderSessionID string

	OrgID       string
	Application string

	SubjectID   string
	SubjectType string
	Username    string
	DisplayName string
	Email       string

	Status    string
	UserAgent string
	IP        string

	CreatedAt  time.Time
	UpdatedAt  time.Time
	ExpiresAt  time.Time
	LastSeenAt time.Time

	Attributes AttributeSet
}

Session is Kernel's provider-neutral view of an identity-provider session.

Casdoor-first deployments must treat Casdoor as the source of truth for sessions. Kernel does not create, validate, refresh or persist sessions. This type is only used for admin/user-facing read models such as "who is online", "which users have active sessions", or "show my logged-in devices".

func (Session) IsActive added in v0.2.4

func (s Session) IsActive(now time.Time) bool

type SessionDirectory added in v0.2.4

type SessionDirectory interface {
	GetSession(ctx context.Context, orgID, sessionID string) (Session, error)
	ListSessions(ctx context.Context, filter SessionFilter) ([]Session, error)
	SummarizeSessions(ctx context.Context, filter SessionFilter) (SessionSummary, error)
}

SessionDirectory reads identity-provider sessions for display and operational visibility. It deliberately does not create or validate sessions; login, logout, refresh-token and browser session lifecycle remain owned by Casdoor or another external identity provider.

type SessionFilter added in v0.2.4

type SessionFilter struct {
	SessionID         string
	ProviderSessionID string
	OrgID             string
	Application       string
	SubjectID         string
	Username          string
	Email             string
	Status            string
	OnlineOnly        bool
	Limit             int
	Offset            int
}

type SessionSummary added in v0.2.4

type SessionSummary struct {
	TotalSessions  int
	ActiveSessions int
	OnlineUsers    int
	ByApplication  map[string]int
}

type TokenAuthenticator

type TokenAuthenticator struct {
	Verifier TokenVerifier
	Issuer   string
	Audience []string
	OrgID    string
	AppID    string
}

TokenAuthenticator adapts a TokenService/TokenVerifier to Authenticator.

func (TokenAuthenticator) Authenticate

func (a TokenAuthenticator) Authenticate(ctx context.Context, credential Credential) (Principal, error)

type TokenService

type TokenService interface {
	ExchangeCode(ctx context.Context, req AuthCodeExchangeRequest) (TokenSet, Principal, error)
	RefreshToken(ctx context.Context, req RefreshTokenRequest) (TokenSet, error)
	VerifyToken(ctx context.Context, req VerifyTokenRequest) (Principal, error)
	RevokeToken(ctx context.Context, req RevokeTokenRequest) error
}

TokenService covers OAuth/OIDC token flows such as Casdoor code exchange, refresh, validation and revocation.

type TokenSet

type TokenSet struct {
	AccessToken  string
	RefreshToken string
	IDToken      string
	TokenType    string
	Scope        string
	ExpiresAt    time.Time
	Raw          AttributeSet
}

TokenSet is the result of OAuth/OIDC token operations.

type TokenVerifier

type TokenVerifier func(ctx context.Context, req VerifyTokenRequest) (Principal, error)

TokenVerifier adapts JWT/OIDC libraries into Authenticator.

type TrustedHeaderAuthenticator added in v0.2.4

type TrustedHeaderAuthenticator struct {
	// InternalToken optionally requires a Gateway-to-backend shared secret before
	// trusting X-Aisphere-* identity headers. Use this in gateway_trusted mode.
	InternalToken InternalServiceTokenConfig
}

TrustedHeaderAuthenticator trusts a Principal already verified and injected by Gateway. Use only behind network policy / mTLS / service-token boundaries that prevent clients from bypassing Gateway.

func (TrustedHeaderAuthenticator) Authenticate added in v0.2.4

func (a TrustedHeaderAuthenticator) Authenticate(ctx context.Context, credential Credential) (Principal, error)

type UpdateApplicationRequest

type UpdateApplicationRequest struct {
	Application Application
	Metadata    map[string]string
}

type UpdateGroupRequest

type UpdateGroupRequest struct {
	Group    Group
	Metadata map[string]string
}

type UpdateOrganizationRequest

type UpdateOrganizationRequest struct {
	Organization Organization
	Metadata     map[string]string
}

type UpdateUserRequest added in v0.2.4

type UpdateUserRequest struct {
	User     User
	Metadata map[string]string
}

UpdateUserRequest updates an identity-provider user projection.

type User

type User struct {
	ID          string
	ExternalID  string
	Provider    string
	OrgID       string
	Username    string
	DisplayName string
	Email       string
	Phone       string
	Roles       []string
	Groups      []string
	Enabled     bool
	Attributes  AttributeSet
}

User mirrors identity-provider user data without importing a provider SDK.

type UserAdmin added in v0.2.4

type UserAdmin interface {
	CreateUser(ctx context.Context, req CreateUserRequest) (User, error)
	UpdateUser(ctx context.Context, req UpdateUserRequest) (User, error)
	DeleteUser(ctx context.Context, req DeleteUserRequest) error
	UpsertUser(ctx context.Context, user User) (User, error)
	DisableUser(ctx context.Context, orgID, userID string) error
}

UserAdmin manages identity-provider users. Passwords, MFA and session state are owned by the backing identity provider, such as Casdoor. Kernel only exposes the management surface; it must not store password hashes or local sessions.

type UserDirectory

type UserDirectory interface {
	GetUser(ctx context.Context, orgID, userID string) (User, error)
	FindUsers(ctx context.Context, filter UserFilter) ([]User, error)
}

UserDirectory reads identity-provider users. Business modules should usually go through Kernel IAM service, not a provider SDK directly.

type UserFilter

type UserFilter struct {
	ID         string
	ExternalID string
	OrgID      string
	Username   string
	Email      string
	Phone      string
	GroupID    string
	Role       string
	Limit      int
	Offset     int
}

type VerifyTokenRequest

type VerifyTokenRequest struct {
	Token     string
	TokenType string
	Issuer    string
	Audience  []string
	OrgID     string
	AppID     string
	Leeway    time.Duration
	Metadata  map[string]string
}

Directories

Path Synopsis
Package callback contains reusable HTTP helpers for browser based authn callback flows.
Package callback contains reusable HTTP helpers for browser based authn callback flows.
Package casdoor adapts the official Casdoor Go SDK to Kernel authn contracts.
Package casdoor adapts the official Casdoor Go SDK to Kernel authn contracts.
Package oidcx provides provider-neutral OIDC/JWKS JWT verification.
Package oidcx provides provider-neutral OIDC/JWKS JWT verification.

Jump to

Keyboard shortcuts

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