Expose the role policy provider

Why: RDM needs a trusted, non-secret view of Backend-owned role policy without importing Backend internals or accepting a caller-supplied actor.

Evidence: The full Backend test suite passed, including public-surface and provider contract tests.

Impact: Adds optional extension surface 2.14 with actor-bound role snapshots and action decisions.

Refs: Focused role and permission system task 4
This commit is contained in:
weichen
2026-10-14 17:09:11 +00:00
parent 4d1ca60067
commit 5abd851256
6 changed files with 236 additions and 1 deletions
+3 -1
View File
@@ -36,7 +36,9 @@ import (
// ResourceAuthzQuery.Source for per-document publication authorization.
// 2.13.0-experimental: optional AccountDirectoryProvider and trusted in-process
// AccountDirectoryRegistrar for scoped, current account candidate decisions.
const SurfaceVersion = "2.13.0-experimental"
// 2.14.0-experimental: optional RolePolicyProvider for the Backend-owned
// single-effective-role policy consumed by trusted in-process domains.
const SurfaceVersion = "2.14.0-experimental"
// ErrNotLinked 表示进程没有空白导入 link 包,Main 无法启动服务。
var ErrNotLinked = errors.New("extension: runner not linked; blank-import agent-system-backend/pkg/extension/link")
+1
View File
@@ -41,6 +41,7 @@ type Handler func(ctx context.Context, h Host, req Request) (any, error)
// 可选能力接口(type assertion 获取,断言失败=明确报错):
// - AdminProvider — EXT-18:调用方平台管理角色查询
// - SurfaceHost — EXT-17:页面保存/读取
// - RolePolicyProvider — Backend 权威职位与动作默认/上限
type Host interface {
// PluginID 返回注册处理器的插件标识(形如 rdm)。
PluginID() string
+44
View File
@@ -0,0 +1,44 @@
package extension
import "context"
const RolePolicySchemaVersion = 1
type RolePermission struct {
Allowed bool `json:"allowed"`
CapAllowed bool `json:"capAllowed"`
}
// RolePolicySnapshot contains authorization metadata only. It intentionally
// excludes profile contact fields and credentials.
type RolePolicySnapshot struct {
SchemaVersion int `json:"schemaVersion"`
UserID string `json:"userId"`
Owner string `json:"owner"`
AccountEnabled bool `json:"accountEnabled"`
BindingID string `json:"bindingId,omitempty"`
RoleID string `json:"roleId,omitempty"`
RoleName string `json:"roleName,omitempty"`
RoleDescription string `json:"roleDescription,omitempty"`
RoleEnabled bool `json:"roleEnabled"`
RoleVersion int64 `json:"roleVersion,omitempty"`
AuthorityEpoch int64 `json:"authorityEpoch"`
Permissions map[string]RolePermission `json:"permissions"`
}
type RoleActionDecision struct {
ActionID string `json:"actionId"`
RoleID string `json:"roleId,omitempty"`
Allowed bool `json:"allowed"`
CapAllowed bool `json:"capAllowed"`
AuthorityEpoch int64 `json:"authorityEpoch"`
Reason string `json:"reason,omitempty"`
}
// RolePolicyProvider is optional on a trusted dispatch Host. Its actor is
// bound by the Backend; callers cannot supply or replace that actor.
type RolePolicyProvider interface {
CurrentRolePolicy(context.Context) (RolePolicySnapshot, error)
RolePolicyForUser(context.Context, string) (RolePolicySnapshot, error)
CheckRoleAction(context.Context, string, string) (RoleActionDecision, error)
}
+8
View File
@@ -79,6 +79,14 @@ ResetCompiled
ResourceAuthorizer
ResourceAuthorizerV2
ResourceAuthzQuery
RoleActionDecision
RolePermission
RolePolicyProvider
RolePolicyProvider.CheckRoleAction
RolePolicyProvider.CurrentRolePolicy
RolePolicyProvider.RolePolicyForUser
RolePolicySchemaVersion
RolePolicySnapshot
SetRunner
SetScopedHostFactory
SurfaceHost