aps-agent/server/core/control-plane/control-plane.ts

57 lines
2.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 控制面(A4):身份、策略、凭据、确认、审计五块绑在一起的入口。
*
* 它们不是五个独立功能,而是同一条链上的五道关:
* 身份(以谁的身份调) → 策略(这次调用允不允许) → 凭据(拿什么去调)
* → 确认(写操作要不要人点头) → 审计(发生后留痕)
* 任何一块缺失都会让「可控」变成空话,所以绑在一起注入 Core。
*
* 这一层与引擎无关:Pi 还是 Codex,走的都是 Core.invoke 这一个出口。
*/
import type { Capability } from '@aps/provider-sdk';
import type { AuditLog } from '../audit/log.js';
import type { CredentialBroker } from '../credentials/broker.js';
import type { IdentityContext } from '../identity/context.js';
import type { PendingActionStore } from '../approval/store.js';
import type { PolicyEngine } from '../policy/engine.js';
import { createRulePolicy } from '../policy/engine.js';
export interface ControlPlaneOptions {
identity: IdentityContext;
credentials: CredentialBroker;
approvals: PendingActionStore;
audit: AuditLog;
/** 能力可见性(A3.5):能力清单与这里必须是同一次过滤 */
isVisible: (capability: Capability, subject: { userId: string; tenantId: string }) => boolean;
policy?: PolicyEngine;
/** 确认卡有效期;超过就失效,必须重新发起 */
approvalTtlMs?: number;
now?: () => number;
}
export interface ControlPlane {
identity: IdentityContext;
credentials: CredentialBroker;
approvals: PendingActionStore;
audit: AuditLog;
policy: PolicyEngine;
isVisible: (capability: Capability, subject: { userId: string; tenantId: string }) => boolean;
approvalTtlMs: number;
now(): number;
}
const DEFAULT_APPROVAL_TTL_MS = 15 * 60_000;
export function createControlPlane(options: ControlPlaneOptions): ControlPlane {
return {
identity: options.identity,
credentials: options.credentials,
approvals: options.approvals,
audit: options.audit,
policy: options.policy ?? createRulePolicy(),
isVisible: options.isVisible,
approvalTtlMs: options.approvalTtlMs ?? DEFAULT_APPROVAL_TTL_MS,
now: options.now ?? Date.now,
};
}