UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

199 lines (198 loc) 10 kB
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js"; import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js"; import { t as ConnectErrorDetailCodes } from "./connect-error-details-DaOfGNN8.js"; import { t as ErrorCodes } from "./gateway-error-details-w0nAGBBp.js"; import { t as INTERNAL_MESSAGE_CHANNEL } from "./message-channel-constants-2zSoJXQC.js"; import { s as isOperatorUiClient } from "./message-channel-BQrhwUEA.js"; import { d as errorShape } from "./error-codes-Bo8q2D1o.js"; import "./users-CPWrgxrZ.js"; import { o as getUserProfileRole } from "./user-profiles-4AB7AmiH.js"; import { o as readUserProfileAliasRevision } from "./user-profiles-owner-DdMEsuGt.js"; //#region src/gateway/gateway-access-revision.ts let revision = 0; /** Marks Gateway access decisions stale across asynchronously yielded reads. */ function bumpGatewayAccessRevision() { revision += 1; } function readGatewayAccessRevision() { return revision + readUserProfileAliasRevision(); } //#endregion //#region src/gateway/server-methods/gateway-client-identity.ts function isGatewayClientProfilePending(client) { return Boolean(client?.authenticatedGitHubIdentitySync && !client.authenticatedUserProfile); } function authenticatedProfileUnavailableError(message = "Authenticated profile verification is unavailable. Retry shortly; if this continues, contact a gateway administrator.", retryAfterMs = 1e3) { return errorShape(ErrorCodes.UNAVAILABLE, message, { retryable: true, retryAfterMs, details: { code: ConnectErrorDetailCodes.AUTHENTICATED_PROFILE_UNAVAILABLE } }); } function gatewayClientSenderFields(client) { if (client?.internal?.senderAttribution) return { sender: client.internal.senderAttribution }; const profile = client?.authenticatedUserProfile; if (profile) return { sender: { id: profile.profileId, ...!client?.internal?.syntheticClient ? { identity: { type: "profile", id: profile.profileId } } : {}, ...profile.displayName ? { name: profile.displayName } : {} } }; if (client?.authenticatedGitHubIdentitySync) return {}; return client?.authenticatedUserId ? { sender: { id: client.authenticatedUserId } } : {}; } /** Returns the same durable human profile identity used for session creation attribution. */ function gatewayClientSessionCreator(client) { const profile = client?.authenticatedUserProfile; return profile ? { type: "human", id: profile.profileId, ...profile.displayName ? { label: profile.displayName } : {} } : void 0; } /** Authenticated ingress facts shared by chat execution and its current caller controls. */ function resolveChatSendCallerContext(client, clientInfo = client?.connect?.client, originatingChannel = INTERNAL_MESSAGE_CHANNEL) { return { Provider: INTERNAL_MESSAGE_CHANNEL, Surface: INTERNAL_MESSAGE_CHANNEL, OriginatingChannel: originatingChannel, ChatType: "direct", ApprovalReviewerDeviceId: normalizeOptionalString(client?.connect?.device?.id), ...!isOperatorUiClient(clientInfo) ? { SenderId: clientInfo?.id, SenderName: clientInfo?.displayName, SenderUsername: clientInfo?.displayName } : {}, GatewayClientScopes: client?.connect?.scopes ?? [], GatewayClientCaps: client?.connect?.caps ?? [] }; } //#endregion //#region src/gateway/server-methods/session-creation-provenance.ts function resolveOperatorSessionCreation(client, options = {}) { if (options.allowTrustedHint && client?.internal?.sessionCreation) return client.internal.sessionCreation; const agentRuntimeIdentity = client?.internal?.agentRuntimeIdentity; if (options.allowTrustedHint && agentRuntimeIdentity?.sessionSpawnContext) return { via: "spawn", actor: { type: "agent", id: agentRuntimeIdentity.agentId }, requesterSessionKey: agentRuntimeIdentity.sessionKey, ...agentRuntimeIdentity.sessionSpawnContext.completionOwnerSessionKey ? { completionOwnerSessionKey: agentRuntimeIdentity.sessionSpawnContext.completionOwnerSessionKey } : {}, inheritedToolPolicy: agentRuntimeIdentity.sessionSpawnContext.inheritedToolPolicy }; const profileId = client?.authenticatedUserProfile?.profileId; return { via: "operator", ...profileId ? { actor: { type: "human", source: "profile", id: profileId } } : {} }; } function resolveAgentRunSessionCreation(client) { const actor = resolveOperatorSessionCreation(client).actor; return { via: "run", ...actor ? { actor } : {} }; } //#endregion //#region src/gateway/operator-role-policy.ts const operatorRoleLog = createSubsystemLogger("gateway/operator-roles"); const MAX_OPERATOR_ROLE_ASSIGNMENTS = 1024; const operatorRoleAssignments = /* @__PURE__ */ new Map(); const reportedUnknownAssignments = /* @__PURE__ */ new Set(); const deniedOperatorRole = { sessions: { others: "none" }, agents: [], scopes: [] }; function readOperatorRoleAssignment(profileId) { if (operatorRoleAssignments.has(profileId)) return operatorRoleAssignments.get(profileId) ?? null; const assignment = getUserProfileRole(profileId); if (operatorRoleAssignments.size >= MAX_OPERATOR_ROLE_ASSIGNMENTS) { const oldestProfileId = operatorRoleAssignments.keys().next().value; if (oldestProfileId !== void 0) { operatorRoleAssignments.delete(oldestProfileId); for (const reported of reportedUnknownAssignments) if (reported.startsWith(`${oldestProfileId}:`)) reportedUnknownAssignments.delete(reported); } } operatorRoleAssignments.set(profileId, assignment); return assignment; } /** Drops a changed assignment so subsequent authorization reads the durable owner. */ function invalidateOperatorRolePolicy(profileId) { bumpGatewayAccessRevision(); operatorRoleAssignments.delete(profileId); for (const reported of reportedUnknownAssignments) if (reported.startsWith(`${profileId}:`)) reportedUnknownAssignments.delete(reported); } /** An enabled role boundary denies missing identity and unresolvable assignments. */ function resolveOperatorRolePolicyForProfile(profileId, cfg) { if (!cfg.gateway?.roles || profileId === "gateway-owner") return; return resolveOperatorRolePolicyForAssignment(profileId, profileId ? readOperatorRoleAssignment(profileId) : null, cfg); } /** Transaction owners supply the authoritative row without consulting the assignment cache. */ function resolveOperatorRolePolicyForAssignment(profileId, assignedRole, cfg) { const roles = cfg.gateway?.roles; if (!roles || profileId === "gateway-owner") return; if (!profileId) return deniedOperatorRole; if (assignedRole && Object.hasOwn(roles.definitions, assignedRole)) return roles.definitions[assignedRole]; if (assignedRole) { const reportKey = `${profileId}:${assignedRole}`; if (!reportedUnknownAssignments.has(reportKey)) { reportedUnknownAssignments.add(reportKey); operatorRoleLog.warn(`User profile ${profileId} references unknown Gateway role "${assignedRole}"; ${roles.default ? `applying default role "${roles.default}"` : "denying access"}. Update gateway.roles.definitions or clear the assignment with users.setRole.`); } } return (roles.default ? roles.definitions[roles.default] : void 0) ?? deniedOperatorRole; } /** Preserve human-derived restrictions, including ambiguous historical actors; this is not identity proof. */ function resolveCreatorSandbox(cfg, creation) { const actor = creation?.actor; return actor?.type === "human" && actor.id && resolveOperatorRolePolicyForProfile(actor.id, cfg)?.sandbox === "required" ? "required" : void 0; } /** Resolves the current named policy from the connection's verified profile identity. */ function resolveGatewayOperatorRoleActor(client) { const actor = client?.internal?.operatorRoleActor; if (actor) return actor; const profileId = gatewayClientSessionCreator(client ?? null)?.id; return profileId && profileId !== "gateway-owner" ? { kind: "operator", profileId } : void 0; } /** Resolves the current named policy from an authoritative operator or system actor. */ function resolveOperatorRolePolicy(client, cfg) { const actor = resolveGatewayOperatorRoleActor(client); if (actor?.kind === "system") return; return resolveOperatorRolePolicyForProfile(actor?.profileId, cfg); } function operatorSessionCap(client, cfg) { return resolveOperatorRolePolicy(client, cfg)?.sessions.others; } function hasOperatorBoundary(client, cfg) { return operatorSessionCap(client, cfg) !== void 0; } /** Enforces the owning agent ceiling for session creation and run-start targets. */ function authorizeGatewaySessionCreation(params) { const actor = params.actor ?? ("client" in params ? resolveGatewayOperatorRoleActor(params.client) : void 0); if (actor?.kind === "system") return; const role = resolveOperatorRolePolicyForProfile(actor?.profileId ?? params.profileId, params.cfg); if (!role || role.agents === "*" || role.agents.includes(params.agentId)) return; return errorShape(ErrorCodes.FORBIDDEN, `Your operator role cannot create sessions for agent "${params.agentId}"; choose an allowed agent or ask a gateway administrator to update your role.`); } /** Leave ordinary creation attribution unchanged unless the authenticated person requires isolation. */ function resolveSandboxedSessionCreation(client, cfg) { const creation = resolveOperatorSessionCreation(client); return resolveCreatorSandbox(cfg, creation) === "required" ? { ...creation, sandbox: "required" } : void 0; } //#endregion export { resolveChatSendCallerContext as _, resolveCreatorSandbox as a, resolveOperatorRolePolicyForAssignment as c, resolveAgentRunSessionCreation as d, resolveOperatorSessionCreation as f, isGatewayClientProfilePending as g, gatewayClientSessionCreator as h, operatorSessionCap as i, resolveOperatorRolePolicyForProfile as l, gatewayClientSenderFields as m, hasOperatorBoundary as n, resolveGatewayOperatorRoleActor as o, authenticatedProfileUnavailableError as p, invalidateOperatorRolePolicy as r, resolveOperatorRolePolicy as s, authorizeGatewaySessionCreation as t, resolveSandboxedSessionCreation as u, bumpGatewayAccessRevision as v, readGatewayAccessRevision as y };