@m1a0rz/agent-identity 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-cn.md +223 -0
- package/README.md +223 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +306 -0
- package/dist/src/actions/identity-actions.d.ts +142 -0
- package/dist/src/actions/identity-actions.d.ts.map +1 -0
- package/dist/src/actions/identity-actions.js +429 -0
- package/dist/src/commands/identity-commands.d.ts +33 -0
- package/dist/src/commands/identity-commands.d.ts.map +1 -0
- package/dist/src/commands/identity-commands.js +572 -0
- package/dist/src/hooks/after-tool-call.d.ts +22 -0
- package/dist/src/hooks/after-tool-call.d.ts.map +1 -0
- package/dist/src/hooks/after-tool-call.js +35 -0
- package/dist/src/hooks/before-agent-start.d.ts +30 -0
- package/dist/src/hooks/before-agent-start.d.ts.map +1 -0
- package/dist/src/hooks/before-agent-start.js +93 -0
- package/dist/src/hooks/before-tool-call.d.ts +38 -0
- package/dist/src/hooks/before-tool-call.d.ts.map +1 -0
- package/dist/src/hooks/before-tool-call.js +138 -0
- package/dist/src/risk/classify-risk.d.ts +24 -0
- package/dist/src/risk/classify-risk.d.ts.map +1 -0
- package/dist/src/risk/classify-risk.js +61 -0
- package/dist/src/risk/diagnose-risk.d.ts +21 -0
- package/dist/src/risk/diagnose-risk.d.ts.map +1 -0
- package/dist/src/risk/diagnose-risk.js +37 -0
- package/dist/src/risk/llm-risk-check.d.ts +27 -0
- package/dist/src/risk/llm-risk-check.d.ts.map +1 -0
- package/dist/src/risk/llm-risk-check.js +274 -0
- package/dist/src/risk/low-risk-tools.d.ts +5 -0
- package/dist/src/risk/low-risk-tools.d.ts.map +1 -0
- package/dist/src/risk/low-risk-tools.js +29 -0
- package/dist/src/routes/oidc-login.d.ts +51 -0
- package/dist/src/routes/oidc-login.d.ts.map +1 -0
- package/dist/src/routes/oidc-login.js +153 -0
- package/dist/src/services/identity-client.d.ts +366 -0
- package/dist/src/services/identity-client.d.ts.map +1 -0
- package/dist/src/services/identity-client.js +578 -0
- package/dist/src/services/identity-credentials.d.ts +28 -0
- package/dist/src/services/identity-credentials.d.ts.map +1 -0
- package/dist/src/services/identity-credentials.js +170 -0
- package/dist/src/services/identity-service.d.ts +33 -0
- package/dist/src/services/identity-service.d.ts.map +1 -0
- package/dist/src/services/identity-service.js +53 -0
- package/dist/src/services/oidc-client.d.ts +57 -0
- package/dist/src/services/oidc-client.d.ts.map +1 -0
- package/dist/src/services/oidc-client.js +127 -0
- package/dist/src/services/send-notification-feishu.d.ts +27 -0
- package/dist/src/services/send-notification-feishu.d.ts.map +1 -0
- package/dist/src/services/send-notification-feishu.js +148 -0
- package/dist/src/services/session-refresh.d.ts +16 -0
- package/dist/src/services/session-refresh.d.ts.map +1 -0
- package/dist/src/services/session-refresh.js +38 -0
- package/dist/src/store/credential-env-bindings.d.ts +16 -0
- package/dist/src/store/credential-env-bindings.d.ts.map +1 -0
- package/dist/src/store/credential-env-bindings.js +61 -0
- package/dist/src/store/credential-store.d.ts +31 -0
- package/dist/src/store/credential-store.d.ts.map +1 -0
- package/dist/src/store/credential-store.js +57 -0
- package/dist/src/store/oidc-state-store.d.ts +15 -0
- package/dist/src/store/oidc-state-store.d.ts.map +1 -0
- package/dist/src/store/oidc-state-store.js +32 -0
- package/dist/src/store/session-store.d.ts +21 -0
- package/dist/src/store/session-store.d.ts.map +1 -0
- package/dist/src/store/session-store.js +69 -0
- package/dist/src/store/tip-store.d.ts +21 -0
- package/dist/src/store/tip-store.d.ts.map +1 -0
- package/dist/src/store/tip-store.js +60 -0
- package/dist/src/store/tool-approval-store.d.ts +44 -0
- package/dist/src/store/tool-approval-store.d.ts.map +1 -0
- package/dist/src/store/tool-approval-store.js +147 -0
- package/dist/src/tools/identity-approve-tool.d.ts +24 -0
- package/dist/src/tools/identity-approve-tool.d.ts.map +1 -0
- package/dist/src/tools/identity-approve-tool.js +36 -0
- package/dist/src/tools/identity-config.d.ts +13 -0
- package/dist/src/tools/identity-config.d.ts.map +1 -0
- package/dist/src/tools/identity-config.js +18 -0
- package/dist/src/tools/identity-fetch.d.ts +21 -0
- package/dist/src/tools/identity-fetch.d.ts.map +1 -0
- package/dist/src/tools/identity-fetch.js +63 -0
- package/dist/src/tools/identity-list-credentials.d.ts +15 -0
- package/dist/src/tools/identity-list-credentials.d.ts.map +1 -0
- package/dist/src/tools/identity-list-credentials.js +30 -0
- package/dist/src/tools/identity-list-risk-patterns.d.ts +13 -0
- package/dist/src/tools/identity-list-risk-patterns.d.ts.map +1 -0
- package/dist/src/tools/identity-list-risk-patterns.js +23 -0
- package/dist/src/tools/identity-list-tips.d.ts +13 -0
- package/dist/src/tools/identity-list-tips.d.ts.map +1 -0
- package/dist/src/tools/identity-list-tips.js +21 -0
- package/dist/src/tools/identity-login.d.ts +14 -0
- package/dist/src/tools/identity-login.d.ts.map +1 -0
- package/dist/src/tools/identity-login.js +40 -0
- package/dist/src/tools/identity-logout.d.ts +13 -0
- package/dist/src/tools/identity-logout.d.ts.map +1 -0
- package/dist/src/tools/identity-logout.js +24 -0
- package/dist/src/tools/identity-risk-check.d.ts +29 -0
- package/dist/src/tools/identity-risk-check.d.ts.map +1 -0
- package/dist/src/tools/identity-risk-check.js +54 -0
- package/dist/src/tools/identity-set-binding.d.ts +16 -0
- package/dist/src/tools/identity-set-binding.d.ts.map +1 -0
- package/dist/src/tools/identity-set-binding.js +31 -0
- package/dist/src/tools/identity-status.d.ts +13 -0
- package/dist/src/tools/identity-status.d.ts.map +1 -0
- package/dist/src/tools/identity-status.js +41 -0
- package/dist/src/tools/identity-unset-binding.d.ts +15 -0
- package/dist/src/tools/identity-unset-binding.d.ts.map +1 -0
- package/dist/src/tools/identity-unset-binding.js +25 -0
- package/dist/src/tools/identity-whoami.d.ts +13 -0
- package/dist/src/tools/identity-whoami.d.ts.map +1 -0
- package/dist/src/tools/identity-whoami.js +38 -0
- package/dist/src/types.d.ts +93 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +5 -0
- package/dist/src/utils/approval-channel.d.ts +11 -0
- package/dist/src/utils/approval-channel.d.ts.map +1 -0
- package/dist/src/utils/approval-channel.js +13 -0
- package/dist/src/utils/auth.d.ts +24 -0
- package/dist/src/utils/auth.d.ts.map +1 -0
- package/dist/src/utils/auth.js +44 -0
- package/dist/src/utils/derive-session-key.d.ts +78 -0
- package/dist/src/utils/derive-session-key.d.ts.map +1 -0
- package/dist/src/utils/derive-session-key.js +198 -0
- package/openclaw.plugin.json +162 -0
- package/package.json +33 -0
- package/skills/SKILL.md +230 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Identity Plugin
|
|
3
|
+
*
|
|
4
|
+
* - UserPool login via /identity login (OIDC URL returned directly, no HTTP start endpoint)
|
|
5
|
+
* - Credential hosting: list-credentials, fetch <provider>, set <provider> <envVar>
|
|
6
|
+
* - TIP token via CIS GetWorkloadAccessTokenForJWT in before_agent_start
|
|
7
|
+
* - Sub-agent TIP propagation in after_tool_call (sessions_spawn)
|
|
8
|
+
* - Optional AuthZ in before_tool_call
|
|
9
|
+
* - HTTP callback: /identity/oauth/callback (OIDC login). Credential OAuth uses Identity-provided callback.
|
|
10
|
+
* - Tools: identity_whoami, identity_logout
|
|
11
|
+
*/
|
|
12
|
+
import { createIdentityCommand, createIdCommand } from "./src/commands/identity-commands.js";
|
|
13
|
+
import { createAfterToolCallHandler } from "./src/hooks/after-tool-call.js";
|
|
14
|
+
import { createBeforeAgentStartHandler } from "./src/hooks/before-agent-start.js";
|
|
15
|
+
import { createBeforeToolCallHandler } from "./src/hooks/before-tool-call.js";
|
|
16
|
+
import { createOIDCCallbackHandler, createOIDCCallbackHandlerLazy, } from "./src/routes/oidc-login.js";
|
|
17
|
+
import { IdentityClient, resolveOIDCConfig, } from "./src/services/identity-client.js";
|
|
18
|
+
import { IdentityService } from "./src/services/identity-service.js";
|
|
19
|
+
import { sendNotificationFeishu } from "./src/services/send-notification-feishu.js";
|
|
20
|
+
import { createIdentityApproveTool } from "./src/tools/identity-approve-tool.js";
|
|
21
|
+
import { createIdentityConfigTool } from "./src/tools/identity-config.js";
|
|
22
|
+
import { createIdentityListRiskPatternsTool } from "./src/tools/identity-list-risk-patterns.js";
|
|
23
|
+
import { createIdentityRiskCheckTool } from "./src/tools/identity-risk-check.js";
|
|
24
|
+
import { createIdentityFetchTool } from "./src/tools/identity-fetch.js";
|
|
25
|
+
import { createIdentityListCredentialsTool } from "./src/tools/identity-list-credentials.js";
|
|
26
|
+
import { createIdentityListTipsTool } from "./src/tools/identity-list-tips.js";
|
|
27
|
+
import { createIdentityLoginTool } from "./src/tools/identity-login.js";
|
|
28
|
+
import { createIdentityLogoutTool } from "./src/tools/identity-logout.js";
|
|
29
|
+
import { createIdentitySetBindingTool } from "./src/tools/identity-set-binding.js";
|
|
30
|
+
import { createIdentityStatusTool } from "./src/tools/identity-status.js";
|
|
31
|
+
import { createIdentityUnsetBindingTool } from "./src/tools/identity-unset-binding.js";
|
|
32
|
+
import { createIdentityWhoamiTool } from "./src/tools/identity-whoami.js";
|
|
33
|
+
import { parseSessionKeyToDeliveryTarget, } from "./src/utils/derive-session-key.js";
|
|
34
|
+
const PLUGIN_STORE_DIR = "~/.openclaw/plugins/identity";
|
|
35
|
+
/**
|
|
36
|
+
* Whether Identity should be enabled.
|
|
37
|
+
*/
|
|
38
|
+
function hasAnyIdentityConfig(identity) {
|
|
39
|
+
if (!identity)
|
|
40
|
+
return false;
|
|
41
|
+
return Boolean(identity.endpoint ||
|
|
42
|
+
identity.accessKeyId ||
|
|
43
|
+
identity.secretAccessKey ||
|
|
44
|
+
identity.sessionToken ||
|
|
45
|
+
identity.credentialsFile ||
|
|
46
|
+
identity.roleTrn ||
|
|
47
|
+
identity.workloadPoolName ||
|
|
48
|
+
identity.workloadName ||
|
|
49
|
+
identity.audience?.length ||
|
|
50
|
+
identity.durationSeconds);
|
|
51
|
+
}
|
|
52
|
+
export default function register(api) {
|
|
53
|
+
const pluginConfig = (api.pluginConfig ?? {});
|
|
54
|
+
const storeDir = api.resolvePath(PLUGIN_STORE_DIR);
|
|
55
|
+
const identityCfg = pluginConfig.identity;
|
|
56
|
+
const hasIdentity = hasAnyIdentityConfig(identityCfg);
|
|
57
|
+
const userpool = pluginConfig.userpool;
|
|
58
|
+
const identityClient = hasIdentity
|
|
59
|
+
? new IdentityClient({
|
|
60
|
+
endpoint: identityCfg?.endpoint ?? "https://id.cn-beijing.volcengineapi.com",
|
|
61
|
+
accessKeyId: identityCfg?.accessKeyId,
|
|
62
|
+
secretAccessKey: identityCfg?.secretAccessKey,
|
|
63
|
+
sessionToken: identityCfg?.sessionToken,
|
|
64
|
+
credentialsFile: identityCfg?.credentialsFile,
|
|
65
|
+
roleTrn: identityCfg?.roleTrn,
|
|
66
|
+
serviceCode: "id",
|
|
67
|
+
})
|
|
68
|
+
: {
|
|
69
|
+
getWorkloadAccessTokenForJWT: async () => {
|
|
70
|
+
throw new Error("Identity not configured.");
|
|
71
|
+
},
|
|
72
|
+
getResourceOauth2Token: async () => {
|
|
73
|
+
throw new Error("Identity not configured.");
|
|
74
|
+
},
|
|
75
|
+
oauth2Callback: async () => {
|
|
76
|
+
throw new Error("Identity not configured.");
|
|
77
|
+
},
|
|
78
|
+
getResourceApiKey: async () => {
|
|
79
|
+
throw new Error("Identity not configured.");
|
|
80
|
+
},
|
|
81
|
+
checkPermission: async () => {
|
|
82
|
+
throw new Error("Identity not configured.");
|
|
83
|
+
},
|
|
84
|
+
listCredentialProviders: async () => ({
|
|
85
|
+
CredentialProviders: [],
|
|
86
|
+
Data: [],
|
|
87
|
+
TotalCount: 0,
|
|
88
|
+
PageNumber: 1,
|
|
89
|
+
PageSize: 20,
|
|
90
|
+
}),
|
|
91
|
+
getUserPool: async () => {
|
|
92
|
+
throw new Error("Identity not configured.");
|
|
93
|
+
},
|
|
94
|
+
listUserPools: async () => ({
|
|
95
|
+
pageNumber: 1,
|
|
96
|
+
pageSize: 10,
|
|
97
|
+
totalCount: 0,
|
|
98
|
+
data: [],
|
|
99
|
+
}),
|
|
100
|
+
createUserPool: async () => {
|
|
101
|
+
throw new Error("Identity not configured.");
|
|
102
|
+
},
|
|
103
|
+
getUserPoolClient: async () => {
|
|
104
|
+
throw new Error("Identity not configured.");
|
|
105
|
+
},
|
|
106
|
+
listUserPoolClients: async () => ({
|
|
107
|
+
pageNumber: 1,
|
|
108
|
+
pageSize: 10,
|
|
109
|
+
totalCount: 0,
|
|
110
|
+
data: [],
|
|
111
|
+
}),
|
|
112
|
+
createUserPoolClient: async () => {
|
|
113
|
+
throw new Error("Identity not configured.");
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
const identityService = new IdentityService({
|
|
117
|
+
identityClient: identityClient,
|
|
118
|
+
workloadPoolName: identityCfg?.workloadPoolName,
|
|
119
|
+
workloadName: identityCfg?.workloadName,
|
|
120
|
+
audience: identityCfg?.audience,
|
|
121
|
+
durationSeconds: identityCfg?.durationSeconds,
|
|
122
|
+
roleTrn: identityCfg?.roleTrn,
|
|
123
|
+
});
|
|
124
|
+
const dynamicOidcEnabled = !!(userpool?.userPoolName &&
|
|
125
|
+
userpool?.clientName &&
|
|
126
|
+
userpool?.callbackUrl &&
|
|
127
|
+
hasIdentity);
|
|
128
|
+
const explicitOidcEnabled = !!(userpool?.discoveryUrl &&
|
|
129
|
+
userpool?.clientId &&
|
|
130
|
+
userpool?.callbackUrl);
|
|
131
|
+
let getResolvedOidcConfig = null;
|
|
132
|
+
if (dynamicOidcEnabled) {
|
|
133
|
+
let cached = null;
|
|
134
|
+
getResolvedOidcConfig = async () => {
|
|
135
|
+
if (cached)
|
|
136
|
+
return cached;
|
|
137
|
+
cached = await resolveOIDCConfig(identityClient, {
|
|
138
|
+
userPoolName: userpool.userPoolName,
|
|
139
|
+
clientName: userpool.clientName,
|
|
140
|
+
redirectUri: userpool.callbackUrl,
|
|
141
|
+
scope: userpool.scope,
|
|
142
|
+
autoCreate: userpool.autoCreate ?? true,
|
|
143
|
+
});
|
|
144
|
+
return cached;
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else if (explicitOidcEnabled) {
|
|
148
|
+
getResolvedOidcConfig = async () => ({
|
|
149
|
+
discoveryUrl: userpool.discoveryUrl,
|
|
150
|
+
clientId: userpool.clientId,
|
|
151
|
+
clientSecret: userpool.clientSecret,
|
|
152
|
+
scope: userpool.scope,
|
|
153
|
+
callbackUrl: userpool.callbackUrl,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
const getOidcConfigForRefresh = dynamicOidcEnabled
|
|
157
|
+
? async () => {
|
|
158
|
+
const c = await getResolvedOidcConfig();
|
|
159
|
+
return {
|
|
160
|
+
discoveryUrl: c.discoveryUrl,
|
|
161
|
+
clientId: c.clientId,
|
|
162
|
+
clientSecret: c.clientSecret,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
: explicitOidcEnabled
|
|
166
|
+
? async () => ({
|
|
167
|
+
discoveryUrl: userpool.discoveryUrl,
|
|
168
|
+
clientId: userpool.clientId,
|
|
169
|
+
clientSecret: userpool.clientSecret,
|
|
170
|
+
})
|
|
171
|
+
: undefined;
|
|
172
|
+
const CHANNEL_SEND_KEYS = {
|
|
173
|
+
telegram: "sendMessageTelegram",
|
|
174
|
+
slack: "sendMessageSlack",
|
|
175
|
+
discord: "sendMessageDiscord",
|
|
176
|
+
signal: "sendMessageSignal",
|
|
177
|
+
imessage: "sendMessageIMessage",
|
|
178
|
+
whatsapp: "sendMessageWhatsApp",
|
|
179
|
+
line: "sendMessageLine",
|
|
180
|
+
feishu: "sendMessageFeishu",
|
|
181
|
+
};
|
|
182
|
+
const sendToSession = async (targetOrSessionKey, text) => {
|
|
183
|
+
const target = typeof targetOrSessionKey === "object"
|
|
184
|
+
? targetOrSessionKey
|
|
185
|
+
: parseSessionKeyToDeliveryTarget(targetOrSessionKey);
|
|
186
|
+
if (!target) {
|
|
187
|
+
api.logger.warn(`agent-identity: Cannot deliver to channel (sessionKey not parseable). Set session.dmScope to per-channel-peer or per-account-channel-peer so approval messages reach Feishu/Telegram/etc.`);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (target.channel === "feishu") {
|
|
191
|
+
try {
|
|
192
|
+
const cfg = await api.runtime.config.loadConfig();
|
|
193
|
+
await sendNotificationFeishu(cfg, target.to, text, target.accountId);
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
api.logger.warn(`agent-identity: Feishu notification failed (to=${target.to}): ${String(err)}`);
|
|
197
|
+
}
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const sendKey = CHANNEL_SEND_KEYS[target.channel];
|
|
201
|
+
const sendFn = sendKey
|
|
202
|
+
? api.runtime?.channel?.[target.channel]?.[sendKey]
|
|
203
|
+
: undefined;
|
|
204
|
+
if (sendFn)
|
|
205
|
+
await sendFn(target.to, text);
|
|
206
|
+
};
|
|
207
|
+
const onLoginSuccess = async (sessionKey, sub, deliveryTarget) => {
|
|
208
|
+
const targetOrKey = deliveryTarget ?? parseSessionKeyToDeliveryTarget(sessionKey) ?? sessionKey;
|
|
209
|
+
await sendToSession(targetOrKey, `✓ Login successful as ${sub}. You can continue in the chat.`);
|
|
210
|
+
};
|
|
211
|
+
// Only 2 HTTP routes: OIDC callback and credential OAuth callback (IdP redirects here)
|
|
212
|
+
if (dynamicOidcEnabled && getResolvedOidcConfig) {
|
|
213
|
+
api.registerHttpRoute({
|
|
214
|
+
path: "/identity/oauth/callback",
|
|
215
|
+
handler: createOIDCCallbackHandlerLazy({
|
|
216
|
+
storeDir,
|
|
217
|
+
getOidcConfig: getResolvedOidcConfig,
|
|
218
|
+
identityService,
|
|
219
|
+
onLoginSuccess,
|
|
220
|
+
}),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
else if (explicitOidcEnabled) {
|
|
224
|
+
const oidcConfig = {
|
|
225
|
+
discoveryUrl: userpool.discoveryUrl,
|
|
226
|
+
clientId: userpool.clientId,
|
|
227
|
+
clientSecret: userpool.clientSecret,
|
|
228
|
+
scope: userpool.scope,
|
|
229
|
+
callbackUrl: userpool.callbackUrl,
|
|
230
|
+
};
|
|
231
|
+
api.registerHttpRoute({
|
|
232
|
+
path: "/identity/oauth/callback",
|
|
233
|
+
handler: createOIDCCallbackHandler({
|
|
234
|
+
storeDir,
|
|
235
|
+
config: oidcConfig,
|
|
236
|
+
identityService,
|
|
237
|
+
onLoginSuccess,
|
|
238
|
+
}),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
// Slash commands (all logic in command, no HTTP start endpoints)
|
|
242
|
+
const getOidcConfigForCommand = getResolvedOidcConfig ??
|
|
243
|
+
(explicitOidcEnabled
|
|
244
|
+
? async () => ({
|
|
245
|
+
discoveryUrl: userpool.discoveryUrl,
|
|
246
|
+
clientId: userpool.clientId,
|
|
247
|
+
clientSecret: userpool.clientSecret,
|
|
248
|
+
scope: userpool.scope,
|
|
249
|
+
callbackUrl: userpool.callbackUrl,
|
|
250
|
+
})
|
|
251
|
+
: async () => {
|
|
252
|
+
throw new Error("OIDC not configured. Set userpool in plugin config.");
|
|
253
|
+
});
|
|
254
|
+
const identityCommandsDeps = {
|
|
255
|
+
storeDir,
|
|
256
|
+
identityService,
|
|
257
|
+
getOidcConfig: getOidcConfigForCommand,
|
|
258
|
+
identityClient: hasIdentity ? identityClient : undefined,
|
|
259
|
+
logger: api.logger,
|
|
260
|
+
pluginConfig,
|
|
261
|
+
sendCredentialMessage: sendToSession,
|
|
262
|
+
};
|
|
263
|
+
api.registerCommand(createIdentityCommand(identityCommandsDeps));
|
|
264
|
+
api.registerCommand(createIdCommand(identityCommandsDeps));
|
|
265
|
+
api.logger.info("agent-identity: commands /identity, /id (login, status, logout, list-tips, list-credentials, fetch, set, unset); HTTP callback /identity/oauth/callback (credential OAuth uses Identity callback)");
|
|
266
|
+
// Tools (share deps with commands). Optional = only included when agent allowlist explicitly adds them.
|
|
267
|
+
api.registerTool(createIdentityWhoamiTool(identityCommandsDeps), { optional: false });
|
|
268
|
+
api.registerTool(createIdentityLogoutTool(identityCommandsDeps), { optional: false });
|
|
269
|
+
api.registerTool(createIdentityStatusTool(identityCommandsDeps), { optional: false });
|
|
270
|
+
api.registerTool(createIdentityLoginTool(identityCommandsDeps), { optional: false });
|
|
271
|
+
api.registerTool(createIdentityListCredentialsTool(identityCommandsDeps), { optional: false });
|
|
272
|
+
api.registerTool(createIdentityListTipsTool(identityCommandsDeps), { optional: false });
|
|
273
|
+
api.registerTool(createIdentityConfigTool(identityCommandsDeps), { optional: false });
|
|
274
|
+
api.registerTool(createIdentityFetchTool(identityCommandsDeps), { optional: false });
|
|
275
|
+
api.registerTool(createIdentitySetBindingTool(identityCommandsDeps), { optional: true });
|
|
276
|
+
api.registerTool(createIdentityUnsetBindingTool(identityCommandsDeps), { optional: true });
|
|
277
|
+
api.registerTool(createIdentityRiskCheckTool({ pluginConfig, logger: api.logger }), { optional: true });
|
|
278
|
+
api.registerTool(createIdentityListRiskPatternsTool(), { optional: true });
|
|
279
|
+
const authz = pluginConfig.authz;
|
|
280
|
+
const approvalTtlMs = (authz?.approvalTtlSeconds ?? 300) * 1000;
|
|
281
|
+
// Optional: agent must NOT have this (would self-approve). Use /identity approve for human approval.
|
|
282
|
+
api.registerTool(createIdentityApproveTool({ approvalTtlMs, logger: api.logger }), {
|
|
283
|
+
optional: true,
|
|
284
|
+
});
|
|
285
|
+
// Hooks
|
|
286
|
+
if (hasIdentity) {
|
|
287
|
+
api.on("before_agent_start", createBeforeAgentStartHandler({
|
|
288
|
+
storeDir,
|
|
289
|
+
identityService,
|
|
290
|
+
getOidcConfigForRefresh,
|
|
291
|
+
logger: api.logger,
|
|
292
|
+
}));
|
|
293
|
+
api.on("after_tool_call", createAfterToolCallHandler({ storeDir, logger: api.logger }));
|
|
294
|
+
}
|
|
295
|
+
if (authz?.enable) {
|
|
296
|
+
api.on("before_tool_call", createBeforeToolCallHandler({
|
|
297
|
+
storeDir,
|
|
298
|
+
identityClient: hasIdentity ? identityClient : undefined,
|
|
299
|
+
namespaceName: authz.namespaceName ?? "default",
|
|
300
|
+
logger: api.logger,
|
|
301
|
+
sendToSession,
|
|
302
|
+
authz,
|
|
303
|
+
approvalTtlMs,
|
|
304
|
+
}));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared identity actions: pure logic returning structured data.
|
|
3
|
+
* Used by both commands (format to text) and tools (return jsonResult).
|
|
4
|
+
*/
|
|
5
|
+
import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
|
6
|
+
import type { IdentityClientInterface } from "../services/identity-client.js";
|
|
7
|
+
import type { IdentityService } from "../services/identity-service.js";
|
|
8
|
+
import type { PluginConfig } from "../types.js";
|
|
9
|
+
import type { SessionKeyDeliveryTarget } from "../utils/derive-session-key.js";
|
|
10
|
+
import { type CredentialEntry } from "../store/credential-store.js";
|
|
11
|
+
export type OIDCConfigForCommand = {
|
|
12
|
+
discoveryUrl: string;
|
|
13
|
+
clientId: string;
|
|
14
|
+
clientSecret?: string;
|
|
15
|
+
scope?: string;
|
|
16
|
+
callbackUrl: string;
|
|
17
|
+
};
|
|
18
|
+
export type IdentityActionsLogger = {
|
|
19
|
+
info?: (msg: string) => void;
|
|
20
|
+
warn?: (msg: string) => void;
|
|
21
|
+
debug?: (msg: string) => void;
|
|
22
|
+
};
|
|
23
|
+
export type IdentityActionsDeps = {
|
|
24
|
+
storeDir: string;
|
|
25
|
+
identityService: IdentityService;
|
|
26
|
+
getOidcConfig: () => Promise<OIDCConfigForCommand>;
|
|
27
|
+
identityClient?: IdentityClientInterface;
|
|
28
|
+
logger?: IdentityActionsLogger;
|
|
29
|
+
pluginConfig?: PluginConfig;
|
|
30
|
+
sendCredentialMessage?: (targetOrSessionKey: SessionKeyDeliveryTarget | string, text: string) => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
export type FetchFlow = "oauth2-user" | "oauth2-m2m" | "apikey";
|
|
33
|
+
export type StatusResult = {
|
|
34
|
+
loggedIn: boolean;
|
|
35
|
+
sub: string | null;
|
|
36
|
+
hasTip: boolean;
|
|
37
|
+
/** Session login time (ms since epoch). */
|
|
38
|
+
sessionLoginAt?: number;
|
|
39
|
+
/** Session expiry (ms). Absent = no explicit expiry. */
|
|
40
|
+
sessionExpiresAt?: number | null;
|
|
41
|
+
/** TIP issued time (ms). */
|
|
42
|
+
tipIssuedAt?: number;
|
|
43
|
+
/** TIP expiry (ms). */
|
|
44
|
+
tipExpiresAt?: number;
|
|
45
|
+
/** TIP delegation chain (agent IDs). */
|
|
46
|
+
tipChain?: string[];
|
|
47
|
+
credentials: Record<string, CredentialEntry>;
|
|
48
|
+
bindings: Record<string, string>;
|
|
49
|
+
};
|
|
50
|
+
export declare function runStatus(deps: IdentityActionsDeps, sessionKey: string, config?: OpenClawConfig): Promise<StatusResult>;
|
|
51
|
+
export type LoginResult = {
|
|
52
|
+
kind: "already_logged_in";
|
|
53
|
+
sub: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "auth_url";
|
|
56
|
+
authUrl: string;
|
|
57
|
+
} | {
|
|
58
|
+
kind: "error";
|
|
59
|
+
message: string;
|
|
60
|
+
};
|
|
61
|
+
export declare function runLogin(deps: IdentityActionsDeps, sessionKey: string, options?: {
|
|
62
|
+
config?: OpenClawConfig;
|
|
63
|
+
deliveryTarget?: SessionKeyDeliveryTarget | null;
|
|
64
|
+
}): Promise<LoginResult>;
|
|
65
|
+
export type LogoutResult = {
|
|
66
|
+
ok: boolean;
|
|
67
|
+
};
|
|
68
|
+
export declare function runLogout(deps: IdentityActionsDeps, sessionKey: string): Promise<LogoutResult>;
|
|
69
|
+
export type ListCredentialsResult = {
|
|
70
|
+
providers: Array<{
|
|
71
|
+
name: string;
|
|
72
|
+
type: string;
|
|
73
|
+
flow?: string;
|
|
74
|
+
status: string;
|
|
75
|
+
binding?: string;
|
|
76
|
+
}>;
|
|
77
|
+
storedOnly: Array<{
|
|
78
|
+
name: string;
|
|
79
|
+
status: string;
|
|
80
|
+
binding?: string;
|
|
81
|
+
}>;
|
|
82
|
+
page: number;
|
|
83
|
+
hasMore: boolean;
|
|
84
|
+
totalCount?: number;
|
|
85
|
+
};
|
|
86
|
+
export declare function runListCredentials(deps: IdentityActionsDeps, sessionKey: string, page?: number): Promise<ListCredentialsResult>;
|
|
87
|
+
export type ListTipsResult = {
|
|
88
|
+
tips: Array<{
|
|
89
|
+
sessionKey: string;
|
|
90
|
+
sub: string;
|
|
91
|
+
chain: string[];
|
|
92
|
+
expiresAt: number;
|
|
93
|
+
ttlSec: number;
|
|
94
|
+
}>;
|
|
95
|
+
/** Bindings per sessionKey (provider -> envVar). */
|
|
96
|
+
bindingsBySession: Record<string, Record<string, string>>;
|
|
97
|
+
};
|
|
98
|
+
export declare function runListTips(deps: IdentityActionsDeps): Promise<ListTipsResult>;
|
|
99
|
+
export type ConfigResult = {
|
|
100
|
+
identity?: Record<string, unknown>;
|
|
101
|
+
userpool?: Record<string, unknown>;
|
|
102
|
+
authz?: Record<string, unknown>;
|
|
103
|
+
};
|
|
104
|
+
export declare function runConfig(deps: IdentityActionsDeps): Promise<ConfigResult>;
|
|
105
|
+
export type FetchResult = {
|
|
106
|
+
kind: "success";
|
|
107
|
+
message: string;
|
|
108
|
+
} | {
|
|
109
|
+
kind: "auth_url";
|
|
110
|
+
authUrl: string;
|
|
111
|
+
message: string;
|
|
112
|
+
} | {
|
|
113
|
+
kind: "error";
|
|
114
|
+
message: string;
|
|
115
|
+
};
|
|
116
|
+
export declare function runFetch(deps: IdentityActionsDeps, sessionKey: string, params: {
|
|
117
|
+
provider: string;
|
|
118
|
+
flow: FetchFlow;
|
|
119
|
+
flowExplicit?: boolean;
|
|
120
|
+
redirectUrl?: string;
|
|
121
|
+
scopes?: string[];
|
|
122
|
+
deliveryTarget?: SessionKeyDeliveryTarget | null;
|
|
123
|
+
config?: OpenClawConfig;
|
|
124
|
+
}): Promise<FetchResult>;
|
|
125
|
+
export type SetBindingResult = {
|
|
126
|
+
ok: boolean;
|
|
127
|
+
message?: string;
|
|
128
|
+
error?: string;
|
|
129
|
+
};
|
|
130
|
+
export declare function runSetBinding(deps: IdentityActionsDeps, sessionKey: string, params: {
|
|
131
|
+
provider: string;
|
|
132
|
+
envVar: string;
|
|
133
|
+
}): Promise<SetBindingResult>;
|
|
134
|
+
export type UnsetBindingResult = {
|
|
135
|
+
ok: boolean;
|
|
136
|
+
message?: string;
|
|
137
|
+
error?: string;
|
|
138
|
+
};
|
|
139
|
+
export declare function runUnsetBinding(deps: IdentityActionsDeps, sessionKey: string, params: {
|
|
140
|
+
provider: string;
|
|
141
|
+
}): Promise<UnsetBindingResult>;
|
|
142
|
+
//# sourceMappingURL=identity-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-actions.d.ts","sourceRoot":"","sources":["../../../src/actions/identity-actions.ts"],"names":[],"mappings":"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"}
|