Skip to main content
Version: 0.4.x(Latest)

Introduction​

services.Auth() returns the authentication and authorization namespace. Source plugins access it through services.Auth(), while dynamic plugins declare service: auth in plugin.yaml and access it through the pluginbridge.Default().Auth() client. It contains two sub-capabilities:

  • Token() handles tenant token selection, tenant switching, and platform admin impersonation token handoff.
  • Authz() handles permission view reading, permission checking, and platform admin checking.

This namespace does not expose the host's JWT signing implementation, session storage, role tables, menu tables, or permission tables. Plugins only initiate token or authorization-related operations through stable domain contracts.

Capability Phase: Runtime

Supported Plugin Types: Source plugins, Dynamic plugins

Capability Design​

Sub-Capability System​

The Auth capability uses a dual sub-capability model, handling authentication tokens and authorization checks separately:

Token Sub-Capability​

Token() handles tenant token handoff, including host signing, token ID, online session state, and permission cache warm-up. Plugins must still complete business authorization and audit checks before calling.

Authz Sub-Capability​

Authz() handles authorization checks, returning only plugin-visible views or boolean results without exposing host role, menu, or permission table structures. Trusted source plugins that need to replace role permission sets should use services.Admin().Auth().Authz().ReplaceRolePermissions.

Dynamic Plugin Identity Acquisition​

After declaring service: auth in plugin.yaml, dynamic plugins access the Token() sub-capability through the pluginbridge.Default().Auth() client. The authentication result for dynamic route requests is also injected by the host into BridgeRequestEnvelopeV1.Identity.

Interface Definitions​

Token Sub-Capability Interface​

MethodDescription
SelectTenantConsumes a pre-login PreToken and issues an AccessToken and RefreshToken bound to the target tenant
SwitchTenantValidates target tenant membership, revokes the current token, and issues a new tenant token
IssueImpersonationTokenIssues an impersonation token for a platform admin to enter the target tenant
RevokeImpersonationTokenValidates and revokes an impersonation access token

Authz Sub-Capability Interface​

MethodDescription
BatchGetPermissionsBatch reads visible permission views; missing results do not reveal specific reasons
HasPermissionChecks whether the current operator has the specified permission within the current scope
IsPlatformAdminChecks whether the specified user has the platform-wide data role

Dynamic Plugin Interface​

Dynamic plugins declare authorized methods through hostServices.auth:

Dynamic MethodDescription
tenant.selectConsumes a pre-login PreToken and issues a token bound to the target tenant
tenant.switchValidates target tenant membership, revokes the current token, and issues a new tenant token
impersonation_token.issueIssues an impersonation token for a platform admin to enter the target tenant
impersonation_token.revokeValidates and revokes an impersonation access token

Usage​

Source Plugin Usage​

Source plugins access Token() and Authz() sub-capabilities through services.Auth():

// Tenant selection: issue a token bound to the target tenant
tenantToken, err := services.Auth().Token().SelectTenant(ctx, token.SelectTenantInput{
PreToken: preToken,
TenantID: tenantID,
})

// Tenant switching: validate membership and issue a new token
tenantToken, err = services.Auth().Token().SwitchTenant(ctx, token.SwitchTenantInput{
BearerToken: bearerToken,
TenantID: targetTenantID,
})

// Permission check
has, err := services.Auth().Authz().HasPermission(ctx, capabilityCtx, permissionKey)

// Platform admin check
isAdmin, err := services.Auth().Authz().IsPlatformAdmin(ctx, capabilityCtx, userID)

Trusted source plugins that need to replace role permission sets:

err := services.Admin().Auth().Authz().ReplaceRolePermissions(ctx, capabilityCtx, roleID, permissions)

Dynamic Plugin Usage​

Dynamic plugins declare the auth service and authorized methods in plugin.yaml:

hostServices:
- service: auth
methods:
- tenant.select
- tenant.switch

Dynamic plugins call through the pluginbridge.Default().Auth() client:

authSvc := pluginbridge.Default().Auth()

// Tenant selection: issue a token bound to the target tenant
tenantToken, err := authSvc.Token().SelectTenant(ctx, token.SelectTenantInput{
PreToken: preToken,
TenantID: tenantID,
})

// Tenant switching: validate membership and issue a new token
tenantToken, err = authSvc.Token().SwitchTenant(ctx, token.SwitchTenantInput{
BearerToken: bearerToken,
TenantID: targetTenantID,
})

Design Constraints​

  • Plugins do not directly issue JWTs. Signing, keys, expiration policies, and session registration are all controlled by the host authentication service.
  • Tenant switching must be validated. SwitchTenant validates membership and revokes the old token. Clients must continue requests with the new token.
  • Authorization reads do not expose permission tables. Authz() returns only plugin-visible views or boolean results without exposing host role, menu, or permission table structures.
  • Impersonation tokens require caller-side auditing. Plugins should log who is impersonating into which tenant and for what reason.