rbac

package
v0.4.3 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 13 Imported by: 0

README

auth/rbac

auth/rbac is the transport-neutral auth core for multi-user applications that need roles, scopes, session-backed JWTs, and opaque API tokens.

It deliberately does not own user CRUD, password hashing policy, registration, invitations, password reset, MFA, OAuth/OIDC/SSO, tenant membership, role storage, API-token storage, or audit-log storage. Those are application data and product policy.

  • UserStore: load users by ID and username from the application database.
  • PasswordVerifier: verify the submitted password against the application's stored password hash.
  • auth/jwt.Manager: issue and validate access/refresh tokens backed by session state.
  • auth/store/redissession: shared Redis session storage for multi-instance deployments.
  • auth/store.MemoryStore: in-process session storage for development or one-process internal tools.
  • Lockout: NewService defaults to NewMemoryLockout for one process; pass a Redis or SQL-backed Lockout for multi-instance deployments.
  • RolePolicy: exact match by default; pass RoleAllows when roles form a hierarchy.
  • APITokenStore: persist only token hashes, not raw API tokens.
  • Events: write audit logs or trigger compensation hooks after auth lifecycle events.

Service Setup

manager, err := authjwt.New(signingKey, sessionStore)
if err != nil {
	return err
}

authz, err := rbac.NewService(rbac.ServiceOptions{
	Users: users,
	Passwords: rbac.PasswordVerifierFunc(func(ctx context.Context, user rbac.User, password string) (bool, error) {
		return verifyPassword(user.ID, password)
	}),
	Tokens:    manager,
	APITokens: apiTokens,
	Lockout:   rbac.NewMemoryLockout(rbac.MemoryLockoutOptions{}),
})
if err != nil {
	return err
}

For multi-instance deployments, replace the default in-memory Lockout with a Redis or database-backed implementation so login failures are consistent across processes. APITokenStore should also be shared when API tokens are accepted by more than one process.

Direct Service.Login callers must provide a non-empty LoginRequest.LockoutKey. The HTTP handler derives it from the client IP and a username hash.

Principals

Successful user authentication returns an auth.Principal with:

  • Subject: user ID
  • Username: username
  • Role: current role loaded from UserStore
  • Scopes: current scopes loaded from UserStore
  • Kind: auth.PrincipalKindUser

AuthenticateBearer reloads the user on every accepted access token, so disabled users, role changes, and scope changes take effect without waiting for the access token to expire.

API tokens authenticate to auth.PrincipalKindAPIToken. They carry their own role and scopes from APITokenStore.

Boundaries

  • Login returns ok=false for invalid credentials and disabled users.
  • Store or verifier failures return error.
  • Refresh validates the refresh token, reloads the current user, then rotates the refresh token.
  • Logout revokes the refresh session.
  • API tokens are generated once, returned as plaintext once, loaded by hash, and marked used only after the service accepts them.
  • Hooks may be called concurrently and must not retain context.Context after returning.

Use auth/rbac/http when the same service should be exposed through JSON bearer HTTP routes and role/scope middleware.

Documentation

Overview

Package rbac provides role and scope based authentication primitives. Package rbac 提供基于角色与 scope 的认证基础能力。

Index

Constants

View Source
const (
	// LoginFailureInvalidCredentials means the username/password pair was rejected.
	// LoginFailureInvalidCredentials 表示 username/password 被拒绝。
	LoginFailureInvalidCredentials = "invalid_credentials"
	// LoginFailureDisabled means the user is disabled.
	// LoginFailureDisabled 表示用户已禁用。
	LoginFailureDisabled = "disabled"
	// LoginFailureLocked means the login key is locked.
	// LoginFailureLocked 表示登录 key 已锁定。
	LoginFailureLocked = "locked"
)

Variables

View Source
var (
	// ErrServiceMisconfigured reports missing Service dependencies.
	// ErrServiceMisconfigured 表示 Service 缺少依赖。
	ErrServiceMisconfigured = errors.New("rbac service is misconfigured")
	// ErrUserStoreMissing reports a missing user store.
	// ErrUserStoreMissing 表示缺少用户存储。
	ErrUserStoreMissing = errors.New("user store is required")
	// ErrPasswordVerifierMissing reports a missing password verifier.
	// ErrPasswordVerifierMissing 表示缺少密码校验器。
	ErrPasswordVerifierMissing = errors.New("password verifier is required")
	// ErrTokenManagerMissing reports a missing token manager.
	// ErrTokenManagerMissing 表示缺少 token manager。
	ErrTokenManagerMissing = errors.New("token manager is required")
	// ErrAPITokenStoreMissing reports a missing API token store.
	// ErrAPITokenStoreMissing 表示缺少 API token 存储。
	ErrAPITokenStoreMissing = errors.New("api token store is required")
	// ErrUserIDRequired reports an empty user ID.
	// ErrUserIDRequired 表示缺少 user ID。
	ErrUserIDRequired = errors.New("user id is required")
	// ErrUsernameRequired reports an empty username.
	// ErrUsernameRequired 表示缺少 username。
	ErrUsernameRequired = errors.New("username is required")
	// ErrRefreshTokenRequired reports an empty refresh token.
	// ErrRefreshTokenRequired 表示缺少 refresh token。
	ErrRefreshTokenRequired = errors.New("refresh token is required")
	// ErrBearerTokenRequired reports an empty bearer token.
	// ErrBearerTokenRequired 表示缺少 bearer token。
	ErrBearerTokenRequired = errors.New("bearer token is required")
	// ErrAPITokenIDRequired reports an empty API token ID.
	// ErrAPITokenIDRequired 表示缺少 API token ID。
	ErrAPITokenIDRequired = errors.New("api token id is required")
	// ErrLockoutMissing reports a missing login lockout.
	// ErrLockoutMissing 表示缺少登录锁定器。
	ErrLockoutMissing = authcore.ErrLockoutMissing
	// ErrLockoutKeyRequired reports an empty login lockout key.
	// ErrLockoutKeyRequired 表示缺少登录锁定 key。
	ErrLockoutKeyRequired = authcore.ErrLockoutKeyRequired
	// ErrLoginLocked reports a locked login key.
	// ErrLoginLocked 表示登录 key 已锁定。
	ErrLoginLocked = authcore.ErrLoginLocked
	// ErrEventFailed reports an auth hook failure.
	// ErrEventFailed 表示认证 hook 失败。
	ErrEventFailed = errors.New("auth event failed")
)

Functions

func HashToken

func HashToken(raw string) string

HashToken returns the stable storage hash for a bearer token. HashToken 返回 bearer token 的稳定存储 hash。

Types

type APIToken

type APIToken struct {
	ID         string
	Name       string
	Hash       string
	Prefix     string
	CreatedBy  string
	Role       string
	Scopes     []string
	ExpiresAt  time.Time
	CreatedAt  time.Time
	LastUsedAt time.Time
	Disabled   bool
}

APIToken is the stored metadata for an opaque bearer API token. Hash must be derived from the raw token; the raw token must not be stored. APIToken 是 opaque bearer API token 的存储元数据。 Hash 必须由原始 token 派生;不得存储原始 token。

func (APIToken) Principal

func (t APIToken) Principal() authcore.Principal

Principal returns the authenticated principal for t. Principal 返回 t 对应的已认证主体。

type APITokenStore

type APITokenStore interface {
	GetAPITokenByHash(ctx context.Context, hash string) (APIToken, bool, error)
	MarkAPITokenUsed(ctx context.Context, id string, at time.Time) error
	CreateAPIToken(ctx context.Context, token APIToken) error
	DeleteAPIToken(ctx context.Context, id string) (APIToken, bool, error)
}

APITokenStore persists API token metadata and usage. GetAPITokenByHash must not mutate token usage state. MarkAPITokenUsed is called only after Service accepts the token. APITokenStore 持久化 API token 元数据与使用状态。 GetAPITokenByHash 不得修改 token 使用状态。 MarkAPITokenUsed 只会在 Service 接受 token 后调用。

type CreateAPITokenRequest

type CreateAPITokenRequest struct {
	ID        string
	Name      string
	CreatedBy string
	Role      string
	Scopes    []string
	ExpiresAt time.Time
}

CreateAPITokenRequest describes a token to create. CreateAPITokenRequest 描述待创建的 token。

type CreatedAPIToken

type CreatedAPIToken struct {
	Token APIToken
	Raw   string
}

CreatedAPIToken returns public metadata and a one-time plaintext token. Token.Hash is empty; only APITokenStore receives the storage hash. CreatedAPIToken 返回公开元数据和仅展示一次的明文 token。 Token.Hash 为空;只有 APITokenStore 会收到存储 hash。

type Events

type Events struct {
	OnLoginSuccess func(context.Context, authcore.Principal) error
	OnLoginFailure func(context.Context, LoginFailure) error
	OnTokenCreated func(context.Context, APIToken) error
	OnTokenRevoked func(context.Context, APIToken) error
}

Events configures auth lifecycle hooks. Hooks may be called concurrently and must not retain ctx after returning. Events 配置认证生命周期 hook。 hook 可能并发调用,返回后不得继续持有 ctx。

type ExactRolePolicy

type ExactRolePolicy struct{}

ExactRolePolicy allows only exact role matches. ExactRolePolicy 只允许角色精确匹配。

func (ExactRolePolicy) Allows

func (ExactRolePolicy) Allows(actual string, required string) bool

Allows reports whether actual equals required. Allows 返回 actual 是否等于 required。

type IssueOptions

type IssueOptions = authjwt.IssueOptions

IssueOptions controls token issuance behavior. IssueOptions 控制 token 签发行为。

type LockedError

type LockedError = authcore.LockedError

LockedError carries the lockout expiration for ErrLoginLocked. LockedError 携带 ErrLoginLocked 的锁定过期时间。

type Lockout

type Lockout = authcore.Lockout

Lockout tracks failed login attempts for a caller-provided non-empty key. Empty keys should return ErrLockoutKeyRequired. Lockout 跟踪调用方提供的非空 key 的失败登录尝试。 空 key 应返回 ErrLockoutKeyRequired。

type LoginFailure

type LoginFailure struct {
	Username string
	UserID   string
	Reason   string
	At       time.Time
}

LoginFailure describes a rejected login attempt. LoginFailure 描述一次被拒绝的登录尝试。

type LoginRequest

type LoginRequest struct {
	Username    string
	Password    string
	SessionOnly bool
	// LockoutKey identifies the login caller and must be non-empty.
	// LockoutKey 标识登录调用方,不能为空。
	LockoutKey string
}

LoginRequest carries a login attempt. LoginRequest 保存一次登录尝试。

type MemoryLockout

type MemoryLockout = authcore.MemoryLockout

MemoryLockout tracks login failures in memory. Use NewMemoryLockout to create it; the zero value is not ready for use. MemoryLockout 在内存中跟踪登录失败。 使用 NewMemoryLockout 创建;零值不可直接使用。

func NewMemoryLockout

func NewMemoryLockout(opts MemoryLockoutOptions) *MemoryLockout

NewMemoryLockout returns an in-memory Lockout. NewMemoryLockout 返回内存版 Lockout。

type MemoryLockoutOptions

type MemoryLockoutOptions = authcore.MemoryLockoutOptions

MemoryLockoutOptions configures NewMemoryLockout. MemoryLockoutOptions 配置 NewMemoryLockout。

type PasswordVerifier

type PasswordVerifier interface {
	VerifyPassword(ctx context.Context, user User, password string) (bool, error)
}

PasswordVerifier verifies a password against a loaded user. PasswordVerifier 根据已加载用户校验密码。

type PasswordVerifierFunc

type PasswordVerifierFunc func(ctx context.Context, user User, password string) (bool, error)

PasswordVerifierFunc adapts a function to PasswordVerifier. PasswordVerifierFunc 将函数适配为 PasswordVerifier。

func (PasswordVerifierFunc) VerifyPassword

func (f PasswordVerifierFunc) VerifyPassword(ctx context.Context, user User, password string) (bool, error)

VerifyPassword calls f(ctx, user, password). VerifyPassword 调用 f(ctx, user, password)。

type RefreshResult

type RefreshResult struct {
	Principal        authcore.Principal
	AccessToken      string
	AccessExpiresAt  time.Time
	RefreshToken     string
	RefreshExpiresAt time.Time
	SessionOnly      bool
}

RefreshResult carries rotated tokens and principal. RefreshResult 保存轮换后的 token 与主体。

type RoleAllows

type RoleAllows func(actual string, required string) bool

RoleAllows adapts a function to RolePolicy. RoleAllows 将函数适配为 RolePolicy。

func (RoleAllows) Allows

func (f RoleAllows) Allows(actual string, required string) bool

Allows calls f(actual, required). Allows 调用 f(actual, required)。

type RolePolicy

type RolePolicy interface {
	Allows(actual string, required string) bool
}

RolePolicy decides whether actual satisfies required. RolePolicy 判断 actual 是否满足 required。

type Service

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

Service runs RBAC authentication flows without transport code. Service 执行与传输层无关的 RBAC 认证流程。

func NewService

func NewService(opts ServiceOptions) (*Service, error)

NewService returns a Service. APITokens is optional. Lockout defaults to NewMemoryLockout. Login requires Users, Passwords, and Tokens. NewService 返回 Service。 APITokens 可选。Lockout 默认使用 NewMemoryLockout。 登录需要 Users、Passwords 和 Tokens。

func (*Service) AuthenticateBearer

func (s *Service) AuthenticateBearer(ctx context.Context, token string) (authcore.Principal, bool, error)

AuthenticateBearer validates a user access token or API token and returns its principal. AuthenticateBearer 校验用户 access token 或 API token 并返回主体。

func (*Service) CreateAPIToken

func (s *Service) CreateAPIToken(ctx context.Context, req CreateAPITokenRequest) (CreatedAPIToken, error)

CreateAPIToken creates an opaque API token and stores only its hash. CreateAPIToken 创建 opaque API token,并且只存储 hash。

func (*Service) DeleteAPIToken

func (s *Service) DeleteAPIToken(ctx context.Context, id string) (bool, error)

DeleteAPIToken deletes an API token and emits the revoke hook when a token existed. DeleteAPIToken 删除 API token,并在 token 存在时发送吊销 hook。

func (*Service) Login

func (s *Service) Login(ctx context.Context, req LoginRequest) (Tokens, bool, error)

Login verifies credentials and issues access and refresh tokens. ok reports whether credentials were accepted. Login 校验凭据并签发 access 与 refresh token。 ok 表示凭据是否通过校验。

func (*Service) Logout

func (s *Service) Logout(ctx context.Context, refresh string) error

Logout revokes a refresh token. Logout 吊销 refresh token。

func (*Service) Refresh

func (s *Service) Refresh(ctx context.Context, refresh string) (RefreshResult, bool, error)

Refresh rotates a refresh token. ok reports whether the refresh token was accepted. Refresh 轮换 refresh token。 ok 表示 refresh token 是否通过校验。

func (*Service) ValidateAPIToken

func (s *Service) ValidateAPIToken(ctx context.Context, raw string) (authcore.Principal, bool, error)

ValidateAPIToken validates an opaque API token. ValidateAPIToken 校验 opaque API token。

type ServiceOptions

type ServiceOptions struct {
	Users     UserStore
	Passwords PasswordVerifier
	Tokens    TokenManager
	APITokens APITokenStore
	Lockout   Lockout
	Events    Events
	Now       func() time.Time
}

ServiceOptions configures NewService. ServiceOptions 配置 NewService。

type TokenManager

type TokenManager interface {
	ValidateAccessToken(ctx context.Context, token string) (authjwt.Claims, bool, error)
	ValidateRefreshToken(ctx context.Context, token string) (authjwt.Claims, bool, error)
	IssueSessionTokens(ctx context.Context, userID string, opts authjwt.IssueOptions) (access string, accessExp time.Time, refresh string, refreshExp time.Time, err error)
	RotateRefreshTokens(ctx context.Context, oldRefresh string) (authjwt.RefreshResult, bool, error)
	RevokeRefresh(ctx context.Context, refresh string) error
}

TokenManager provides user session token operations. TokenManager 提供用户 session token 操作。

type Tokens

type Tokens struct {
	Principal        authcore.Principal
	AccessToken      string
	AccessExpiresAt  time.Time
	RefreshToken     string
	RefreshExpiresAt time.Time
	SessionOnly      bool
}

Tokens carries a newly issued token pair and principal. Tokens 保存新签发的 token 对与主体。

type User

type User struct {
	ID       string
	Username string
	Role     string
	Scopes   []string
	Disabled bool
}

User is the auth-facing user state. Scopes is copied before being stored or returned. User 是认证层需要的用户状态。 Scopes 在存储或返回前会复制。

func (User) Principal

func (u User) Principal() authcore.Principal

Principal returns the authenticated principal for u. Principal 返回 u 对应的已认证主体。

type UserStore

type UserStore interface {
	GetUser(ctx context.Context, id string) (User, bool, error)
	GetUserByUsername(ctx context.Context, username string) (User, bool, error)
}

UserStore loads users for login and access-token validation. UserStore 为登录和 access token 校验加载用户。

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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