Skip to content

Commit 9105b94

Browse files
authored
Merge pull request #6 from Kilo-Org/fix/avoid-gateway-restart-on-token-capture
fix(osa) better secret handling and reduces number of restarts
2 parents 25d1951 + 465611b commit 9105b94

5 files changed

Lines changed: 48 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
- First-time device auth no longer triggers a brief gateway restart after the token is captured. The plugin now registers `reload.noopPrefixes` for `plugins.entries.openclaw-security-advisor.config.authToken`, so the SecretRef patch written to `openclaw.json` after device auth is classified as a noop by the gateway reload planner instead of falling through to the default `plugins.* → restart` rule. The security checkup report is returned in the same response with no connection interruption. Scope is intentionally limited to the `authToken` field — `apiBaseUrl` and other config changes still take effect via the normal restart path.
1213
- Release workflow: consolidated post-publish git/GitHub operations into a single atomic step with retries, eliminating a race condition where the version bump commit and tag could be pushed separately. Registry verification is now informational-only and never blocks tag/release steps.
1314
- Release workflow: added a `Reconcile latest dist-tag` step that automatically repoints `npm dist-tags.latest` back to the highest stable version after a dev publish, preventing npm's first-publish auto-assign behavior from routing plain `npm install` users to a prerelease.
1415

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,6 @@ connection. Then run `/security-checkup` again. The plugin will pick
125125
up the approval, persist your auth token, run the checkup, and return
126126
the report in the same response.
127127

128-
> **Note:** after the token is saved, OpenClaw briefly reloads to apply
129-
> the new credential. You'll see a short connection blip in the chat
130-
> UI. This is expected and only happens on first auth. Subsequent
131-
> checkups run instantly without any reload.
132-
133128
For every run after the first, no auth prompt appears. The saved token
134129
is reused automatically.
135130

index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,26 @@ export default definePluginEntry({
294294
name: "OpenClaw Security Advisor",
295295
description:
296296
"Run a security checkup of your OpenClaw instance and get an expert analysis report from KiloCode.",
297+
// The gateway reload planner classifies any change under `plugins.*`
298+
// as `kind: "restart"` by default. writeStoredToken() patches
299+
// plugins.entries.openclaw-security-advisor.config.authToken with a
300+
// SecretRef after device auth, which would force a full gateway
301+
// restart on first-time token capture. Plugin-registered reload
302+
// rules are evaluated before the base rules (first-match wins), so
303+
// declaring just the authToken path as a noop shadows the base
304+
// restart rule for that one field without affecting anything else.
305+
//
306+
// Scope is intentionally narrow — only `.config.authToken`, NOT the
307+
// full `.config` subtree. `apiBaseUrl` is captured as a snapshot in
308+
// register() (see `pluginConfig` below), so runtime updates to it
309+
// still need to fall through to the base `plugins.* → restart` rule
310+
// to take effect. The plugin reads the token directly from disk via
311+
// readTokenFromFile() on every invocation, so authToken noop is safe.
312+
reload: {
313+
noopPrefixes: [
314+
"plugins.entries.openclaw-security-advisor.config.authToken",
315+
],
316+
},
297317
// The SDK's OpenClawPluginApi type is large and internal. We narrow
298318
// to our own structural PluginApi (declared above) immediately on
299319
// entry so everything inside this function is strongly typed.

src/auth/token-store.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,18 @@ async function ensureSecretsDir(): Promise<void> {
5353
* 2. Register a file-based SecretRef provider in config
5454
* 3. Point the plugin authToken config at that provider
5555
*
56-
* This triggers one gateway restart. On restart, OpenClaw resolves the
57-
* SecretRef → api.pluginConfig.authToken = the token string, available
58-
* in the plugin closure forever after.
56+
* The config write does NOT trigger a gateway restart: the plugin
57+
* declares `reload.noopPrefixes` for
58+
* `plugins.entries.<id>.config.authToken` in index.ts, which shadows
59+
* the gateway reload planner's default `plugins.* → restart` rule for
60+
* just that one field. Other `.config.*` fields (e.g. `apiBaseUrl`)
61+
* intentionally still hit the default restart rule so runtime edits
62+
* take effect. The plugin reads the token directly from the secrets
63+
* file via readTokenFromFile() on every invocation, so no hot-resolve
64+
* of api.pluginConfig.authToken is needed — the SecretRef in
65+
* openclaw.json exists for discoverability (so operators inspecting
66+
* config can see where the token lives) and to align with openclaw's
67+
* SecretRef direction.
5968
*/
6069
export async function writeStoredToken(
6170
api: TokenStoreApi,

src/openclaw-sdk.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@
1414
*/
1515

1616
declare module "openclaw/plugin-sdk/plugin-entry" {
17+
/**
18+
* Subset of the SDK's OpenClawPluginReloadRegistration. Entries here let a
19+
* plugin override the gateway reload planner's default classification for
20+
* specific config prefixes. First-match wins, and plugin-registered rules
21+
* are evaluated before the base `plugins.* -> restart` rule, so declaring
22+
* `plugins.entries.<id>.config` here overrides the base restart for our
23+
* own config subtree.
24+
*/
25+
export type PluginReloadRegistration = {
26+
restartPrefixes?: string[];
27+
hotPrefixes?: string[];
28+
noopPrefixes?: string[];
29+
};
30+
1731
/**
1832
* Register a plugin with the OpenClaw runtime. The `register` callback
1933
* receives a runtime-provided plugin API object. The SDK's concrete
@@ -24,6 +38,7 @@ declare module "openclaw/plugin-sdk/plugin-entry" {
2438
id: string;
2539
name: string;
2640
description: string;
41+
reload?: PluginReloadRegistration;
2742
register: (api: any) => void;
2843
}): unknown;
2944
}

0 commit comments

Comments
 (0)