@ory/argus 0.14.0 → 1.0.1
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.md +31 -46
- package/assets/commands/temporal-up.md +1 -1
- package/assets/skills/auth-setup/SKILL.md +1 -1
- package/assets/skills/local-dev/SKILL.md +17 -7
- package/assets/skills/ory-build-agent/SKILL.md +39 -91
- package/assets/skills/ory-e2b-sandbox/SKILL.md +18 -17
- package/assets/skills/ory-temporal-worker/SKILL.md +31 -33
- package/assets/skills/permissions-onboarding/SKILL.md +131 -104
- package/dist/adapters.d.ts +88 -32
- package/dist/adapters.js +443 -164
- package/dist/agent-auth.d.ts +226 -67
- package/dist/agent-auth.js +951 -205
- package/dist/auth-store.d.ts +37 -2
- package/dist/auth-store.js +37 -3
- package/dist/auth.d.ts +33 -4
- package/dist/auth.js +163 -20
- package/dist/bash-parser.d.ts +98 -0
- package/dist/bash-parser.js +396 -0
- package/dist/branding.d.ts +77 -16
- package/dist/branding.js +93 -23
- package/dist/build-info.json +4 -4
- package/dist/cli-invocation.d.ts +1 -1
- package/dist/cli-invocation.js +2 -1
- package/dist/cli.d.ts +20 -29
- package/dist/cli.js +271 -239
- package/dist/client.d.ts +175 -138
- package/dist/client.js +672 -391
- package/dist/config.d.ts +217 -54
- package/dist/config.js +461 -42
- package/dist/context.d.ts +10 -0
- package/dist/context.js +21 -0
- package/dist/contract-suite.d.ts +3 -5
- package/dist/contract-suite.js +75 -47
- package/dist/denial.d.ts +36 -3
- package/dist/denial.js +79 -10
- package/dist/event-reporter.d.ts +77 -0
- package/dist/event-reporter.js +776 -0
- package/dist/external-registrations-main.d.ts +10 -0
- package/dist/external-registrations-main.js +38 -0
- package/dist/external-registrations.d.ts +79 -0
- package/dist/external-registrations.js +188 -0
- package/dist/help-cli.d.ts +39 -0
- package/dist/help-cli.js +55 -0
- package/dist/hook-timeout.d.ts +64 -0
- package/dist/hook-timeout.js +88 -0
- package/dist/index.d.ts +28 -23
- package/dist/index.js +173 -58
- package/dist/lifecycle.d.ts +3 -3
- package/dist/lifecycle.js +38 -6
- package/dist/local/cli.js +11 -6
- package/dist/local/configs.d.ts +74 -18
- package/dist/local/configs.js +291 -84
- package/dist/local/health.js +7 -7
- package/dist/local/index.d.ts +2 -2
- package/dist/local/index.js +24 -10
- package/dist/local/manager.d.ts +20 -1
- package/dist/local/manager.js +159 -36
- package/dist/local/ports.d.ts +158 -0
- package/dist/local/ports.js +443 -0
- package/dist/local/seed.d.ts +13 -5
- package/dist/local/seed.js +62 -38
- package/dist/logger.d.ts +54 -25
- package/dist/logger.js +329 -63
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +10 -5
- package/dist/mirror-bootstrap.d.ts +48 -0
- package/dist/mirror-bootstrap.js +254 -0
- package/dist/opl.d.ts +289 -0
- package/dist/opl.js +446 -0
- package/dist/permission-mode.d.ts +87 -0
- package/dist/permission-mode.js +307 -0
- package/dist/permissions-cli.d.ts +13 -49
- package/dist/permissions-cli.js +154 -348
- package/dist/permissions.d.ts +148 -38
- package/dist/permissions.js +591 -45
- package/dist/post-install.d.ts +33 -0
- package/dist/post-install.js +127 -0
- package/dist/read-credential.d.ts +65 -0
- package/dist/read-credential.js +86 -0
- package/dist/registry/cli.js +5 -2
- package/dist/registry/config.d.ts +0 -17
- package/dist/registry/config.js +0 -23
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.js +2 -2
- package/dist/registry/manager.d.ts +4 -21
- package/dist/registry/manager.js +21 -37
- package/dist/runtime-credential.d.ts +140 -0
- package/dist/runtime-credential.js +572 -0
- package/dist/runtime.d.ts +413 -0
- package/dist/runtime.js +825 -0
- package/dist/setup.d.ts +23 -47
- package/dist/setup.js +59 -116
- package/dist/skills.js +0 -7
- package/dist/status-cli.d.ts +27 -11
- package/dist/status-cli.js +121 -115
- package/dist/status-data.d.ts +116 -17
- package/dist/status-data.js +121 -38
- package/dist/subject.d.ts +126 -20
- package/dist/subject.js +215 -30
- package/dist/testing.d.ts +74 -38
- package/dist/testing.js +185 -68
- package/dist/tool-catalog.d.ts +53 -11
- package/dist/tool-catalog.js +164 -13
- package/dist/tool-metadata.d.ts +7 -6
- package/dist/tool-metadata.js +6 -5
- package/dist/types.d.ts +11 -1
- package/dist/uninstall.d.ts +71 -34
- package/dist/uninstall.js +217 -85
- package/dist/user-login.d.ts +9 -10
- package/dist/user-login.js +56 -75
- package/dist/watch-cli.d.ts +6 -0
- package/dist/watch-cli.js +217 -0
- package/package.json +4 -27
- package/assets/commands/dashboard.md +0 -34
- package/dist/dashboard-cli.d.ts +0 -8
- package/dist/dashboard-cli.js +0 -70
- package/dist/dev.d.ts +0 -103
- package/dist/dev.js +0 -583
- package/dist/interactive-setup.d.ts +0 -286
- package/dist/interactive-setup.js +0 -1734
- package/dist/local/jaeger-main.d.ts +0 -13
- package/dist/local/jaeger-main.js +0 -85
- package/dist/local/jaeger.d.ts +0 -50
- package/dist/local/jaeger.js +0 -162
- package/dist/otel/exporter.d.ts +0 -17
- package/dist/otel/exporter.js +0 -12
- package/dist/otel/index.d.ts +0 -2
- package/dist/otel/index.js +0 -8
- package/dist/otel/otlp.d.ts +0 -103
- package/dist/otel/otlp.js +0 -385
- package/dist/project-api-key.d.ts +0 -69
- package/dist/project-api-key.js +0 -147
- package/dist/setup-actions.d.ts +0 -232
- package/dist/setup-actions.js +0 -507
- package/dist/tracer.d.ts +0 -190
- package/dist/tracer.js +0 -481
- package/dist/watch-sandbox.d.ts +0 -9
- package/dist/watch-sandbox.js +0 -81
- package/dist/web/api.d.ts +0 -33
- package/dist/web/api.js +0 -294
- package/dist/web/launch.d.ts +0 -11
- package/dist/web/launch.js +0 -96
- package/dist/web/server.d.ts +0 -20
- package/dist/web/server.js +0 -233
- package/dist/web/types.d.ts +0 -65
- package/dist/web/types.js +0 -2
- package/dist/webapp/assets/index-Wucl4SZs.css +0 -1
- package/dist/webapp/assets/index-m-GtEdq0.js +0 -49
- package/dist/webapp/favicon.ico +0 -0
- package/dist/webapp/index.html +0 -15
package/dist/cli.js
CHANGED
|
@@ -38,8 +38,6 @@ exports.printOryConfig = printOryConfig;
|
|
|
38
38
|
exports.printEnvironment = printEnvironment;
|
|
39
39
|
exports.printLogTail = printLogTail;
|
|
40
40
|
exports.printEnvHelp = printEnvHelp;
|
|
41
|
-
exports.printTraceTail = printTraceTail;
|
|
42
|
-
exports.runWatchCommand = runWatchCommand;
|
|
43
41
|
exports.isTtyAvailable = isTtyAvailable;
|
|
44
42
|
exports.promptOnTty = promptOnTty;
|
|
45
43
|
exports.promptForProjectUrl = promptForProjectUrl;
|
|
@@ -49,31 +47,34 @@ const fs = __importStar(require("node:fs"));
|
|
|
49
47
|
const readline = __importStar(require("node:readline"));
|
|
50
48
|
const config_js_1 = require("./config.js");
|
|
51
49
|
const agent_auth_js_1 = require("./agent-auth.js");
|
|
52
|
-
const
|
|
50
|
+
const logger_js_1 = require("./logger.js");
|
|
53
51
|
const cli_invocation_js_1 = require("./cli-invocation.js");
|
|
54
52
|
const client_js_1 = require("./client.js");
|
|
55
53
|
/**
|
|
56
54
|
* Shared `configure` command implementation for all plugin CLIs.
|
|
57
55
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
56
|
+
* `configure` only ever touches the **security** half of a plugin. The
|
|
57
|
+
* developer-experience half — skills, commands, the local Ory stack, the MCP
|
|
58
|
+
* server, local activity logging — is installed unconditionally and has nothing to
|
|
59
|
+
* configure, so it is never mentioned here as an alternative or a fallback.
|
|
61
60
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
61
|
+
* Connecting takes the project URL and canonical broker origin from the Ory
|
|
62
|
+
* Console (Agent Security). The public OAuth2 client id defaults to the reserved
|
|
63
|
+
* Agent Security login client and can be overridden for custom deployments.
|
|
64
|
+
* Existing configurations use the project URL as a legacy broker fallback.
|
|
65
|
+
* `--disconnect` clears all three stored connection values.
|
|
66
|
+
*
|
|
67
|
+
* With no arguments, prints what is currently resolved.
|
|
68
68
|
*/
|
|
69
69
|
function runConfigureCommand(binName, args) {
|
|
70
70
|
let projectUrl;
|
|
71
|
+
let agentSecurityUrl;
|
|
71
72
|
let projectId;
|
|
72
|
-
let apiKey;
|
|
73
73
|
let oauth2ClientId;
|
|
74
|
-
let
|
|
75
|
-
// `undefined` = not specified; a string
|
|
76
|
-
//
|
|
74
|
+
let disconnect = false;
|
|
75
|
+
// `undefined` = not specified; a string overrides the default `User`
|
|
76
|
+
// namespace; empty string ("") clears the override (via
|
|
77
|
+
// --no-user-subject-namespace) so the default `User` namespace applies.
|
|
77
78
|
let userSubjectNamespace;
|
|
78
79
|
for (let i = 0; i < args.length; i++) {
|
|
79
80
|
switch (args[i]) {
|
|
@@ -86,14 +87,14 @@ function runConfigureCommand(binName, args) {
|
|
|
86
87
|
case "--project-id":
|
|
87
88
|
projectId = args[++i];
|
|
88
89
|
break;
|
|
89
|
-
case "--
|
|
90
|
-
|
|
90
|
+
case "--agent-security-url":
|
|
91
|
+
agentSecurityUrl = args[++i];
|
|
91
92
|
break;
|
|
92
93
|
case "--oauth2-client-id":
|
|
93
94
|
oauth2ClientId = args[++i];
|
|
94
95
|
break;
|
|
95
|
-
case "--
|
|
96
|
-
|
|
96
|
+
case "--disconnect":
|
|
97
|
+
disconnect = true;
|
|
97
98
|
break;
|
|
98
99
|
case "--user-subject-namespace":
|
|
99
100
|
userSubjectNamespace = args[++i];
|
|
@@ -104,10 +105,10 @@ function runConfigureCommand(binName, args) {
|
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
if (!projectUrl &&
|
|
108
|
+
!agentSecurityUrl &&
|
|
107
109
|
!projectId &&
|
|
108
|
-
!apiKey &&
|
|
109
110
|
!oauth2ClientId &&
|
|
110
|
-
!
|
|
111
|
+
!disconnect &&
|
|
111
112
|
userSubjectNamespace === undefined) {
|
|
112
113
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
113
114
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
@@ -116,135 +117,163 @@ function runConfigureCommand(binName, args) {
|
|
|
116
117
|
console.log("");
|
|
117
118
|
console.log(`Config file: ${configPath}${fs.existsSync(configPath) ? "" : " (not created yet)"}`);
|
|
118
119
|
console.log(`Project URL: ${resolved.projectUrl ?? "(not set)"} [${resolved.projectUrlSource}]`);
|
|
119
|
-
console.log(`
|
|
120
|
-
console.log(`API Key: ${resolved.apiKey ? "(set)" : "(not set)"} [${resolved.apiKeySource}]`);
|
|
120
|
+
console.log(`Agent Security URL: ${resolved.agentSecurityUrl ?? "(not set)"} [${resolved.agentSecurityUrlSource}]`);
|
|
121
121
|
console.log(`OAuth2 Client ID: ${resolved.oauth2ClientId ?? "(not set)"} [${resolved.oauth2ClientIdSource}]`);
|
|
122
|
-
console.log(`
|
|
123
|
-
console.log(`User subject ns: ${resolved.userSubjectNamespace ?? "(direct subject id)"} [${resolved.userSubjectNamespaceSource}]`);
|
|
122
|
+
console.log(`Agent Security: ${resolved.security.connected ? "connected" : `not connected (${(0, config_js_1.describeSecurityGap)(resolved.security)})`}`);
|
|
124
123
|
console.log("");
|
|
125
|
-
console.log(
|
|
126
|
-
console.log(` ${
|
|
124
|
+
console.log(`Project ID: ${resolved.projectId ?? "(not set)"} [${resolved.projectIdSource}]`);
|
|
125
|
+
console.log(`User subject ns: ${resolved.userSubjectNamespace ?? "User (default)"} [${resolved.userSubjectNamespaceSource}]`);
|
|
127
126
|
console.log("");
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
if (resolved.security.connected) {
|
|
128
|
+
console.log("Sign-in and permission checks are running. Tool grants, explicit blocks,");
|
|
129
|
+
console.log("and the observe/enforce posture are managed in the Ory Console (Agent Security).");
|
|
130
|
+
console.log("");
|
|
131
|
+
console.log("To disconnect (skills, commands, the local stack, and activity logging keep working):");
|
|
132
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --disconnect`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
console.log("Skills, commands, the local Ory stack, the MCP server, and local activity logging are");
|
|
136
|
+
console.log("installed and working — they don't need a project. Only sign-in and permission");
|
|
137
|
+
console.log("checks are off.");
|
|
138
|
+
console.log("");
|
|
139
|
+
console.log("To turn them on, supply the project and canonical Agent Security origin:");
|
|
140
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL> --agent-security-url <URL>`);
|
|
141
|
+
}
|
|
130
142
|
console.log("");
|
|
131
|
-
console.log("
|
|
132
|
-
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --
|
|
143
|
+
console.log("Users are addressed as SubjectSets (default namespace 'User'). To override the namespace (must match how the project's permissions were written):");
|
|
144
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --user-subject-namespace <Namespace> (reset to 'User' with --no-user-subject-namespace)`);
|
|
133
145
|
console.log("");
|
|
134
146
|
console.log("Or set environment variables:");
|
|
135
147
|
console.log(" export ORY_PROJECT_URL=https://your-project.projects.oryapis.com");
|
|
148
|
+
console.log(" export ORY_AGENT_SECURITY_URL=https://agents.console.ory.com");
|
|
136
149
|
console.log(" # ORY_SDK_URL (the Ory Console 'Get Started' name) is accepted as an alias.");
|
|
137
150
|
console.log(" # ORY_PROJECT_ID=<project uuid> is stored for admin operations (not an SDK URL).");
|
|
138
|
-
console.log(
|
|
139
|
-
console.log(" export ORY_AGENT_API_KEY=ory_pat_...");
|
|
151
|
+
console.log(` # ORY_OAUTH2_CLIENT_ID defaults to ${config_js_1.DEFAULT_OAUTH2_CLIENT_ID}.`);
|
|
140
152
|
return;
|
|
141
153
|
}
|
|
142
|
-
if (
|
|
143
|
-
//
|
|
144
|
-
|
|
154
|
+
if (disconnect) {
|
|
155
|
+
// Clear both required values. Everything else the plugin does is
|
|
156
|
+
// unaffected — this turns off sign-in and permission checks, nothing more.
|
|
157
|
+
(0, config_js_1.saveConfig)({ projectUrl: null, agentSecurityUrl: null, oauth2ClientId: null });
|
|
145
158
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
146
159
|
console.log(`Configuration saved to ${configPath}`);
|
|
147
|
-
console.log("
|
|
160
|
+
console.log(" Ory Agent Security: disconnected (no sign-in, no permission checks)");
|
|
148
161
|
console.log("");
|
|
149
|
-
console.log("
|
|
162
|
+
console.log("Skills, commands, the local Ory stack, the MCP server, and local activity logging");
|
|
163
|
+
console.log("are unaffected and keep working.");
|
|
164
|
+
if (process.env.ORY_PROJECT_URL || process.env.ORY_SDK_URL || process.env.ORY_AGENT_SECURITY_URL || process.env.ORY_OAUTH2_CLIENT_ID) {
|
|
165
|
+
console.log("");
|
|
166
|
+
console.log("Note: ORY_PROJECT_URL / ORY_SDK_URL / ORY_AGENT_SECURITY_URL /");
|
|
167
|
+
console.log("ORY_OAUTH2_CLIENT_ID are set in your");
|
|
168
|
+
console.log("environment and take precedence over the config file — unset them to stay");
|
|
169
|
+
console.log("disconnected.");
|
|
170
|
+
}
|
|
150
171
|
return;
|
|
151
172
|
}
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
// Agent Security needs the project and broker origin. The login client uses
|
|
174
|
+
// the reserved default unless an explicit flag, environment variable, or
|
|
175
|
+
// persisted override is present. A bare --project-id is an admin identifier
|
|
176
|
+
// only and doesn't connect anything, so it doesn't trigger this.
|
|
177
|
+
if (agentSecurityUrl) {
|
|
178
|
+
try {
|
|
179
|
+
const parsed = new URL(agentSecurityUrl);
|
|
180
|
+
if ((parsed.protocol !== "https:" && parsed.origin !== config_js_1.LOCAL_AGENT_SECURITY_URL) ||
|
|
181
|
+
!parsed.hostname ||
|
|
182
|
+
parsed.username ||
|
|
183
|
+
parsed.password ||
|
|
184
|
+
(parsed.pathname !== "" && parsed.pathname !== "/") ||
|
|
185
|
+
parsed.search ||
|
|
186
|
+
parsed.hash) {
|
|
187
|
+
throw new Error("invalid origin");
|
|
188
|
+
}
|
|
189
|
+
agentSecurityUrl = parsed.origin;
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
console.error("Error: --agent-security-url must be an HTTPS origin without credentials, path, query, or fragment " +
|
|
193
|
+
`(for example ${config_js_1.DEFAULT_AGENT_SECURITY_URL} or ${config_js_1.LOCAL_AGENT_SECURITY_URL}).`);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (projectUrl || agentSecurityUrl || oauth2ClientId) {
|
|
198
|
+
const persisted = (0, config_js_1.loadConfig)();
|
|
199
|
+
const resolvedUrl = projectUrl ?? process.env.ORY_PROJECT_URL ?? process.env.ORY_SDK_URL ?? persisted.projectUrl;
|
|
200
|
+
if (!resolvedUrl) {
|
|
201
|
+
console.error("Error: Ory Agent Security needs --project-url <URL>.\n" +
|
|
202
|
+
"\n" +
|
|
203
|
+
"Copy the project URL from the Ory Console under Agent Security:\n" +
|
|
204
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL>\n` +
|
|
163
205
|
"\n" +
|
|
164
|
-
"
|
|
165
|
-
"environment. The client must be a public OAuth2 client (no client secret,\n" +
|
|
166
|
-
"token_endpoint_auth_method=none) registered in your Ory project with all four\n" +
|
|
167
|
-
"loopback redirect URIs:\n" +
|
|
168
|
-
" http://127.0.0.1:47823/callback\n" +
|
|
169
|
-
" http://127.0.0.1:47824/callback\n" +
|
|
170
|
-
" http://127.0.0.1:47825/callback\n" +
|
|
171
|
-
" http://127.0.0.1:47826/callback\n" +
|
|
206
|
+
"(--agent-security-url and --oauth2-client-id override their production defaults.)\n" +
|
|
172
207
|
"\n" +
|
|
173
|
-
"
|
|
174
|
-
" ory create oauth2-client --project <project-id> \\\n" +
|
|
175
|
-
" --name \"ory-agent-plugin\" \\\n" +
|
|
176
|
-
" --grant-type authorization_code,refresh_token \\\n" +
|
|
177
|
-
" --response-type code \\\n" +
|
|
178
|
-
" --scope openid,offline_access \\\n" +
|
|
179
|
-
" --token-endpoint-auth-method none \\\n" +
|
|
180
|
-
" --redirect-uri http://127.0.0.1:47823/callback \\\n" +
|
|
181
|
-
" --redirect-uri http://127.0.0.1:47824/callback \\\n" +
|
|
182
|
-
" --redirect-uri http://127.0.0.1:47825/callback \\\n" +
|
|
183
|
-
" --redirect-uri http://127.0.0.1:47826/callback\n" +
|
|
208
|
+
"Connecting needs no workspace privilege. The plugin never provisions the project itself.\n" +
|
|
184
209
|
"\n" +
|
|
185
|
-
"
|
|
186
|
-
|
|
210
|
+
"Nothing was changed. The plugin's skills, commands, local Ory stack, MCP\n" +
|
|
211
|
+
"server, and local activity logging work without a project and are unaffected.");
|
|
187
212
|
process.exit(1);
|
|
188
213
|
}
|
|
214
|
+
if (projectUrl && !agentSecurityUrl && !process.env.ORY_AGENT_SECURITY_URL?.trim() && !persisted.agentSecurityUrl) {
|
|
215
|
+
agentSecurityUrl = config_js_1.DEFAULT_AGENT_SECURITY_URL;
|
|
216
|
+
}
|
|
189
217
|
}
|
|
190
218
|
const update = {};
|
|
191
219
|
if (projectUrl)
|
|
192
220
|
update.projectUrl = projectUrl;
|
|
221
|
+
if (agentSecurityUrl)
|
|
222
|
+
update.agentSecurityUrl = agentSecurityUrl;
|
|
193
223
|
if (projectId)
|
|
194
224
|
update.projectId = projectId;
|
|
195
|
-
if (apiKey) {
|
|
196
|
-
update.apiKey = apiKey;
|
|
197
|
-
// A hand-supplied key has no known token id; drop any stale id so uninstall
|
|
198
|
-
// never tries to delete a different token by an id that no longer matches.
|
|
199
|
-
update.apiKeyId = null;
|
|
200
|
-
}
|
|
201
225
|
if (oauth2ClientId)
|
|
202
226
|
update.oauth2ClientId = oauth2ClientId;
|
|
203
|
-
// A non-empty namespace
|
|
204
|
-
// (from --no-user-subject-namespace) clears
|
|
227
|
+
// A non-empty namespace overrides the default `User` SubjectSet namespace; the
|
|
228
|
+
// empty string (from --no-user-subject-namespace) clears the override (null ⇒
|
|
229
|
+
// delete the key) so the `User` default applies.
|
|
205
230
|
if (userSubjectNamespace !== undefined) {
|
|
206
231
|
update.userSubjectNamespace = userSubjectNamespace === "" ? null : userSubjectNamespace;
|
|
207
232
|
}
|
|
208
|
-
// Configuring an actual connection (a slug-based URL, api key, or client id)
|
|
209
|
-
// implies leaving audit-only mode. A bare project id is only an admin
|
|
210
|
-
// identifier — it doesn't connect anything on its own — so it doesn't flip
|
|
211
|
-
// the flag.
|
|
212
|
-
if (projectUrl || apiKey || oauth2ClientId)
|
|
213
|
-
update.auditOnly = false;
|
|
214
233
|
(0, config_js_1.saveConfig)(update);
|
|
215
234
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
216
235
|
console.log(`Configuration saved to ${configPath}`);
|
|
217
236
|
if (projectUrl)
|
|
218
237
|
console.log(` Project URL: ${projectUrl}`);
|
|
238
|
+
if (agentSecurityUrl)
|
|
239
|
+
console.log(` Agent Security URL: ${agentSecurityUrl}`);
|
|
219
240
|
if (projectId)
|
|
220
241
|
console.log(` Project ID: ${projectId}`);
|
|
221
|
-
if (apiKey)
|
|
222
|
-
console.log(` API Key: (set)`);
|
|
223
242
|
if (oauth2ClientId)
|
|
224
243
|
console.log(` OAuth2 Client ID: ${oauth2ClientId}`);
|
|
225
244
|
if (userSubjectNamespace !== undefined)
|
|
226
|
-
console.log(` User subject namespace: ${userSubjectNamespace === "" ? "(
|
|
245
|
+
console.log(` User subject namespace: ${userSubjectNamespace === "" ? "(reset to default 'User')" : userSubjectNamespace}`);
|
|
246
|
+
// Report the resulting posture rather than assuming the write connected
|
|
247
|
+
// anything: `--project-id` on its own changes no part of it.
|
|
248
|
+
const security = (0, config_js_1.resolveConfig)().security;
|
|
249
|
+
console.log(` Ory Agent Security: ${security.connected ? "connected — sign-in and permission checks run on the next session" : `not connected (${(0, config_js_1.describeSecurityGap)(security)})`}`);
|
|
227
250
|
console.log("");
|
|
228
251
|
console.log("This configuration is shared across all Ory agent plugins.");
|
|
229
|
-
console.log("Environment variables (ORY_PROJECT_URL,
|
|
252
|
+
console.log("Environment variables (ORY_PROJECT_URL, ORY_AGENT_SECURITY_URL, ORY_OAUTH2_CLIENT_ID) take precedence when set.");
|
|
230
253
|
}
|
|
231
254
|
/**
|
|
232
|
-
* Print the "Configuration:" block showing
|
|
255
|
+
* Print the "Configuration:" block showing the resolved Ory connection.
|
|
233
256
|
*/
|
|
234
257
|
function printOryConfig() {
|
|
235
258
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
236
259
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
237
|
-
const namespace = process.env.ORY_PERMISSION_NAMESPACE || "
|
|
260
|
+
const namespace = process.env.ORY_PERMISSION_NAMESPACE || "AgentTool";
|
|
238
261
|
console.log("Configuration:");
|
|
239
262
|
console.log(` Config file: ${configPath}`);
|
|
240
|
-
console.log(`
|
|
263
|
+
console.log(` Agent Security: ${resolved.security.connected
|
|
264
|
+
? "connected (sign-in + permission checks + activity logging)"
|
|
265
|
+
: `not connected — ${(0, config_js_1.describeSecurityGap)(resolved.security)} (local activity logging only)`}`);
|
|
241
266
|
console.log(` Project URL: ${resolved.projectUrl ?? "NOT SET"} [source: ${resolved.projectUrlSource}]`);
|
|
242
|
-
console.log(`
|
|
243
|
-
console.log(` API Key: ${resolved.apiKey ? "(set)" : "NOT SET"} [source: ${resolved.apiKeySource}]`);
|
|
267
|
+
console.log(` Agent Security: ${resolved.agentSecurityUrl ?? "NOT SET"} [source: ${resolved.agentSecurityUrlSource}]`);
|
|
244
268
|
console.log(` OAuth2 Client: ${resolved.oauth2ClientId ?? "NOT SET"} [source: ${resolved.oauth2ClientIdSource}]`);
|
|
245
|
-
console.log(`
|
|
269
|
+
console.log(` Project ID: ${resolved.projectId ?? "NOT SET"} [source: ${resolved.projectIdSource}]`);
|
|
270
|
+
// Only meaningful while connected — with no checks running there is no deny
|
|
271
|
+
// to have a posture about.
|
|
272
|
+
if (resolved.security.connected) {
|
|
273
|
+
console.log(` Permission mode: ${resolved.permissionMode} [source: ${resolved.permissionModeSource}]`);
|
|
274
|
+
}
|
|
246
275
|
console.log(` Namespace: ${namespace}`);
|
|
247
|
-
console.log(` User subject ns: ${resolved.userSubjectNamespace ?? "(
|
|
276
|
+
console.log(` User subject ns: ${resolved.userSubjectNamespace ?? "User (default)"} [source: ${resolved.userSubjectNamespaceSource}]`);
|
|
248
277
|
}
|
|
249
278
|
/**
|
|
250
279
|
* Print the "Environment:" block showing Ory-related environment variables.
|
|
@@ -255,32 +284,20 @@ function printEnvironment() {
|
|
|
255
284
|
const vars = [
|
|
256
285
|
["ORY_PROJECT_URL", process.env.ORY_PROJECT_URL, false],
|
|
257
286
|
["ORY_SDK_URL", process.env.ORY_SDK_URL, false],
|
|
287
|
+
["ORY_AGENT_SECURITY_URL", process.env.ORY_AGENT_SECURITY_URL, false],
|
|
258
288
|
["ORY_PROJECT_ID", process.env.ORY_PROJECT_ID, false],
|
|
259
|
-
[
|
|
260
|
-
"ORY_AGENT_API_KEY",
|
|
261
|
-
process.env.ORY_AGENT_API_KEY ? "(set)" : undefined,
|
|
262
|
-
false,
|
|
263
|
-
],
|
|
264
289
|
["ORY_AGENT_CLIENT_ID", process.env.ORY_AGENT_CLIENT_ID, false],
|
|
265
290
|
["ORY_OAUTH2_CLIENT_ID", process.env.ORY_OAUTH2_CLIENT_ID, false],
|
|
266
291
|
[
|
|
267
|
-
"
|
|
268
|
-
process.env.
|
|
292
|
+
"ORY_USER_OAUTH2_TOKEN",
|
|
293
|
+
process.env.ORY_USER_OAUTH2_TOKEN ? "(set)" : undefined,
|
|
269
294
|
false,
|
|
270
295
|
],
|
|
271
296
|
["ORY_USER_SUBJECT_ID", process.env.ORY_USER_SUBJECT_ID, false],
|
|
272
297
|
["ORY_AGENT_SUBJECT_ID", process.env.ORY_AGENT_SUBJECT_ID, false],
|
|
273
298
|
["ORY_AGENT_DEBUG", process.env.ORY_AGENT_DEBUG, false],
|
|
274
299
|
["ORY_AGENT_LOG_FILE", process.env.ORY_AGENT_LOG_FILE, false],
|
|
275
|
-
["ORY_AGENT_TRACE_FILE", process.env.ORY_AGENT_TRACE_FILE, false],
|
|
276
300
|
];
|
|
277
|
-
if (process.env.ORY_API_KEY && !process.env.ORY_AGENT_API_KEY) {
|
|
278
|
-
vars.splice(2, 0, [
|
|
279
|
-
"ORY_API_KEY",
|
|
280
|
-
"(set, DEPRECATED — use ORY_AGENT_API_KEY)",
|
|
281
|
-
false,
|
|
282
|
-
]);
|
|
283
|
-
}
|
|
284
301
|
for (const [name, value, required] of vars) {
|
|
285
302
|
const display = value
|
|
286
303
|
? value
|
|
@@ -292,12 +309,11 @@ function printEnvironment() {
|
|
|
292
309
|
}
|
|
293
310
|
}
|
|
294
311
|
/**
|
|
295
|
-
* Print the last
|
|
312
|
+
* Print the last 10 unified activity/debug log entries. When `harness` is given the path is
|
|
296
313
|
* resolved the same way the plugin does at runtime — the default per-harness
|
|
297
314
|
* data-dir location when `ORY_AGENT_LOG_FILE` is unset — so `status` finds the
|
|
298
|
-
* log without the reader hand-setting env vars.
|
|
299
|
-
*
|
|
300
|
-
* one-line pointer on how to turn it on rather than staying silent.
|
|
315
|
+
* log without the reader hand-setting env vars. Activity is always filed;
|
|
316
|
+
* verbose diagnostic entries are included only when `ORY_AGENT_DEBUG=true`.
|
|
301
317
|
*/
|
|
302
318
|
function printLogTail(harness) {
|
|
303
319
|
const logFile = harness
|
|
@@ -306,12 +322,11 @@ function printLogTail(harness) {
|
|
|
306
322
|
if (logFile && fs.existsSync(logFile)) {
|
|
307
323
|
const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n");
|
|
308
324
|
console.log("");
|
|
309
|
-
console.log(`
|
|
310
|
-
console.log("Last
|
|
311
|
-
for (const line of lines.slice(-
|
|
325
|
+
console.log(`Activity log: ${logFile} (${lines.length} events)`);
|
|
326
|
+
console.log("Last 10 events:");
|
|
327
|
+
for (const line of lines.slice(-10)) {
|
|
312
328
|
try {
|
|
313
|
-
|
|
314
|
-
console.log(` ${entry.timestamp} [${entry.level}] ${entry.event}`);
|
|
329
|
+
console.log(" " + (0, logger_js_1.formatLogEntry)(JSON.parse(line)));
|
|
315
330
|
}
|
|
316
331
|
catch {
|
|
317
332
|
console.log(` ${line.slice(0, 120)}`);
|
|
@@ -321,8 +336,8 @@ function printLogTail(harness) {
|
|
|
321
336
|
else if (harness) {
|
|
322
337
|
console.log("");
|
|
323
338
|
console.log(logFile
|
|
324
|
-
? `
|
|
325
|
-
: "
|
|
339
|
+
? `Activity log: none yet — events land in ${logFile} once a session runs`
|
|
340
|
+
: "Activity log: disabled (ORY_AGENT_LOG_FILE set empty)");
|
|
326
341
|
}
|
|
327
342
|
}
|
|
328
343
|
/**
|
|
@@ -334,79 +349,19 @@ function printEnvHelp(binName) {
|
|
|
334
349
|
console.log("");
|
|
335
350
|
console.log(" Option 1 — Save to config file (persists across sessions):");
|
|
336
351
|
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url https://your-project.projects.oryapis.com \\`);
|
|
337
|
-
console.log(" --
|
|
338
|
-
console.log(" --
|
|
352
|
+
console.log(" --agent-security-url https://agents.console.ory.com \\");
|
|
353
|
+
console.log(" --oauth2-client-id <public OAuth2 client id>");
|
|
339
354
|
console.log("");
|
|
340
355
|
console.log(" Option 2 — Set environment variables:");
|
|
341
356
|
console.log(" export ORY_PROJECT_URL=https://your-project.projects.oryapis.com");
|
|
357
|
+
console.log(" export ORY_AGENT_SECURITY_URL=https://agents.console.ory.com");
|
|
342
358
|
console.log(" export ORY_OAUTH2_CLIENT_ID=<public OAuth2 client id>");
|
|
343
|
-
console.log("
|
|
359
|
+
console.log("");
|
|
360
|
+
console.log(" Both values come from the Ory Console (Agent Security), which provisions the");
|
|
361
|
+
console.log(" project's login client, permission model, grants, and enforce posture.");
|
|
344
362
|
console.log("");
|
|
345
363
|
console.log("If neither is set when a session starts, the agent will prompt for configuration.");
|
|
346
364
|
}
|
|
347
|
-
/**
|
|
348
|
-
* Print the last 5 trace spans. When `harness` is given the path is resolved
|
|
349
|
-
* the same way the plugin does at runtime — the default per-harness data-dir
|
|
350
|
-
* location when `ORY_AGENT_TRACE_FILE` is unset — so `status` shows recent
|
|
351
|
-
* activity out of the box (traces are written on every recorded span). When no
|
|
352
|
-
* spans have been recorded yet, prints a one-line pointer at the trace file so
|
|
353
|
-
* the reader knows where to look (and how to watch it live).
|
|
354
|
-
*/
|
|
355
|
-
function printTraceTail(harness) {
|
|
356
|
-
const traceFile = harness
|
|
357
|
-
? (0, client_js_1.resolveTraceFilePath)(harness)
|
|
358
|
-
: process.env.ORY_AGENT_TRACE_FILE;
|
|
359
|
-
if (traceFile && fs.existsSync(traceFile)) {
|
|
360
|
-
const lines = fs.readFileSync(traceFile, "utf-8").trim().split("\n");
|
|
361
|
-
console.log("");
|
|
362
|
-
console.log(`Trace file: ${traceFile} (${lines.length} spans)`);
|
|
363
|
-
console.log("Last 5 spans:");
|
|
364
|
-
for (const line of lines.slice(-5)) {
|
|
365
|
-
try {
|
|
366
|
-
const span = JSON.parse(line);
|
|
367
|
-
console.log(" " + (0, tracer_js_1.formatSpan)(span));
|
|
368
|
-
}
|
|
369
|
-
catch {
|
|
370
|
-
console.log(` ${line.slice(0, 120)}`);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
else if (harness) {
|
|
375
|
-
console.log("");
|
|
376
|
-
console.log(traceFile
|
|
377
|
-
? `Trace file: none yet — spans land in ${traceFile} once a session runs a tool`
|
|
378
|
-
: "Trace file: disabled (ORY_AGENT_TRACE_FILE set empty)");
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Run the live trace watcher. Tails the NDJSON trace file and prints
|
|
383
|
-
* formatted spans to stdout as they arrive. Blocks until interrupted.
|
|
384
|
-
*/
|
|
385
|
-
function runWatchCommand(harness, args) {
|
|
386
|
-
// Precedence: explicit arg → resolved default (honors ORY_AGENT_TRACE_FILE,
|
|
387
|
-
// falling back to the per-harness data-dir path). The resolver returns
|
|
388
|
-
// undefined only when tracing is explicitly disabled (ORY_AGENT_TRACE_FILE
|
|
389
|
-
// set empty), so that's the one case that dead-ends here.
|
|
390
|
-
const traceFile = args[0] || (0, client_js_1.resolveTraceFilePath)(harness);
|
|
391
|
-
if (!traceFile) {
|
|
392
|
-
console.error("Trace file is disabled (ORY_AGENT_TRACE_FILE is set empty).\n" +
|
|
393
|
-
"Unset it, or pass a path: watch <trace-file>\n");
|
|
394
|
-
process.exit(1);
|
|
395
|
-
}
|
|
396
|
-
console.log(`Watching traces: ${traceFile}`);
|
|
397
|
-
if (!fs.existsSync(traceFile)) {
|
|
398
|
-
console.log("(file doesn't exist yet — waiting for the first span…)");
|
|
399
|
-
}
|
|
400
|
-
console.log("Press Ctrl+C to stop.\n");
|
|
401
|
-
const stop = (0, tracer_js_1.watchTraceFile)(traceFile, (span) => {
|
|
402
|
-
console.log((0, tracer_js_1.formatSpan)(span));
|
|
403
|
-
});
|
|
404
|
-
process.on("SIGINT", () => {
|
|
405
|
-
stop();
|
|
406
|
-
console.log("\nStopped watching.");
|
|
407
|
-
process.exit(0);
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
365
|
/**
|
|
411
366
|
* Returns true if `/dev/tty` can be opened for reading. Use this before
|
|
412
367
|
* attempting to prompt the user — the harness has already taken stdin so
|
|
@@ -490,8 +445,9 @@ async function promptForProjectUrl(binName) {
|
|
|
490
445
|
process.stderr.write(`\nIgnoring invalid project URL "${answer}".\n\n`);
|
|
491
446
|
return null;
|
|
492
447
|
}
|
|
493
|
-
(0, config_js_1.saveConfig)({ projectUrl: url,
|
|
494
|
-
process.stderr.write(`\nSaved project URL to ${(0, config_js_1.getConfigPath)()}.\n
|
|
448
|
+
(0, config_js_1.saveConfig)({ projectUrl: url, agentSecurityUrl: config_js_1.DEFAULT_AGENT_SECURITY_URL });
|
|
449
|
+
process.stderr.write(`\nSaved project URL to ${(0, config_js_1.getConfigPath)()}.\n`);
|
|
450
|
+
process.stderr.write("\n");
|
|
495
451
|
return url;
|
|
496
452
|
}
|
|
497
453
|
/**
|
|
@@ -510,21 +466,19 @@ async function interactiveConfigPrompt(binName) {
|
|
|
510
466
|
" Ory Agent Plugin — Configuration Required",
|
|
511
467
|
"--------------------------------------------",
|
|
512
468
|
"",
|
|
513
|
-
"
|
|
514
|
-
"
|
|
469
|
+
"Ory Agent Security is not connected, so no sign-in or permission checks run.",
|
|
470
|
+
"To turn them on, run this in another terminal:",
|
|
515
471
|
"",
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
"",
|
|
519
|
-
" Or, enable audit logging only (no auth or permission checks):",
|
|
520
|
-
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --audit-only`,
|
|
472
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL>`,
|
|
473
|
+
" (pass --agent-security-url to override the production broker)",
|
|
521
474
|
"",
|
|
522
475
|
`Config is saved to ${configPath}`,
|
|
523
476
|
"and shared across all agent plugins.",
|
|
524
477
|
"",
|
|
525
478
|
"You can also set environment variables (requires session restart):",
|
|
526
479
|
" export ORY_PROJECT_URL=https://your-project.projects.oryapis.com",
|
|
527
|
-
" export
|
|
480
|
+
" export ORY_AGENT_SECURITY_URL=https://agents.console.ory.com",
|
|
481
|
+
" export ORY_OAUTH2_CLIENT_ID=<public OAuth2 client id>",
|
|
528
482
|
"",
|
|
529
483
|
].join("\n");
|
|
530
484
|
process.stderr.write(message + "\n");
|
|
@@ -552,12 +506,12 @@ async function interactiveConfigPrompt(binName) {
|
|
|
552
506
|
}
|
|
553
507
|
// Re-read config from disk (env vars set in another shell won't be visible)
|
|
554
508
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
555
|
-
if (resolved.
|
|
556
|
-
process.stderr.write("\
|
|
509
|
+
if (resolved.security.connected) {
|
|
510
|
+
process.stderr.write("\nOry Agent Security is connected. Continuing session.\n\n");
|
|
557
511
|
return true;
|
|
558
512
|
}
|
|
559
|
-
process.stderr.write(
|
|
560
|
-
process.stderr.write("
|
|
513
|
+
process.stderr.write(`\nOry Agent Security is still not connected (${(0, config_js_1.describeSecurityGap)(resolved.security)}).\n`);
|
|
514
|
+
process.stderr.write("Continuing without sign-in or permission checks.\n\n");
|
|
561
515
|
return false;
|
|
562
516
|
}
|
|
563
517
|
/**
|
|
@@ -568,71 +522,149 @@ async function interactiveConfigPrompt(binName) {
|
|
|
568
522
|
* - `unregister` — best-effort RFC 7592 DELETE on the registered
|
|
569
523
|
* client, then clear the persisted block.
|
|
570
524
|
*
|
|
525
|
+
* Each installed harness owns its own agent identity, so both subcommands act
|
|
526
|
+
* on `harness`'s registration by default. `--all` widens them to every
|
|
527
|
+
* harness registered against the shared config.
|
|
528
|
+
*
|
|
571
529
|
* Returns the process exit code (0 on success, non-zero on usage error).
|
|
572
530
|
*/
|
|
573
|
-
async function runAgentCommand(binName, args) {
|
|
531
|
+
async function runAgentCommand(binName, harness, args) {
|
|
574
532
|
const sub = args[0];
|
|
575
533
|
if (!sub || sub === "--help" || sub === "-h") {
|
|
576
|
-
console.log(`Usage: ${binName} agent <subcommand
|
|
534
|
+
console.log(`Usage: ${binName} agent <subcommand> [--all]`);
|
|
577
535
|
console.log("");
|
|
578
536
|
console.log("Subcommands:");
|
|
579
|
-
console.log(" status Show the registered agent OAuth2
|
|
580
|
-
console.log(" unregister Delete the registered agent
|
|
537
|
+
console.log(" status Show the registered agent OAuth2 clients (one per session)");
|
|
538
|
+
console.log(" unregister Delete the registered agent clients and clear local state");
|
|
539
|
+
console.log("");
|
|
540
|
+
console.log("Options:");
|
|
541
|
+
console.log(` --all Act on every harness's agent client, not just ${harness}'s`);
|
|
581
542
|
return sub ? 0 : 1;
|
|
582
543
|
}
|
|
544
|
+
const all = args.includes("--all");
|
|
583
545
|
switch (sub) {
|
|
584
546
|
case "status":
|
|
585
|
-
runAgentStatus();
|
|
547
|
+
runAgentStatus(harness, all);
|
|
586
548
|
return 0;
|
|
587
549
|
case "unregister":
|
|
588
|
-
return await runAgentUnregister();
|
|
550
|
+
return await runAgentUnregister(harness, all);
|
|
589
551
|
default:
|
|
590
552
|
console.error(`Unknown agent subcommand: ${sub}`);
|
|
591
553
|
console.error(`Run "${binName} agent --help" for usage.`);
|
|
592
554
|
return 1;
|
|
593
555
|
}
|
|
594
556
|
}
|
|
595
|
-
|
|
596
|
-
|
|
557
|
+
/**
|
|
558
|
+
* The agent registrations a command should act on — one per harness install.
|
|
559
|
+
* `--all` widens to every harness. Sorted newest-registration first.
|
|
560
|
+
*/
|
|
561
|
+
function selectAgentRegistrations(harness, all) {
|
|
562
|
+
const byHarness = (0, agent_auth_js_1.loadAgentDynamicCredentialsByHarness)();
|
|
563
|
+
const entries = [];
|
|
564
|
+
for (const [key, bySession] of Object.entries(byHarness)) {
|
|
565
|
+
if (!all && key !== harness)
|
|
566
|
+
continue;
|
|
567
|
+
for (const [sessionKey, credentials] of Object.entries(bySession)) {
|
|
568
|
+
entries.push({ harness: key, sessionKey, credentials });
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
return entries.sort((a, b) => b.credentials.registeredAt - a.credentials.registeredAt ||
|
|
572
|
+
a.harness.localeCompare(b.harness));
|
|
573
|
+
}
|
|
574
|
+
function runAgentStatus(harness, all) {
|
|
575
|
+
const registrations = selectAgentRegistrations(harness, all);
|
|
597
576
|
console.log("Agent identity (Dynamic Client Registration)");
|
|
598
577
|
console.log("=============================================");
|
|
599
578
|
console.log("");
|
|
600
|
-
if (
|
|
601
|
-
console.log(
|
|
602
|
-
|
|
579
|
+
if (registrations.length === 0) {
|
|
580
|
+
console.log(all
|
|
581
|
+
? " No registered agent clients for any harness. Each install registers"
|
|
582
|
+
: ` No registered agent client for ${harness}. Each install registers`);
|
|
583
|
+
console.log(" one on its first session start, using the user's bearer (or");
|
|
603
584
|
console.log(" ORY_AGENT_REGISTRATION_TOKEN) as the initial access token.");
|
|
604
585
|
return;
|
|
605
586
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
console.log(`
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
587
|
+
for (const { harness: key, sessionKey, credentials: persisted } of registrations) {
|
|
588
|
+
console.log(` harness: ${key}`);
|
|
589
|
+
console.log(` session: ${sessionKey}`);
|
|
590
|
+
console.log(` client_id: ${persisted.clientId}`);
|
|
591
|
+
console.log(` client_secret: ${persisted.clientSecret ? "(set)" : "(not set — public client)"}`);
|
|
592
|
+
console.log(` registered_at: ${new Date(persisted.registeredAt * 1000).toISOString()}`);
|
|
593
|
+
console.log(` project_url: ${persisted.projectUrl}`);
|
|
594
|
+
if (persisted.registrationClientUri) {
|
|
595
|
+
console.log(` management_uri: ${persisted.registrationClientUri}`);
|
|
596
|
+
}
|
|
597
|
+
if (persisted.registrationAccessToken) {
|
|
598
|
+
console.log(` registration_token: (set — used to manage/delete this client)`);
|
|
599
|
+
}
|
|
600
|
+
console.log("");
|
|
617
601
|
}
|
|
618
602
|
}
|
|
619
|
-
async function runAgentUnregister() {
|
|
620
|
-
const
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
603
|
+
async function runAgentUnregister(harness, all) {
|
|
604
|
+
const targets = [];
|
|
605
|
+
const children = (0, agent_auth_js_1.loadSubAgentDynamicCredentialsByHarness)();
|
|
606
|
+
for (const [key, bySession] of Object.entries(children)) {
|
|
607
|
+
if (!all && key !== harness)
|
|
608
|
+
continue;
|
|
609
|
+
for (const [sessionKey, byType] of Object.entries(bySession)) {
|
|
610
|
+
for (const [type, credentials] of Object.entries(byType)) {
|
|
611
|
+
targets.push({
|
|
612
|
+
label: `${key}/${sessionKey}/${type}`,
|
|
613
|
+
credentials,
|
|
614
|
+
clear: () => (0, agent_auth_js_1.clearSubAgentDynamicCredentials)(key, sessionKey, type),
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
}
|
|
624
618
|
}
|
|
625
|
-
const
|
|
626
|
-
|
|
627
|
-
|
|
619
|
+
for (const { harness: key, sessionKey, credentials } of selectAgentRegistrations(harness, all)) {
|
|
620
|
+
targets.push({
|
|
621
|
+
label: `${key}/${sessionKey}`,
|
|
622
|
+
credentials,
|
|
623
|
+
clear: () => (0, agent_auth_js_1.clearAgentDynamicCredentials)(key, sessionKey),
|
|
624
|
+
});
|
|
628
625
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
626
|
+
for (const credentials of (0, agent_auth_js_1.loadRetiredCredentials)()) {
|
|
627
|
+
if (!all && credentials.harness !== harness)
|
|
628
|
+
continue;
|
|
629
|
+
targets.push({
|
|
630
|
+
label: `${credentials.harness ?? "unknown"}/retired`,
|
|
631
|
+
credentials,
|
|
632
|
+
clear: () => undefined,
|
|
633
|
+
retired: true,
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
if (targets.length === 0) {
|
|
637
|
+
console.log(all
|
|
638
|
+
? "No registered agent clients to unregister. Nothing to do."
|
|
639
|
+
: `No registered agent client for ${harness} to unregister. Nothing to do.`);
|
|
640
|
+
return 0;
|
|
641
|
+
}
|
|
642
|
+
const retiredIds = [];
|
|
643
|
+
const seen = new Set();
|
|
644
|
+
for (const target of targets) {
|
|
645
|
+
const { label, credentials: persisted } = target;
|
|
646
|
+
if (seen.has(persisted.clientId)) {
|
|
647
|
+
target.clear();
|
|
648
|
+
if (target.retired)
|
|
649
|
+
retiredIds.push(persisted.clientId);
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
seen.add(persisted.clientId);
|
|
653
|
+
const outcome = await (0, agent_auth_js_1.revokeAgentDynamicClient)(persisted);
|
|
654
|
+
if (outcome.status === "skipped") {
|
|
655
|
+
console.warn(`Warning: no registration_access_token was persisted for ${label}, so we cannot DELETE the server-side client. Clearing local state only.`);
|
|
656
|
+
}
|
|
657
|
+
else if (outcome.status === "failed") {
|
|
658
|
+
const detail = typeof outcome.httpStatus === "number"
|
|
659
|
+
? `returned HTTP ${outcome.httpStatus}`
|
|
660
|
+
: `failed (${outcome.message})`;
|
|
661
|
+
console.warn(`Warning: server-side DELETE for ${label} ${detail}. Local state will be cleared anyway.`);
|
|
662
|
+
}
|
|
663
|
+
target.clear();
|
|
664
|
+
if (target.retired)
|
|
665
|
+
retiredIds.push(persisted.clientId);
|
|
666
|
+
console.log(`Unregistered agent client ${persisted.clientId} (${label}).`);
|
|
634
667
|
}
|
|
635
|
-
(0, agent_auth_js_1.
|
|
636
|
-
console.log(`Unregistered agent client ${persisted.clientId}.`);
|
|
668
|
+
(0, agent_auth_js_1.clearRetiredCredentials)(retiredIds);
|
|
637
669
|
return 0;
|
|
638
670
|
}
|