CLI: make read-only SecretRef status flows degrade safely (#37023)

* CLI: add read-only SecretRef inspection

* CLI: fix read-only SecretRef status regressions

* CLI: preserve read-only SecretRef status fallbacks

* Docs: document read-only channel inspection hook

* CLI: preserve audit coverage for read-only SecretRefs

* CLI: fix read-only status account selection

* CLI: fix targeted gateway fallback analysis

* CLI: fix Slack HTTP read-only inspection

* CLI: align audit credential status checks

* CLI: restore Telegram read-only fallback semantics
This commit is contained in:
Josh Avant
2026-03-05 23:07:13 -06:00
committed by GitHub
parent 8d4a2f2c59
commit 0e4245063f
58 changed files with 3422 additions and 215 deletions

View File

@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { withEnv } from "../test-utils/env.js";
import { getChannelDock } from "./dock.js";
function emptyConfig(): OpenClawConfig {
@@ -69,7 +70,7 @@ describe("channels dock", () => {
},
},
},
} as OpenClawConfig;
} as unknown as OpenClawConfig;
const accountDefault = ircDock?.config?.resolveDefaultTo?.({ cfg, accountId: "work" });
const rootDefault = ircDock?.config?.resolveDefaultTo?.({ cfg, accountId: "missing" });
@@ -99,4 +100,73 @@ describe("channels dock", () => {
expect(formatted).toEqual(["user", "foo", "plain"]);
});
it("telegram dock config readers preserve omitted-account fallback semantics", () => {
withEnv({ TELEGRAM_BOT_TOKEN: "tok-env" }, () => {
const telegramDock = getChannelDock("telegram");
const cfg = {
channels: {
telegram: {
allowFrom: ["top-owner"],
defaultTo: "@top-target",
accounts: {
work: {
botToken: "tok-work",
allowFrom: ["work-owner"],
defaultTo: "@work-target",
},
},
},
},
} as unknown as OpenClawConfig;
expect(telegramDock?.config?.resolveAllowFrom?.({ cfg })).toEqual(["top-owner"]);
expect(telegramDock?.config?.resolveDefaultTo?.({ cfg })).toBe("@top-target");
});
});
it("slack dock config readers stay read-only when tokens are unresolved SecretRefs", () => {
const slackDock = getChannelDock("slack");
const cfg = {
channels: {
slack: {
botToken: {
source: "env",
provider: "default",
id: "SLACK_BOT_TOKEN",
},
appToken: {
source: "env",
provider: "default",
id: "SLACK_APP_TOKEN",
},
defaultTo: "channel:C111",
dm: { allowFrom: ["U123"] },
channels: {
C111: { requireMention: false },
},
replyToMode: "all",
},
},
} as unknown as OpenClawConfig;
expect(slackDock?.config?.resolveAllowFrom?.({ cfg, accountId: "default" })).toEqual(["U123"]);
expect(slackDock?.config?.resolveDefaultTo?.({ cfg, accountId: "default" })).toBe(
"channel:C111",
);
expect(
slackDock?.threading?.resolveReplyToMode?.({
cfg,
accountId: "default",
chatType: "channel",
}),
).toBe("all");
expect(
slackDock?.groups?.resolveRequireMention?.({
cfg,
accountId: "default",
groupId: "C111",
}),
).toBe(false);
});
});