@ory/argus 0.13.9 → 1.0.0
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 -45
- 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 +43 -97
- package/assets/skills/ory-e2b-sandbox/SKILL.md +18 -18
- package/assets/skills/ory-temporal-worker/SKILL.md +38 -42
- package/assets/skills/permissions-onboarding/SKILL.md +131 -104
- package/dist/adapters.d.ts +93 -30
- package/dist/adapters.js +464 -136
- package/dist/agent-auth.d.ts +258 -68
- package/dist/agent-auth.js +998 -202
- package/dist/auth-store.d.ts +37 -2
- package/dist/auth-store.js +37 -3
- package/dist/auth.d.ts +40 -4
- package/dist/auth.js +247 -19
- package/dist/bash-parser.d.ts +98 -0
- package/dist/bash-parser.js +396 -0
- package/dist/branding.d.ts +128 -0
- package/dist/branding.js +151 -0
- 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 -278
- package/dist/client.d.ts +175 -138
- package/dist/client.js +672 -391
- package/dist/config.d.ts +249 -57
- package/dist/config.js +486 -62
- package/dist/context.d.ts +10 -0
- package/dist/context.js +21 -0
- package/dist/contract-suite.d.ts +8 -8
- package/dist/contract-suite.js +88 -69
- 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 +31 -19
- package/dist/index.js +182 -31
- 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.d.ts +14 -0
- package/dist/local/health.js +50 -4
- 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 +160 -39
- package/dist/local/ports.d.ts +158 -0
- package/dist/local/ports.js +443 -0
- package/dist/local/seed.d.ts +22 -25
- package/dist/local/seed.js +88 -56
- 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 +83 -55
- package/dist/runtime-credential.d.ts +140 -0
- package/dist/runtime-credential.js +572 -0
- package/dist/runtime.d.ts +408 -0
- package/dist/runtime.js +748 -0
- package/dist/setup.d.ts +23 -28
- package/dist/setup.js +57 -84
- package/dist/status-cli.d.ts +29 -13
- package/dist/status-cli.js +124 -144
- package/dist/status-data.d.ts +195 -0
- package/dist/status-data.js +333 -0
- package/dist/status-system.d.ts +24 -0
- package/dist/status-system.js +56 -0
- 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 +74 -19
- package/dist/uninstall.js +224 -49
- package/dist/user-login.d.ts +22 -16
- package/dist/user-login.js +67 -96
- package/dist/watch-cli.d.ts +6 -0
- package/dist/watch-cli.js +217 -0
- package/package.json +3 -11
- package/dist/dev.d.ts +0 -103
- package/dist/dev.js +0 -584
- package/dist/interactive-setup.d.ts +0 -165
- package/dist/interactive-setup.js +0 -1546
- 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/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/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,34 +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
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
// `undefined` = not specified; a string sets it; empty string ("") clears it
|
|
79
|
-
// (via --no-user-subject-namespace) to fall back to direct SubjectID.
|
|
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.
|
|
80
78
|
let userSubjectNamespace;
|
|
81
79
|
for (let i = 0; i < args.length; i++) {
|
|
82
80
|
switch (args[i]) {
|
|
@@ -89,20 +87,14 @@ function runConfigureCommand(binName, args) {
|
|
|
89
87
|
case "--project-id":
|
|
90
88
|
projectId = args[++i];
|
|
91
89
|
break;
|
|
92
|
-
case "--
|
|
93
|
-
|
|
90
|
+
case "--agent-security-url":
|
|
91
|
+
agentSecurityUrl = args[++i];
|
|
94
92
|
break;
|
|
95
93
|
case "--oauth2-client-id":
|
|
96
94
|
oauth2ClientId = args[++i];
|
|
97
95
|
break;
|
|
98
|
-
case "--
|
|
99
|
-
|
|
100
|
-
break;
|
|
101
|
-
case "--user-login":
|
|
102
|
-
userLogin = true;
|
|
103
|
-
break;
|
|
104
|
-
case "--no-user-login":
|
|
105
|
-
userLogin = false;
|
|
96
|
+
case "--disconnect":
|
|
97
|
+
disconnect = true;
|
|
106
98
|
break;
|
|
107
99
|
case "--user-subject-namespace":
|
|
108
100
|
userSubjectNamespace = args[++i];
|
|
@@ -113,176 +105,175 @@ function runConfigureCommand(binName, args) {
|
|
|
113
105
|
}
|
|
114
106
|
}
|
|
115
107
|
if (!projectUrl &&
|
|
108
|
+
!agentSecurityUrl &&
|
|
116
109
|
!projectId &&
|
|
117
|
-
!apiKey &&
|
|
118
110
|
!oauth2ClientId &&
|
|
119
|
-
!
|
|
120
|
-
userLogin === undefined &&
|
|
111
|
+
!disconnect &&
|
|
121
112
|
userSubjectNamespace === undefined) {
|
|
122
113
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
123
114
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
124
115
|
console.log("Ory Plugin Configuration");
|
|
125
116
|
console.log("========================");
|
|
126
117
|
console.log("");
|
|
127
|
-
console.log(`Config file: ${configPath}`);
|
|
118
|
+
console.log(`Config file: ${configPath}${fs.existsSync(configPath) ? "" : " (not created yet)"}`);
|
|
128
119
|
console.log(`Project URL: ${resolved.projectUrl ?? "(not set)"} [${resolved.projectUrlSource}]`);
|
|
129
|
-
console.log(`
|
|
130
|
-
console.log(`API Key: ${resolved.apiKey ? "(set)" : "(not set)"} [${resolved.apiKeySource}]`);
|
|
120
|
+
console.log(`Agent Security URL: ${resolved.agentSecurityUrl ?? "(not set)"} [${resolved.agentSecurityUrlSource}]`);
|
|
131
121
|
console.log(`OAuth2 Client ID: ${resolved.oauth2ClientId ?? "(not set)"} [${resolved.oauth2ClientIdSource}]`);
|
|
132
|
-
console.log(`
|
|
133
|
-
console.log(`User Login: ${resolved.userLogin ? "on" : "off"} [${resolved.userLoginSource}]`);
|
|
134
|
-
console.log(`User subject ns: ${resolved.userSubjectNamespace ?? "(direct subject id)"} [${resolved.userSubjectNamespaceSource}]`);
|
|
135
|
-
console.log("");
|
|
136
|
-
console.log("To configure:");
|
|
137
|
-
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL> --oauth2-client-id <CLIENT_ID> [--api-key <KEY>]`);
|
|
122
|
+
console.log(`Agent Security: ${resolved.security.connected ? "connected" : `not connected (${(0, config_js_1.describeSecurityGap)(resolved.security)})`}`);
|
|
138
123
|
console.log("");
|
|
139
|
-
console.log(
|
|
140
|
-
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}]`);
|
|
141
126
|
console.log("");
|
|
142
|
-
|
|
143
|
-
|
|
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
|
+
}
|
|
144
142
|
console.log("");
|
|
145
|
-
console.log("
|
|
146
|
-
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)`);
|
|
147
145
|
console.log("");
|
|
148
146
|
console.log("Or set environment variables:");
|
|
149
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");
|
|
150
149
|
console.log(" # ORY_SDK_URL (the Ory Console 'Get Started' name) is accepted as an alias.");
|
|
151
150
|
console.log(" # ORY_PROJECT_ID=<project uuid> is stored for admin operations (not an SDK URL).");
|
|
152
|
-
console.log(
|
|
153
|
-
console.log(" export ORY_AGENT_API_KEY=ory_pat_...");
|
|
154
|
-
console.log(" export ORY_USER_LOGIN=true");
|
|
151
|
+
console.log(` # ORY_OAUTH2_CLIENT_ID defaults to ${config_js_1.DEFAULT_OAUTH2_CLIENT_ID}.`);
|
|
155
152
|
return;
|
|
156
153
|
}
|
|
157
|
-
if (
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
(0, config_js_1.saveConfig)({ auditOnly: true, ...(userLogin !== undefined ? { userLogin } : {}) });
|
|
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 });
|
|
162
158
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
163
159
|
console.log(`Configuration saved to ${configPath}`);
|
|
164
|
-
console.log("
|
|
165
|
-
if (userLogin !== undefined) {
|
|
166
|
-
console.log(` User login: ${userLogin ? "on" : "off"} (takes effect when audit-only is disabled)`);
|
|
167
|
-
}
|
|
160
|
+
console.log(" Ory Agent Security: disconnected (no sign-in, no permission checks)");
|
|
168
161
|
console.log("");
|
|
169
|
-
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
|
+
}
|
|
170
171
|
return;
|
|
171
172
|
}
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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" +
|
|
183
202
|
"\n" +
|
|
184
|
-
"
|
|
185
|
-
|
|
186
|
-
"token_endpoint_auth_method=none) registered in your Ory project with all four\n" +
|
|
187
|
-
"loopback redirect URIs:\n" +
|
|
188
|
-
" http://127.0.0.1:47823/callback\n" +
|
|
189
|
-
" http://127.0.0.1:47824/callback\n" +
|
|
190
|
-
" http://127.0.0.1:47825/callback\n" +
|
|
191
|
-
" http://127.0.0.1:47826/callback\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` +
|
|
192
205
|
"\n" +
|
|
193
|
-
"
|
|
194
|
-
" ory create oauth2-client --project <project-id> \\\n" +
|
|
195
|
-
" --name \"ory-agent-plugin\" \\\n" +
|
|
196
|
-
" --grant-type authorization_code,refresh_token \\\n" +
|
|
197
|
-
" --response-type code \\\n" +
|
|
198
|
-
" --scope openid,offline_access \\\n" +
|
|
199
|
-
" --token-endpoint-auth-method none \\\n" +
|
|
200
|
-
" --redirect-uri http://127.0.0.1:47823/callback \\\n" +
|
|
201
|
-
" --redirect-uri http://127.0.0.1:47824/callback \\\n" +
|
|
202
|
-
" --redirect-uri http://127.0.0.1:47825/callback \\\n" +
|
|
203
|
-
" --redirect-uri http://127.0.0.1:47826/callback\n" +
|
|
206
|
+
"(--agent-security-url and --oauth2-client-id override their production defaults.)\n" +
|
|
204
207
|
"\n" +
|
|
205
|
-
"
|
|
206
|
-
|
|
208
|
+
"Connecting needs no workspace privilege. The plugin never provisions the project itself.\n" +
|
|
209
|
+
"\n" +
|
|
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.");
|
|
207
212
|
process.exit(1);
|
|
208
213
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
// to complete the PKCE flow. Warn (don't block) if either is missing —
|
|
212
|
-
// the operator may supply them separately or via env before running.
|
|
213
|
-
if (userLogin === true) {
|
|
214
|
-
// resolveConfig() already folds in the ORY_SDK_URL alias and the config
|
|
215
|
-
// file; OR in the URL being set on this same invocation.
|
|
216
|
-
const nextProjectUrl = projectUrl ?? (0, config_js_1.resolveConfig)().projectUrl;
|
|
217
|
-
const nextClientId = oauth2ClientId ?? process.env.ORY_OAUTH2_CLIENT_ID ?? (0, config_js_1.loadConfig)().oauth2ClientId;
|
|
218
|
-
if (!nextProjectUrl || !nextClientId) {
|
|
219
|
-
const missing = [
|
|
220
|
-
!nextProjectUrl ? "a project URL (--project-url / --sdk-url / ORY_PROJECT_URL)" : null,
|
|
221
|
-
!nextClientId ? "an OAuth2 client id (--oauth2-client-id / ORY_OAUTH2_CLIENT_ID)" : null,
|
|
222
|
-
].filter(Boolean);
|
|
223
|
-
console.warn(`Warning: user login is enabled but still missing ${missing.join(" and ")}.\n` +
|
|
224
|
-
"The PKCE browser flow can't complete until both are configured.");
|
|
214
|
+
if (projectUrl && !agentSecurityUrl && !process.env.ORY_AGENT_SECURITY_URL?.trim() && !persisted.agentSecurityUrl) {
|
|
215
|
+
agentSecurityUrl = config_js_1.DEFAULT_AGENT_SECURITY_URL;
|
|
225
216
|
}
|
|
226
217
|
}
|
|
227
218
|
const update = {};
|
|
228
219
|
if (projectUrl)
|
|
229
220
|
update.projectUrl = projectUrl;
|
|
221
|
+
if (agentSecurityUrl)
|
|
222
|
+
update.agentSecurityUrl = agentSecurityUrl;
|
|
230
223
|
if (projectId)
|
|
231
224
|
update.projectId = projectId;
|
|
232
|
-
if (apiKey)
|
|
233
|
-
update.apiKey = apiKey;
|
|
234
225
|
if (oauth2ClientId)
|
|
235
226
|
update.oauth2ClientId = oauth2ClientId;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
//
|
|
239
|
-
// (from --no-user-subject-namespace) clears it (null ⇒ delete the key).
|
|
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.
|
|
240
230
|
if (userSubjectNamespace !== undefined) {
|
|
241
231
|
update.userSubjectNamespace = userSubjectNamespace === "" ? null : userSubjectNamespace;
|
|
242
232
|
}
|
|
243
|
-
// Configuring an actual connection (a slug-based URL, api key, or client id)
|
|
244
|
-
// implies leaving audit-only mode. A bare project id is only an admin
|
|
245
|
-
// identifier — it doesn't connect anything on its own — so it doesn't flip
|
|
246
|
-
// the flag; nor does a standalone user-login toggle.
|
|
247
|
-
if (projectUrl || apiKey || oauth2ClientId)
|
|
248
|
-
update.auditOnly = false;
|
|
249
233
|
(0, config_js_1.saveConfig)(update);
|
|
250
234
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
251
235
|
console.log(`Configuration saved to ${configPath}`);
|
|
252
236
|
if (projectUrl)
|
|
253
237
|
console.log(` Project URL: ${projectUrl}`);
|
|
238
|
+
if (agentSecurityUrl)
|
|
239
|
+
console.log(` Agent Security URL: ${agentSecurityUrl}`);
|
|
254
240
|
if (projectId)
|
|
255
241
|
console.log(` Project ID: ${projectId}`);
|
|
256
|
-
if (apiKey)
|
|
257
|
-
console.log(` API Key: (set)`);
|
|
258
242
|
if (oauth2ClientId)
|
|
259
243
|
console.log(` OAuth2 Client ID: ${oauth2ClientId}`);
|
|
260
|
-
if (userLogin !== undefined)
|
|
261
|
-
console.log(` User Login: ${userLogin ? "on" : "off"}`);
|
|
262
244
|
if (userSubjectNamespace !== undefined)
|
|
263
|
-
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)})`}`);
|
|
264
250
|
console.log("");
|
|
265
251
|
console.log("This configuration is shared across all Ory agent plugins.");
|
|
266
|
-
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.");
|
|
267
253
|
}
|
|
268
254
|
/**
|
|
269
|
-
* Print the "Configuration:" block showing
|
|
255
|
+
* Print the "Configuration:" block showing the resolved Ory connection.
|
|
270
256
|
*/
|
|
271
257
|
function printOryConfig() {
|
|
272
258
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
273
259
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
274
|
-
const namespace = process.env.ORY_PERMISSION_NAMESPACE || "
|
|
260
|
+
const namespace = process.env.ORY_PERMISSION_NAMESPACE || "AgentTool";
|
|
275
261
|
console.log("Configuration:");
|
|
276
262
|
console.log(` Config file: ${configPath}`);
|
|
277
|
-
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)`}`);
|
|
278
266
|
console.log(` Project URL: ${resolved.projectUrl ?? "NOT SET"} [source: ${resolved.projectUrlSource}]`);
|
|
279
|
-
console.log(`
|
|
280
|
-
console.log(` API Key: ${resolved.apiKey ? "(set)" : "NOT SET"} [source: ${resolved.apiKeySource}]`);
|
|
267
|
+
console.log(` Agent Security: ${resolved.agentSecurityUrl ?? "NOT SET"} [source: ${resolved.agentSecurityUrlSource}]`);
|
|
281
268
|
console.log(` OAuth2 Client: ${resolved.oauth2ClientId ?? "NOT SET"} [source: ${resolved.oauth2ClientIdSource}]`);
|
|
282
|
-
console.log(`
|
|
283
|
-
|
|
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
|
+
}
|
|
284
275
|
console.log(` Namespace: ${namespace}`);
|
|
285
|
-
console.log(` User subject ns: ${resolved.userSubjectNamespace ?? "(
|
|
276
|
+
console.log(` User subject ns: ${resolved.userSubjectNamespace ?? "User (default)"} [source: ${resolved.userSubjectNamespaceSource}]`);
|
|
286
277
|
}
|
|
287
278
|
/**
|
|
288
279
|
* Print the "Environment:" block showing Ory-related environment variables.
|
|
@@ -293,33 +284,20 @@ function printEnvironment() {
|
|
|
293
284
|
const vars = [
|
|
294
285
|
["ORY_PROJECT_URL", process.env.ORY_PROJECT_URL, false],
|
|
295
286
|
["ORY_SDK_URL", process.env.ORY_SDK_URL, false],
|
|
287
|
+
["ORY_AGENT_SECURITY_URL", process.env.ORY_AGENT_SECURITY_URL, false],
|
|
296
288
|
["ORY_PROJECT_ID", process.env.ORY_PROJECT_ID, false],
|
|
297
|
-
["ORY_USER_LOGIN", process.env.ORY_USER_LOGIN, false],
|
|
298
|
-
[
|
|
299
|
-
"ORY_AGENT_API_KEY",
|
|
300
|
-
process.env.ORY_AGENT_API_KEY ? "(set)" : undefined,
|
|
301
|
-
false,
|
|
302
|
-
],
|
|
303
289
|
["ORY_AGENT_CLIENT_ID", process.env.ORY_AGENT_CLIENT_ID, false],
|
|
304
290
|
["ORY_OAUTH2_CLIENT_ID", process.env.ORY_OAUTH2_CLIENT_ID, false],
|
|
305
291
|
[
|
|
306
|
-
"
|
|
307
|
-
process.env.
|
|
292
|
+
"ORY_USER_OAUTH2_TOKEN",
|
|
293
|
+
process.env.ORY_USER_OAUTH2_TOKEN ? "(set)" : undefined,
|
|
308
294
|
false,
|
|
309
295
|
],
|
|
310
296
|
["ORY_USER_SUBJECT_ID", process.env.ORY_USER_SUBJECT_ID, false],
|
|
311
297
|
["ORY_AGENT_SUBJECT_ID", process.env.ORY_AGENT_SUBJECT_ID, false],
|
|
312
298
|
["ORY_AGENT_DEBUG", process.env.ORY_AGENT_DEBUG, false],
|
|
313
299
|
["ORY_AGENT_LOG_FILE", process.env.ORY_AGENT_LOG_FILE, false],
|
|
314
|
-
["ORY_AGENT_TRACE_FILE", process.env.ORY_AGENT_TRACE_FILE, false],
|
|
315
300
|
];
|
|
316
|
-
if (process.env.ORY_API_KEY && !process.env.ORY_AGENT_API_KEY) {
|
|
317
|
-
vars.splice(2, 0, [
|
|
318
|
-
"ORY_API_KEY",
|
|
319
|
-
"(set, DEPRECATED — use ORY_AGENT_API_KEY)",
|
|
320
|
-
false,
|
|
321
|
-
]);
|
|
322
|
-
}
|
|
323
301
|
for (const [name, value, required] of vars) {
|
|
324
302
|
const display = value
|
|
325
303
|
? value
|
|
@@ -331,12 +309,11 @@ function printEnvironment() {
|
|
|
331
309
|
}
|
|
332
310
|
}
|
|
333
311
|
/**
|
|
334
|
-
* Print the last
|
|
312
|
+
* Print the last 10 unified activity/debug log entries. When `harness` is given the path is
|
|
335
313
|
* resolved the same way the plugin does at runtime — the default per-harness
|
|
336
314
|
* data-dir location when `ORY_AGENT_LOG_FILE` is unset — so `status` finds the
|
|
337
|
-
* log without the reader hand-setting env vars.
|
|
338
|
-
*
|
|
339
|
-
* 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`.
|
|
340
317
|
*/
|
|
341
318
|
function printLogTail(harness) {
|
|
342
319
|
const logFile = harness
|
|
@@ -345,12 +322,11 @@ function printLogTail(harness) {
|
|
|
345
322
|
if (logFile && fs.existsSync(logFile)) {
|
|
346
323
|
const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n");
|
|
347
324
|
console.log("");
|
|
348
|
-
console.log(`
|
|
349
|
-
console.log("Last
|
|
350
|
-
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)) {
|
|
351
328
|
try {
|
|
352
|
-
|
|
353
|
-
console.log(` ${entry.timestamp} [${entry.level}] ${entry.event}`);
|
|
329
|
+
console.log(" " + (0, logger_js_1.formatLogEntry)(JSON.parse(line)));
|
|
354
330
|
}
|
|
355
331
|
catch {
|
|
356
332
|
console.log(` ${line.slice(0, 120)}`);
|
|
@@ -360,8 +336,8 @@ function printLogTail(harness) {
|
|
|
360
336
|
else if (harness) {
|
|
361
337
|
console.log("");
|
|
362
338
|
console.log(logFile
|
|
363
|
-
? `
|
|
364
|
-
: "
|
|
339
|
+
? `Activity log: none yet — events land in ${logFile} once a session runs`
|
|
340
|
+
: "Activity log: disabled (ORY_AGENT_LOG_FILE set empty)");
|
|
365
341
|
}
|
|
366
342
|
}
|
|
367
343
|
/**
|
|
@@ -373,79 +349,19 @@ function printEnvHelp(binName) {
|
|
|
373
349
|
console.log("");
|
|
374
350
|
console.log(" Option 1 — Save to config file (persists across sessions):");
|
|
375
351
|
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url https://your-project.projects.oryapis.com \\`);
|
|
376
|
-
console.log(" --
|
|
377
|
-
console.log(" --
|
|
352
|
+
console.log(" --agent-security-url https://agents.console.ory.com \\");
|
|
353
|
+
console.log(" --oauth2-client-id <public OAuth2 client id>");
|
|
378
354
|
console.log("");
|
|
379
355
|
console.log(" Option 2 — Set environment variables:");
|
|
380
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");
|
|
381
358
|
console.log(" export ORY_OAUTH2_CLIENT_ID=<public OAuth2 client id>");
|
|
382
|
-
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.");
|
|
383
362
|
console.log("");
|
|
384
363
|
console.log("If neither is set when a session starts, the agent will prompt for configuration.");
|
|
385
364
|
}
|
|
386
|
-
/**
|
|
387
|
-
* Print the last 5 trace spans. When `harness` is given the path is resolved
|
|
388
|
-
* the same way the plugin does at runtime — the default per-harness data-dir
|
|
389
|
-
* location when `ORY_AGENT_TRACE_FILE` is unset — so `status` shows recent
|
|
390
|
-
* activity out of the box (traces are written on every recorded span). When no
|
|
391
|
-
* spans have been recorded yet, prints a one-line pointer at the trace file so
|
|
392
|
-
* the reader knows where to look (and how to watch it live).
|
|
393
|
-
*/
|
|
394
|
-
function printTraceTail(harness) {
|
|
395
|
-
const traceFile = harness
|
|
396
|
-
? (0, client_js_1.resolveTraceFilePath)(harness)
|
|
397
|
-
: process.env.ORY_AGENT_TRACE_FILE;
|
|
398
|
-
if (traceFile && fs.existsSync(traceFile)) {
|
|
399
|
-
const lines = fs.readFileSync(traceFile, "utf-8").trim().split("\n");
|
|
400
|
-
console.log("");
|
|
401
|
-
console.log(`Trace file: ${traceFile} (${lines.length} spans)`);
|
|
402
|
-
console.log("Last 5 spans:");
|
|
403
|
-
for (const line of lines.slice(-5)) {
|
|
404
|
-
try {
|
|
405
|
-
const span = JSON.parse(line);
|
|
406
|
-
console.log(" " + (0, tracer_js_1.formatSpan)(span));
|
|
407
|
-
}
|
|
408
|
-
catch {
|
|
409
|
-
console.log(` ${line.slice(0, 120)}`);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
else if (harness) {
|
|
414
|
-
console.log("");
|
|
415
|
-
console.log(traceFile
|
|
416
|
-
? `Trace file: none yet — spans land in ${traceFile} once a session runs a tool`
|
|
417
|
-
: "Trace file: disabled (ORY_AGENT_TRACE_FILE set empty)");
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Run the live trace watcher. Tails the NDJSON trace file and prints
|
|
422
|
-
* formatted spans to stdout as they arrive. Blocks until interrupted.
|
|
423
|
-
*/
|
|
424
|
-
function runWatchCommand(harness, args) {
|
|
425
|
-
// Precedence: explicit arg → resolved default (honors ORY_AGENT_TRACE_FILE,
|
|
426
|
-
// falling back to the per-harness data-dir path). The resolver returns
|
|
427
|
-
// undefined only when tracing is explicitly disabled (ORY_AGENT_TRACE_FILE
|
|
428
|
-
// set empty), so that's the one case that dead-ends here.
|
|
429
|
-
const traceFile = args[0] || (0, client_js_1.resolveTraceFilePath)(harness);
|
|
430
|
-
if (!traceFile) {
|
|
431
|
-
console.error("Trace file is disabled (ORY_AGENT_TRACE_FILE is set empty).\n" +
|
|
432
|
-
"Unset it, or pass a path: watch <trace-file>\n");
|
|
433
|
-
process.exit(1);
|
|
434
|
-
}
|
|
435
|
-
console.log(`Watching traces: ${traceFile}`);
|
|
436
|
-
if (!fs.existsSync(traceFile)) {
|
|
437
|
-
console.log("(file doesn't exist yet — waiting for the first span…)");
|
|
438
|
-
}
|
|
439
|
-
console.log("Press Ctrl+C to stop.\n");
|
|
440
|
-
const stop = (0, tracer_js_1.watchTraceFile)(traceFile, (span) => {
|
|
441
|
-
console.log((0, tracer_js_1.formatSpan)(span));
|
|
442
|
-
});
|
|
443
|
-
process.on("SIGINT", () => {
|
|
444
|
-
stop();
|
|
445
|
-
console.log("\nStopped watching.");
|
|
446
|
-
process.exit(0);
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
365
|
/**
|
|
450
366
|
* Returns true if `/dev/tty` can be opened for reading. Use this before
|
|
451
367
|
* attempting to prompt the user — the harness has already taken stdin so
|
|
@@ -529,8 +445,9 @@ async function promptForProjectUrl(binName) {
|
|
|
529
445
|
process.stderr.write(`\nIgnoring invalid project URL "${answer}".\n\n`);
|
|
530
446
|
return null;
|
|
531
447
|
}
|
|
532
|
-
(0, config_js_1.saveConfig)({ projectUrl: url,
|
|
533
|
-
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");
|
|
534
451
|
return url;
|
|
535
452
|
}
|
|
536
453
|
/**
|
|
@@ -549,21 +466,19 @@ async function interactiveConfigPrompt(binName) {
|
|
|
549
466
|
" Ory Agent Plugin — Configuration Required",
|
|
550
467
|
"--------------------------------------------",
|
|
551
468
|
"",
|
|
552
|
-
"
|
|
553
|
-
"
|
|
554
|
-
"",
|
|
555
|
-
" Connect to Ory (enables auth & permission checks):",
|
|
556
|
-
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL> --oauth2-client-id <CLIENT_ID> [--api-key <KEY>]`,
|
|
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:",
|
|
557
471
|
"",
|
|
558
|
-
|
|
559
|
-
|
|
472
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL>`,
|
|
473
|
+
" (pass --agent-security-url to override the production broker)",
|
|
560
474
|
"",
|
|
561
475
|
`Config is saved to ${configPath}`,
|
|
562
476
|
"and shared across all agent plugins.",
|
|
563
477
|
"",
|
|
564
478
|
"You can also set environment variables (requires session restart):",
|
|
565
479
|
" export ORY_PROJECT_URL=https://your-project.projects.oryapis.com",
|
|
566
|
-
" export
|
|
480
|
+
" export ORY_AGENT_SECURITY_URL=https://agents.console.ory.com",
|
|
481
|
+
" export ORY_OAUTH2_CLIENT_ID=<public OAuth2 client id>",
|
|
567
482
|
"",
|
|
568
483
|
].join("\n");
|
|
569
484
|
process.stderr.write(message + "\n");
|
|
@@ -591,12 +506,12 @@ async function interactiveConfigPrompt(binName) {
|
|
|
591
506
|
}
|
|
592
507
|
// Re-read config from disk (env vars set in another shell won't be visible)
|
|
593
508
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
594
|
-
if (resolved.
|
|
595
|
-
process.stderr.write("\
|
|
509
|
+
if (resolved.security.connected) {
|
|
510
|
+
process.stderr.write("\nOry Agent Security is connected. Continuing session.\n\n");
|
|
596
511
|
return true;
|
|
597
512
|
}
|
|
598
|
-
process.stderr.write(
|
|
599
|
-
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");
|
|
600
515
|
return false;
|
|
601
516
|
}
|
|
602
517
|
/**
|
|
@@ -607,71 +522,149 @@ async function interactiveConfigPrompt(binName) {
|
|
|
607
522
|
* - `unregister` — best-effort RFC 7592 DELETE on the registered
|
|
608
523
|
* client, then clear the persisted block.
|
|
609
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
|
+
*
|
|
610
529
|
* Returns the process exit code (0 on success, non-zero on usage error).
|
|
611
530
|
*/
|
|
612
|
-
async function runAgentCommand(binName, args) {
|
|
531
|
+
async function runAgentCommand(binName, harness, args) {
|
|
613
532
|
const sub = args[0];
|
|
614
533
|
if (!sub || sub === "--help" || sub === "-h") {
|
|
615
|
-
console.log(`Usage: ${binName} agent <subcommand
|
|
534
|
+
console.log(`Usage: ${binName} agent <subcommand> [--all]`);
|
|
616
535
|
console.log("");
|
|
617
536
|
console.log("Subcommands:");
|
|
618
|
-
console.log(" status Show the registered agent OAuth2
|
|
619
|
-
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`);
|
|
620
542
|
return sub ? 0 : 1;
|
|
621
543
|
}
|
|
544
|
+
const all = args.includes("--all");
|
|
622
545
|
switch (sub) {
|
|
623
546
|
case "status":
|
|
624
|
-
runAgentStatus();
|
|
547
|
+
runAgentStatus(harness, all);
|
|
625
548
|
return 0;
|
|
626
549
|
case "unregister":
|
|
627
|
-
return await runAgentUnregister();
|
|
550
|
+
return await runAgentUnregister(harness, all);
|
|
628
551
|
default:
|
|
629
552
|
console.error(`Unknown agent subcommand: ${sub}`);
|
|
630
553
|
console.error(`Run "${binName} agent --help" for usage.`);
|
|
631
554
|
return 1;
|
|
632
555
|
}
|
|
633
556
|
}
|
|
634
|
-
|
|
635
|
-
|
|
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);
|
|
636
576
|
console.log("Agent identity (Dynamic Client Registration)");
|
|
637
577
|
console.log("=============================================");
|
|
638
578
|
console.log("");
|
|
639
|
-
if (
|
|
640
|
-
console.log(
|
|
641
|
-
|
|
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");
|
|
642
584
|
console.log(" ORY_AGENT_REGISTRATION_TOKEN) as the initial access token.");
|
|
643
585
|
return;
|
|
644
586
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
console.log(`
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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("");
|
|
656
601
|
}
|
|
657
602
|
}
|
|
658
|
-
async function runAgentUnregister() {
|
|
659
|
-
const
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
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
|
+
}
|
|
663
618
|
}
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
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
|
+
});
|
|
625
|
+
}
|
|
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;
|
|
667
641
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
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}).`);
|
|
673
667
|
}
|
|
674
|
-
(0, agent_auth_js_1.
|
|
675
|
-
console.log(`Unregistered agent client ${persisted.clientId}.`);
|
|
668
|
+
(0, agent_auth_js_1.clearRetiredCredentials)(retiredIds);
|
|
676
669
|
return 0;
|
|
677
670
|
}
|