mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:50:43 +00:00
fix(commands): scope owner allowlist prefixes (#72928)
* fix(commands): scope owner allowlist prefixes Co-authored-by: zsx <git@zsxsoft.com> * fix(commands): annotate owner allowlist short-circuit * docs: move changelog entry to unreleased fixes --------- Co-authored-by: zsx <git@zsxsoft.com> Co-authored-by: Devin Robison <drobison@nvidia.com>
This commit is contained in:
@@ -229,6 +229,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Auto-reply/subagents: reject `/focus` from leaf subagents and scope fallback target resolution to the requesting subagent's children, so subagents cannot bind conversations outside their control boundary. (#73613) Thanks @drobison00.
|
||||
- Gateway/startup: skip inherited workspace startup memory for sandboxed spawned sessions without real-workspace write access, so `/new` no longer preloads host workspace memory into isolated child runs. (#73611) Thanks @drobison00.
|
||||
- Agents/tool policy: validate caller group IDs against session or spawned context before applying group-scoped tool policies or persisting gateway group metadata, so forged group IDs cannot unlock more permissive tools. (#73720) Thanks @mmaps.
|
||||
- Commands: keep channel-prefixed owner allowlist entries scoped to matching providers so webchat command contexts cannot inherit external channel owners. Thanks @zsxsoft.
|
||||
|
||||
## 2026.4.27
|
||||
|
||||
|
||||
@@ -289,7 +289,8 @@ function resolveOwnerAllowFromList(params: {
|
||||
const prefix = trimmed.slice(0, separatorIndex);
|
||||
const channel = normalizeAnyChannelId(prefix);
|
||||
if (channel) {
|
||||
if (params.providerId && channel !== params.providerId) {
|
||||
// Channel-prefixed entries require a known matching provider; webchat leaves it unset.
|
||||
if (!params.providerId || channel !== params.providerId) {
|
||||
continue;
|
||||
}
|
||||
const remainder = trimmed.slice(separatorIndex + 1).trim();
|
||||
|
||||
@@ -356,6 +356,88 @@ describe("resolveCommandAuthorization", () => {
|
||||
expect(auth.isAuthorizedSender).toBe(true);
|
||||
});
|
||||
|
||||
it("does not apply channel-prefixed owner wildcards to webchat command contexts", () => {
|
||||
const cfg = {
|
||||
commands: { ownerAllowFrom: ["discord:*"] },
|
||||
} as OpenClawConfig;
|
||||
|
||||
const auth = resolveCommandAuthorization({
|
||||
ctx: {
|
||||
Provider: "webchat",
|
||||
Surface: "webchat",
|
||||
OriginatingChannel: "webchat",
|
||||
SenderId: "123456789012345678",
|
||||
GatewayClientScopes: ["operator.write"],
|
||||
} as MsgContext,
|
||||
cfg,
|
||||
commandAuthorized: true,
|
||||
});
|
||||
|
||||
expect(auth.providerId).toBeUndefined();
|
||||
expect(auth.senderIsOwner).toBe(false);
|
||||
});
|
||||
|
||||
it("does not apply channel-prefixed owner identities to webchat command contexts", () => {
|
||||
const cfg = {
|
||||
commands: { ownerAllowFrom: ["discord:123456789012345678"] },
|
||||
} as OpenClawConfig;
|
||||
|
||||
const auth = resolveCommandAuthorization({
|
||||
ctx: {
|
||||
Provider: "webchat",
|
||||
Surface: "webchat",
|
||||
OriginatingChannel: "webchat",
|
||||
SenderId: "123456789012345678",
|
||||
GatewayClientScopes: ["operator.write"],
|
||||
} as MsgContext,
|
||||
cfg,
|
||||
commandAuthorized: true,
|
||||
});
|
||||
|
||||
expect(auth.providerId).toBeUndefined();
|
||||
expect(auth.senderIsOwner).toBe(false);
|
||||
});
|
||||
|
||||
it("applies channel-prefixed owner identities to matching providers", () => {
|
||||
const cfg = {
|
||||
commands: { ownerAllowFrom: ["discord:123456789012345678"] },
|
||||
} as OpenClawConfig;
|
||||
|
||||
const auth = resolveCommandAuthorization({
|
||||
ctx: {
|
||||
Provider: "discord",
|
||||
Surface: "discord",
|
||||
From: "discord:123456789012345678",
|
||||
SenderId: "123456789012345678",
|
||||
} as MsgContext,
|
||||
cfg,
|
||||
commandAuthorized: true,
|
||||
});
|
||||
|
||||
expect(auth.providerId).toBe("discord");
|
||||
expect(auth.senderIsOwner).toBe(true);
|
||||
});
|
||||
|
||||
it("does not apply channel-prefixed owner wildcards to mismatched providers", () => {
|
||||
const cfg = {
|
||||
commands: { ownerAllowFrom: ["telegram:*"] },
|
||||
} as OpenClawConfig;
|
||||
|
||||
const auth = resolveCommandAuthorization({
|
||||
ctx: {
|
||||
Provider: "discord",
|
||||
Surface: "discord",
|
||||
From: "discord:123456789012345678",
|
||||
SenderId: "123456789012345678",
|
||||
} as MsgContext,
|
||||
cfg,
|
||||
commandAuthorized: true,
|
||||
});
|
||||
|
||||
expect(auth.providerId).toBe("discord");
|
||||
expect(auth.senderIsOwner).toBe(false);
|
||||
});
|
||||
|
||||
it("preserves external channel command auth in mixed webchat contexts", () => {
|
||||
const cfg = {
|
||||
commands: { allowFrom: { whatsapp: ["+15551234567"] } },
|
||||
|
||||
Reference in New Issue
Block a user