@ory/argus 1.2.0 → 1.2.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/dist/branding.d.ts +3 -3
- package/dist/branding.js +7 -7
- package/dist/build-info.json +4 -4
- package/dist/cli.d.ts +3 -5
- package/dist/cli.js +31 -30
- package/dist/config.d.ts +1 -1
- package/dist/status-cli.d.ts +8 -10
- package/dist/status-cli.js +31 -73
- package/dist/status-data.d.ts +27 -37
- package/dist/status-data.js +43 -75
- package/package.json +1 -1
package/dist/branding.d.ts
CHANGED
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
* name carrying *who* and *where*, so a shared project's resource list stays
|
|
20
20
|
* legible and prunable: {@link agentClientName}, {@link projectApiKeyName}.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* Display names stay short because the Console already provides the resource
|
|
23
|
+
* type and project context around them.
|
|
24
24
|
*/
|
|
25
25
|
/** Human-readable umbrella name for everything this product creates. */
|
|
26
26
|
export declare const PRODUCT_NAME = "Ory Agent Security";
|
|
@@ -58,7 +58,7 @@ export declare const USER_LOGIN_CLIENT_ID = "ory-agent-security-login";
|
|
|
58
58
|
* installs onto one client, and {@link isUserLoginClient} is the only accepted
|
|
59
59
|
* test for "is this the login client".
|
|
60
60
|
*/
|
|
61
|
-
export declare const USER_LOGIN_CLIENT_NAME = "
|
|
61
|
+
export declare const USER_LOGIN_CLIENT_NAME = "Agent Security login";
|
|
62
62
|
/**
|
|
63
63
|
* Whether a client is *the* shared user-login client, decided **only** by its
|
|
64
64
|
* id. A client carrying {@link USER_LOGIN_CLIENT_NAME} under any other id is
|
package/dist/branding.js
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* name carrying *who* and *where*, so a shared project's resource list stays
|
|
21
21
|
* legible and prunable: {@link agentClientName}, {@link projectApiKeyName}.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* Display names stay short because the Console already provides the resource
|
|
24
|
+
* type and project context around them.
|
|
25
25
|
*/
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
27
|
exports.PERMISSION_NAMESPACE = exports.DEFAULT_PROJECT_NAME = exports.USER_LOGIN_SCOPE_CLI = exports.USER_LOGIN_SCOPE_OAUTH = exports.USER_LOGIN_SCOPES = exports.USER_LOGIN_BASE_SCOPES = exports.USER_LOGIN_CLIENT_NAME = exports.USER_LOGIN_CLIENT_ID = exports.PRODUCT_NAME = void 0;
|
|
@@ -65,7 +65,7 @@ exports.USER_LOGIN_CLIENT_ID = "ory-agent-security-login";
|
|
|
65
65
|
* installs onto one client, and {@link isUserLoginClient} is the only accepted
|
|
66
66
|
* test for "is this the login client".
|
|
67
67
|
*/
|
|
68
|
-
exports.USER_LOGIN_CLIENT_NAME =
|
|
68
|
+
exports.USER_LOGIN_CLIENT_NAME = "Agent Security login";
|
|
69
69
|
/**
|
|
70
70
|
* Whether a client is *the* shared user-login client, decided **only** by its
|
|
71
71
|
* id. A client carrying {@link USER_LOGIN_CLIENT_NAME} under any other id is
|
|
@@ -111,11 +111,11 @@ function agentClientName(opts) {
|
|
|
111
111
|
const session = sessionId?.trim() ? ` · ${shortSessionLabel(sessionId)}` : "";
|
|
112
112
|
if (subAgentType) {
|
|
113
113
|
const scope = harness ? `${harness}/${subAgentType}` : subAgentType;
|
|
114
|
-
return
|
|
114
|
+
return `Sub-agent · ${scope}${session} @ ${host}`;
|
|
115
115
|
}
|
|
116
116
|
return harness
|
|
117
|
-
?
|
|
118
|
-
:
|
|
117
|
+
? `Agent · ${harness}${session} @ ${host}`
|
|
118
|
+
: `Agent${session} @ ${host}`;
|
|
119
119
|
}
|
|
120
120
|
/** How much of a session id goes into a display label. */
|
|
121
121
|
const SESSION_LABEL_LENGTH = 8;
|
|
@@ -147,5 +147,5 @@ function shortSessionLabel(sessionId) {
|
|
|
147
147
|
function projectApiKeyName(opts) {
|
|
148
148
|
const who = opts.user && opts.user !== "agent:unknown" ? opts.user : null;
|
|
149
149
|
const where = who ? `${who} @ ${opts.host}` : opts.host;
|
|
150
|
-
return
|
|
150
|
+
return `Permission checks · ${where}`;
|
|
151
151
|
}
|
package/dist/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repo": "ory-agent-plugins",
|
|
3
|
-
"commit": "
|
|
4
|
-
"commitShort": "
|
|
3
|
+
"commit": "fc1ff6ae66afbfb17f4190927e734abe3df8d241",
|
|
4
|
+
"commitShort": "fc1ff6a",
|
|
5
5
|
"branch": "main",
|
|
6
|
-
"commitDate": "2026-09-
|
|
6
|
+
"commitDate": "2026-09-09T14:04:39-07:00",
|
|
7
7
|
"dirty": false,
|
|
8
|
-
"builtAt": "2026-09-
|
|
8
|
+
"builtAt": "2026-09-09T21:08:18.388Z"
|
|
9
9
|
}
|
package/dist/cli.d.ts
CHANGED
|
@@ -66,12 +66,10 @@ export declare function promptForProjectUrl(binName: string): Promise<string | n
|
|
|
66
66
|
*/
|
|
67
67
|
export declare function interactiveConfigPrompt(binName: string): Promise<boolean>;
|
|
68
68
|
/**
|
|
69
|
-
* Run the `agent <subcommand>` family of CLI commands.
|
|
70
|
-
* agent's dynamic OAuth2 client registration (RFC 7591). Subcommands:
|
|
69
|
+
* Run the `agent <subcommand>` family of CLI commands. Subcommands:
|
|
71
70
|
*
|
|
72
|
-
* - `status` —
|
|
73
|
-
* - `unregister` —
|
|
74
|
-
* client, then clear the persisted block.
|
|
71
|
+
* - `status` — inspect the actor-bound runtime credential.
|
|
72
|
+
* - `unregister` — clean up legacy OAuth registrations.
|
|
75
73
|
*
|
|
76
74
|
* Each installed harness owns its own agent identity, so both subcommands act
|
|
77
75
|
* on `harness`'s registration by default. `--all` widens them to every
|
package/dist/cli.js
CHANGED
|
@@ -50,6 +50,7 @@ const agent_auth_js_1 = require("./agent-auth.js");
|
|
|
50
50
|
const logger_js_1 = require("./logger.js");
|
|
51
51
|
const cli_invocation_js_1 = require("./cli-invocation.js");
|
|
52
52
|
const client_js_1 = require("./client.js");
|
|
53
|
+
const status_data_js_1 = require("./status-data.js");
|
|
53
54
|
/**
|
|
54
55
|
* Shared `configure` command implementation for all plugin CLIs.
|
|
55
56
|
*
|
|
@@ -286,8 +287,12 @@ function printEnvironment() {
|
|
|
286
287
|
["ORY_SDK_URL", process.env.ORY_SDK_URL, false],
|
|
287
288
|
["ORY_AGENT_SECURITY_URL", process.env.ORY_AGENT_SECURITY_URL, false],
|
|
288
289
|
["ORY_PROJECT_ID", process.env.ORY_PROJECT_ID, false],
|
|
289
|
-
["ORY_AGENT_CLIENT_ID", process.env.ORY_AGENT_CLIENT_ID, false],
|
|
290
290
|
["ORY_OAUTH2_CLIENT_ID", process.env.ORY_OAUTH2_CLIENT_ID, false],
|
|
291
|
+
[
|
|
292
|
+
"ORY_AGENT_API_KEY",
|
|
293
|
+
process.env.ORY_AGENT_API_KEY ? "(set)" : undefined,
|
|
294
|
+
false,
|
|
295
|
+
],
|
|
291
296
|
[
|
|
292
297
|
"ORY_USER_OAUTH2_TOKEN",
|
|
293
298
|
process.env.ORY_USER_OAUTH2_TOKEN ? "(set)" : undefined,
|
|
@@ -515,12 +520,10 @@ async function interactiveConfigPrompt(binName) {
|
|
|
515
520
|
return false;
|
|
516
521
|
}
|
|
517
522
|
/**
|
|
518
|
-
* Run the `agent <subcommand>` family of CLI commands.
|
|
519
|
-
* agent's dynamic OAuth2 client registration (RFC 7591). Subcommands:
|
|
523
|
+
* Run the `agent <subcommand>` family of CLI commands. Subcommands:
|
|
520
524
|
*
|
|
521
|
-
* - `status` —
|
|
522
|
-
* - `unregister` —
|
|
523
|
-
* client, then clear the persisted block.
|
|
525
|
+
* - `status` — inspect the actor-bound runtime credential.
|
|
526
|
+
* - `unregister` — clean up legacy OAuth registrations.
|
|
524
527
|
*
|
|
525
528
|
* Each installed harness owns its own agent identity, so both subcommands act
|
|
526
529
|
* on `harness`'s registration by default. `--all` widens them to every
|
|
@@ -534,8 +537,8 @@ async function runAgentCommand(binName, harness, args) {
|
|
|
534
537
|
console.log(`Usage: ${binName} agent <subcommand> [--all]`);
|
|
535
538
|
console.log("");
|
|
536
539
|
console.log("Subcommands:");
|
|
537
|
-
console.log(" status Show
|
|
538
|
-
console.log(" unregister Delete
|
|
540
|
+
console.log(" status Show actor-bound runtime credential availability");
|
|
541
|
+
console.log(" unregister Delete legacy OAuth registrations and clear legacy state");
|
|
539
542
|
console.log("");
|
|
540
543
|
console.log("Options:");
|
|
541
544
|
console.log(` --all Act on every harness's agent client, not just ${harness}'s`);
|
|
@@ -544,7 +547,7 @@ async function runAgentCommand(binName, harness, args) {
|
|
|
544
547
|
const all = args.includes("--all");
|
|
545
548
|
switch (sub) {
|
|
546
549
|
case "status":
|
|
547
|
-
runAgentStatus(harness, all);
|
|
550
|
+
await runAgentStatus(harness, all);
|
|
548
551
|
return 0;
|
|
549
552
|
case "unregister":
|
|
550
553
|
return await runAgentUnregister(harness, all);
|
|
@@ -571,32 +574,30 @@ function selectAgentRegistrations(harness, all) {
|
|
|
571
574
|
return entries.sort((a, b) => b.credentials.registeredAt - a.credentials.registeredAt ||
|
|
572
575
|
a.harness.localeCompare(b.harness));
|
|
573
576
|
}
|
|
574
|
-
function runAgentStatus(harness, all) {
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
|
|
577
|
+
async function runAgentStatus(harness, all) {
|
|
578
|
+
const config = (0, config_js_1.loadConfig)();
|
|
579
|
+
const harnesses = all
|
|
580
|
+
? [...new Set([
|
|
581
|
+
...(config.installedHarnesses ?? []),
|
|
582
|
+
...Object.keys(config.delegationAnchors ?? {}),
|
|
583
|
+
])].sort()
|
|
584
|
+
: [harness];
|
|
585
|
+
console.log("Agent identity (actor-bound runtime)");
|
|
586
|
+
console.log("====================================");
|
|
578
587
|
console.log("");
|
|
579
|
-
if (
|
|
580
|
-
console.log(
|
|
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");
|
|
584
|
-
console.log(" ORY_AGENT_REGISTRATION_TOKEN) as the initial access token.");
|
|
588
|
+
if (harnesses.length === 0) {
|
|
589
|
+
console.log(" No installed harnesses found.");
|
|
585
590
|
return;
|
|
586
591
|
}
|
|
587
|
-
for (const
|
|
592
|
+
for (const key of harnesses) {
|
|
593
|
+
const sessionKey = (0, status_data_js_1.latestRuntimeSession)(key);
|
|
594
|
+
const identity = await (0, status_data_js_1.inspectRuntimeAgentIdentity)(key, sessionKey);
|
|
588
595
|
console.log(` harness: ${key}`);
|
|
589
596
|
console.log(` session: ${sessionKey}`);
|
|
590
|
-
console.log(
|
|
591
|
-
console.log(`
|
|
592
|
-
console.log(`
|
|
593
|
-
console.log(`
|
|
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
|
-
}
|
|
597
|
+
console.log(" method: Talos API key");
|
|
598
|
+
console.log(` source: ${identity.source === "talos_environment" ? "ORY_AGENT_API_KEY" : "OS credential store"}`);
|
|
599
|
+
console.log(` status: ${identity.source === "unavailable" ? "not found (enrollment runs at session start)" : "available"}`);
|
|
600
|
+
console.log(` actor_id: ${identity.subject ?? "resolved by Agent Security at request time"}`);
|
|
600
601
|
console.log("");
|
|
601
602
|
}
|
|
602
603
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ export interface OryAgentDynamicCredentials {
|
|
|
68
68
|
harness?: string;
|
|
69
69
|
/**
|
|
70
70
|
* The human-readable OAuth2 `client_name` this registration was issued
|
|
71
|
-
* under (e.g. `"
|
|
71
|
+
* under (e.g. `"Agent · claude-code @ host"`). Kept only
|
|
72
72
|
* on a fresh registration response for immediate display; never persisted.
|
|
73
73
|
* Later callers reconstruct a best-effort name from the outer harness key.
|
|
74
74
|
*/
|
package/dist/status-cli.d.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
+
import type { TalosCredentialStore } from "./runtime-credential.js";
|
|
1
2
|
/**
|
|
2
3
|
* Render the "User identity" block. The interactive PKCE login runs every
|
|
3
4
|
* session; this shows the cached token's subject and expiry, if any.
|
|
4
5
|
*/
|
|
5
6
|
export declare function printUserIdentitySection(): void;
|
|
6
7
|
/**
|
|
7
|
-
* Render the
|
|
8
|
-
*
|
|
9
|
-
* installed harness has its own agent registration, so the report is for
|
|
10
|
-
* `harness`'s identity only.
|
|
8
|
+
* Render the actor-bound runtime credential used by this harness. The status
|
|
9
|
+
* command only reads credentials; enrollment remains a session-start action.
|
|
11
10
|
*/
|
|
12
|
-
export declare function printAgentIdentitySection(harness: string): void
|
|
11
|
+
export declare function printAgentIdentitySection(harness: string, credentialStore?: TalosCredentialStore): Promise<void>;
|
|
13
12
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* agent. A no-op when none exist yet.
|
|
13
|
+
* Child credentials are keyed by session, type, and stable spawn id in the OS
|
|
14
|
+
* credential store. That store has no portable enumeration API, so status
|
|
15
|
+
* reports the active model rather than pretending the retired DCR config is
|
|
16
|
+
* the current set of sub-agents.
|
|
19
17
|
*/
|
|
20
18
|
export declare function printSubAgentIdentitiesSection(harness: string): void;
|
|
21
19
|
/**
|
package/dist/status-cli.js
CHANGED
|
@@ -16,9 +16,7 @@ exports.runStatusCommand = runStatusCommand;
|
|
|
16
16
|
*/
|
|
17
17
|
const config_js_1 = require("./config.js");
|
|
18
18
|
const auth_store_js_1 = require("./auth-store.js");
|
|
19
|
-
const agent_auth_js_1 = require("./agent-auth.js");
|
|
20
19
|
const branding_js_1 = require("./branding.js");
|
|
21
|
-
const subject_js_1 = require("./subject.js");
|
|
22
20
|
const logger_js_1 = require("./logger.js");
|
|
23
21
|
const auth_js_1 = require("./auth.js");
|
|
24
22
|
const status_data_js_1 = require("./status-data.js");
|
|
@@ -78,86 +76,46 @@ function printUserIdentitySection() {
|
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
/**
|
|
81
|
-
* Render the
|
|
82
|
-
*
|
|
83
|
-
* installed harness has its own agent registration, so the report is for
|
|
84
|
-
* `harness`'s identity only.
|
|
79
|
+
* Render the actor-bound runtime credential used by this harness. The status
|
|
80
|
+
* command only reads credentials; enrollment remains a session-start action.
|
|
85
81
|
*/
|
|
86
|
-
function printAgentIdentitySection(harness) {
|
|
82
|
+
async function printAgentIdentitySection(harness, credentialStore) {
|
|
87
83
|
console.log("");
|
|
88
|
-
console.log("Agent identity (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
console.log(" Source: static client_credentials (ORY_AGENT_CLIENT_ID/SECRET)");
|
|
93
|
-
console.log(` Client ID: ${process.env.ORY_AGENT_CLIENT_ID}`);
|
|
94
|
-
const subject = (0, subject_js_1.readAgentSubjectOverride)() ?? process.env.ORY_AGENT_CLIENT_ID;
|
|
95
|
-
console.log(` Subject: ${subject}`);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const latest = (0, agent_auth_js_1.latestAgentRegistration)(harness);
|
|
99
|
-
if (!latest) {
|
|
100
|
-
console.log(" Source: not registered yet");
|
|
101
|
-
console.log(" Status: first session start will register an OAuth2 client (RFC 7591)");
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
const { sessionKey, credentials: persisted } = latest;
|
|
105
|
-
const resolved = (0, config_js_1.resolveConfig)();
|
|
106
|
-
const mismatched = resolved.projectUrl && persisted.projectUrl !== resolved.projectUrl;
|
|
107
|
-
console.log(" Source: OAuth2 Dynamic Client Registration (RFC 7591)");
|
|
108
|
-
console.log(` Status: registered`);
|
|
109
|
-
console.log(` Name: ${(0, status_data_js_1.resolveDynamicName)(persisted)}`);
|
|
110
|
-
console.log(` Client ID: ${persisted.clientId}`);
|
|
111
|
-
const subject = (0, subject_js_1.readAgentSubjectOverride)() ?? persisted.clientId;
|
|
112
|
-
console.log(` Subject: ${subject_js_1.AGENT_NAMESPACE}:${subject}`);
|
|
113
|
-
console.log(` Registered: ${new Date(persisted.registeredAt * 1000).toISOString()}`);
|
|
84
|
+
console.log("Agent identity (actor-bound runtime):");
|
|
85
|
+
const identity = await (0, status_data_js_1.inspectRuntimeAgentIdentity)(harness, undefined, credentialStore);
|
|
86
|
+
const sessionKey = identity.sessionKey ?? config_js_1.SESSIONLESS_KEY;
|
|
87
|
+
console.log(" Method: Talos API key");
|
|
114
88
|
console.log(` Session: ${sessionKey}`);
|
|
115
|
-
console.log(` Retained: ${(0, agent_auth_js_1.countAgentSessions)(harness)} session(s)`);
|
|
116
89
|
if (sessionKey !== config_js_1.SESSIONLESS_KEY) {
|
|
117
|
-
console.log(` Session
|
|
90
|
+
console.log(` Session ref: ${(0, branding_js_1.shortSessionLabel)(sessionKey)}`);
|
|
91
|
+
}
|
|
92
|
+
if (identity.source === "talos_environment") {
|
|
93
|
+
console.log(" Source: ORY_AGENT_API_KEY");
|
|
94
|
+
console.log(" Status: available");
|
|
95
|
+
}
|
|
96
|
+
else if (identity.source === "talos_os_store") {
|
|
97
|
+
console.log(" Source: OS credential store");
|
|
98
|
+
console.log(" Status: available");
|
|
118
99
|
}
|
|
119
|
-
|
|
120
|
-
console.log(
|
|
121
|
-
console.log("
|
|
100
|
+
else {
|
|
101
|
+
console.log(" Source: OS credential store");
|
|
102
|
+
console.log(" Status: not found (enrollment runs at session start)");
|
|
122
103
|
}
|
|
104
|
+
console.log(` Actor ID: ${identity.subject ?? "resolved by Agent Security at request time"}`);
|
|
123
105
|
}
|
|
124
106
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* agent. A no-op when none exist yet.
|
|
107
|
+
* Child credentials are keyed by session, type, and stable spawn id in the OS
|
|
108
|
+
* credential store. That store has no portable enumeration API, so status
|
|
109
|
+
* reports the active model rather than pretending the retired DCR config is
|
|
110
|
+
* the current set of sub-agents.
|
|
130
111
|
*/
|
|
131
112
|
function printSubAgentIdentitiesSection(harness) {
|
|
132
|
-
const sessionKey = (0,
|
|
133
|
-
const subAgents = sessionKey
|
|
134
|
-
? (0, agent_auth_js_1.loadAllSubAgentDynamicCredentials)(harness, sessionKey)
|
|
135
|
-
: {};
|
|
136
|
-
const types = Object.keys(subAgents).sort((a, b) => a.localeCompare(b));
|
|
113
|
+
const sessionKey = (0, status_data_js_1.latestRuntimeSession)(harness);
|
|
137
114
|
console.log("");
|
|
138
|
-
console.log(`Sub-agent identities
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
const resolved = (0, config_js_1.resolveConfig)();
|
|
145
|
-
types.forEach((type, i) => {
|
|
146
|
-
if (i > 0)
|
|
147
|
-
console.log("");
|
|
148
|
-
const creds = subAgents[type];
|
|
149
|
-
const subject = creds.delegation?.delegatedBy
|
|
150
|
-
? `subagent:${creds.clientId} (delegated by ${creds.delegation.delegatedBy})`
|
|
151
|
-
: `subagent:${creds.clientId}`;
|
|
152
|
-
console.log(` ${type}:`);
|
|
153
|
-
console.log(` Name: ${(0, status_data_js_1.resolveDynamicName)(creds, type)}`);
|
|
154
|
-
console.log(` Client ID: ${creds.clientId}`);
|
|
155
|
-
console.log(` Subject: ${subject}`);
|
|
156
|
-
console.log(` Registered: ${new Date(creds.registeredAt * 1000).toISOString()}`);
|
|
157
|
-
if (resolved.projectUrl && creds.projectUrl !== resolved.projectUrl) {
|
|
158
|
-
console.log(` Warning: registered against ${creds.projectUrl}, but current project URL is ${resolved.projectUrl}`);
|
|
159
|
-
}
|
|
160
|
-
});
|
|
115
|
+
console.log(`Sub-agent identities (session ${(0, branding_js_1.shortSessionLabel)(sessionKey)}):`);
|
|
116
|
+
console.log(" Method: child Talos API key");
|
|
117
|
+
console.log(" Scope: one credential per stable sub-agent spawn");
|
|
118
|
+
console.log(" Source: OS credential store (resolved when the sub-agent starts)");
|
|
161
119
|
}
|
|
162
120
|
/**
|
|
163
121
|
* Render the "Permissions" block: the deny posture, the namespace, and the
|
|
@@ -201,7 +159,7 @@ async function printPermissionsSection(binName, harness) {
|
|
|
201
159
|
const spinner = process.stdout.isTTY === true;
|
|
202
160
|
if (spinner)
|
|
203
161
|
process.stdout.write(" checking…\r");
|
|
204
|
-
const probe = await (0, status_data_js_1.probePermissionsCoverage)(harness);
|
|
162
|
+
const probe = await (0, status_data_js_1.probePermissionsCoverage)(harness, (0, status_data_js_1.latestRuntimeSession)(harness));
|
|
205
163
|
if (spinner)
|
|
206
164
|
process.stdout.write(" ".repeat(40) + "\r");
|
|
207
165
|
if (!probe) {
|
|
@@ -271,7 +229,7 @@ async function runStatusCommand(binName, harness, options) {
|
|
|
271
229
|
console.log("");
|
|
272
230
|
(0, cli_js_1.printOryConfig)();
|
|
273
231
|
printUserIdentitySection();
|
|
274
|
-
printAgentIdentitySection(harness);
|
|
232
|
+
await printAgentIdentitySection(harness);
|
|
275
233
|
printSubAgentIdentitiesSection(harness);
|
|
276
234
|
await printPermissionsSection(binName, harness);
|
|
277
235
|
if (options.printPluginSection) {
|
package/dist/status-data.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { type PermissionMode, type SecurityConnection } from "./config.js";
|
|
14
14
|
import { type PermissionModeSource } from "./permission-mode.js";
|
|
15
|
+
import type { TalosCredentialStore } from "./runtime-credential.js";
|
|
15
16
|
import { type StatusSystemSection } from "./status-system.js";
|
|
16
17
|
export interface PermissionsCoverage {
|
|
17
18
|
total: number;
|
|
@@ -42,7 +43,7 @@ export interface PermissionsCoverage {
|
|
|
42
43
|
* Checks use the same default-allow `use` permit as the runtime gate. A false
|
|
43
44
|
* result therefore means an explicit block, not missing grant coverage.
|
|
44
45
|
*/
|
|
45
|
-
export declare function probePermissionsCoverage(harness: string): Promise<PermissionsCoverage | undefined>;
|
|
46
|
+
export declare function probePermissionsCoverage(harness: string, sessionKey?: string): Promise<PermissionsCoverage | undefined>;
|
|
46
47
|
export interface StatusConfigSection {
|
|
47
48
|
configPath: string;
|
|
48
49
|
/** Whether a config file actually exists at `configPath` (vs. where one would be written). */
|
|
@@ -94,52 +95,50 @@ export interface StatusUserSection {
|
|
|
94
95
|
expiresInSeconds?: number;
|
|
95
96
|
clientId?: string;
|
|
96
97
|
}
|
|
97
|
-
export type AgentIdentitySource = "
|
|
98
|
+
export type AgentIdentitySource = "talos_environment" | "talos_os_store" | "unavailable"
|
|
99
|
+
/** @deprecated Legacy status values retained for API compatibility. */
|
|
100
|
+
| "static_client_credentials" | "dcr" | "unregistered";
|
|
98
101
|
export interface StatusAgentSection {
|
|
99
102
|
source: AgentIdentitySource;
|
|
100
|
-
/**
|
|
103
|
+
/** Broker-assigned actor id. Unavailable for an opaque environment credential. */
|
|
104
|
+
subject?: string;
|
|
105
|
+
/** Session identity inspected in the OS credential store. */
|
|
106
|
+
sessionKey?: string;
|
|
107
|
+
reason?: string;
|
|
108
|
+
/** @deprecated Runtime identities no longer use OAuth client registrations. */
|
|
101
109
|
name?: string;
|
|
110
|
+
/** @deprecated Runtime identities no longer use OAuth client registrations. */
|
|
102
111
|
clientId?: string;
|
|
103
|
-
|
|
112
|
+
/** @deprecated Runtime identities no longer use OAuth client registrations. */
|
|
104
113
|
registeredAt?: string;
|
|
105
|
-
/**
|
|
106
|
-
* The session whose credential this report describes, if any. Sessionless SDK
|
|
107
|
-
* callers report the reserved `sessionless` key.
|
|
108
|
-
*/
|
|
109
|
-
sessionKey?: string;
|
|
110
|
-
/**
|
|
111
|
-
* The narrower per-session subject for this run. Absent when there is no
|
|
112
|
-
* ambient session (an SDK integration with no session concept).
|
|
113
|
-
*/
|
|
114
|
+
/** @deprecated Runtime identities are already actor-bound. */
|
|
114
115
|
sessionSubject?: string;
|
|
116
|
+
/** @deprecated Runtime credentials are keyed by project and cannot mismatch it. */
|
|
115
117
|
projectUrlMismatch?: {
|
|
116
118
|
registeredAgainst: string;
|
|
117
119
|
current: string;
|
|
118
120
|
};
|
|
119
121
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
export interface StatusSubAgentSection {
|
|
129
|
-
/** Sub-agent type key (the config map key), e.g. `"Explore"`. */
|
|
122
|
+
export interface StatusSubAgentRuntimeSection {
|
|
123
|
+
source: "talos_os_store";
|
|
124
|
+
scope: "per_spawn";
|
|
125
|
+
sessionKey: string;
|
|
126
|
+
reason: string;
|
|
127
|
+
}
|
|
128
|
+
/** @deprecated DCR-shaped rows are retained in the type for API compatibility only. */
|
|
129
|
+
export interface StatusSubAgentLegacySection {
|
|
130
130
|
subAgentType: string;
|
|
131
|
-
/** Human-readable OAuth2 client_name for this sub-agent, when known. */
|
|
132
131
|
name?: string;
|
|
133
132
|
clientId: string;
|
|
134
133
|
subject: string;
|
|
135
134
|
registeredAt?: string;
|
|
136
|
-
/** The delegator recorded at registration (`agent:<sub>`), when known. */
|
|
137
135
|
delegatedBy?: string;
|
|
138
136
|
projectUrlMismatch?: {
|
|
139
137
|
registeredAgainst: string;
|
|
140
138
|
current: string;
|
|
141
139
|
};
|
|
142
140
|
}
|
|
141
|
+
export type StatusSubAgentSection = StatusSubAgentRuntimeSection | StatusSubAgentLegacySection;
|
|
143
142
|
export type PermissionsCoverageStatus =
|
|
144
143
|
/** Agent Security isn't connected — no project URL and/or OAuth2 client id. */
|
|
145
144
|
"not_connected" | "no_catalog" | "no_user" | "fully_allowed" | "partially_blocked" | "fully_blocked"
|
|
@@ -168,24 +167,15 @@ export interface StatusReport {
|
|
|
168
167
|
config: StatusConfigSection;
|
|
169
168
|
user: StatusUserSection;
|
|
170
169
|
agent: StatusAgentSection;
|
|
171
|
-
/**
|
|
170
|
+
/** Runtime child-identity model; credentials themselves remain in the OS store. */
|
|
172
171
|
subAgents: StatusSubAgentSection[];
|
|
173
172
|
permissions: StatusPermissionsSection;
|
|
174
173
|
activity: StatusActivitySection;
|
|
175
174
|
/** Core Ory service health (Kratos, Hydra, Keto) — the dashboard's "System information". */
|
|
176
175
|
system: StatusSystemSection;
|
|
177
176
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
* `client_name` when present, else a best-effort reconstruction from the
|
|
181
|
-
* harness and (for sub-agents) type. Reconstruction uses the current hostname,
|
|
182
|
-
* which may differ from the registration host for credentials saved before the
|
|
183
|
-
* name was persisted — acceptable for a display-only label.
|
|
184
|
-
*/
|
|
185
|
-
export declare function resolveDynamicName(creds: {
|
|
186
|
-
clientName?: string;
|
|
187
|
-
harness?: string;
|
|
188
|
-
}, subAgentType?: string, harness?: string): string;
|
|
177
|
+
export declare function latestRuntimeSession(harness: string): string;
|
|
178
|
+
export declare function inspectRuntimeAgentIdentity(harness: string, sessionKey?: string, credentialStore?: TalosCredentialStore): Promise<StatusAgentSection>;
|
|
189
179
|
/**
|
|
190
180
|
* Gather the full structured status report for a harness. The permissions
|
|
191
181
|
* section runs a live network probe when a project URL and user identity are
|
package/dist/status-data.js
CHANGED
|
@@ -34,7 +34,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.probePermissionsCoverage = probePermissionsCoverage;
|
|
37
|
-
exports.
|
|
37
|
+
exports.latestRuntimeSession = latestRuntimeSession;
|
|
38
|
+
exports.inspectRuntimeAgentIdentity = inspectRuntimeAgentIdentity;
|
|
38
39
|
exports.collectStatusReport = collectStatusReport;
|
|
39
40
|
/**
|
|
40
41
|
* Structured status data — the data-gathering half of the `status` command,
|
|
@@ -52,12 +53,10 @@ const config_js_1 = require("./config.js");
|
|
|
52
53
|
const permission_mode_js_1 = require("./permission-mode.js");
|
|
53
54
|
const auth_store_js_1 = require("./auth-store.js");
|
|
54
55
|
const agent_auth_js_1 = require("./agent-auth.js");
|
|
55
|
-
const subject_js_1 = require("./subject.js");
|
|
56
56
|
const client_js_1 = require("./client.js");
|
|
57
|
-
const
|
|
57
|
+
const subject_js_1 = require("./subject.js");
|
|
58
58
|
const branding_js_1 = require("./branding.js");
|
|
59
59
|
const auth_js_1 = require("./auth.js");
|
|
60
|
-
const node_os_1 = require("node:os");
|
|
61
60
|
const tool_catalog_js_1 = require("./tool-catalog.js");
|
|
62
61
|
const opl_js_1 = require("./opl.js");
|
|
63
62
|
const fs = __importStar(require("node:fs"));
|
|
@@ -76,7 +75,7 @@ function resolveNamespace() {
|
|
|
76
75
|
* Checks use the same default-allow `use` permit as the runtime gate. A false
|
|
77
76
|
* result therefore means an explicit block, not missing grant coverage.
|
|
78
77
|
*/
|
|
79
|
-
async function probePermissionsCoverage(harness) {
|
|
78
|
+
async function probePermissionsCoverage(harness, sessionKey = latestRuntimeSession(harness)) {
|
|
80
79
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
81
80
|
if (!resolved.projectUrl)
|
|
82
81
|
return undefined;
|
|
@@ -92,14 +91,20 @@ async function probePermissionsCoverage(harness) {
|
|
|
92
91
|
if (tokens && !(0, auth_store_js_1.isExpired)(tokens)) {
|
|
93
92
|
client.setUserPrincipal({ subject: tokens.subject, token: tokens.accessToken });
|
|
94
93
|
}
|
|
95
|
-
await (0, agent_auth_js_1.
|
|
96
|
-
|
|
94
|
+
const runtime = await (0, agent_auth_js_1.resolveRuntimeAgentCredentials)({
|
|
95
|
+
projectUrl: resolved.projectUrl,
|
|
96
|
+
harness,
|
|
97
|
+
sessionId: sessionKey,
|
|
97
98
|
});
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
if (runtime.runtimeCredential)
|
|
100
|
+
client.setRuntimeCredential(runtime.runtimeCredential);
|
|
101
|
+
if (runtime.subject)
|
|
102
|
+
client.setAgentPrincipal({ subject: runtime.subject }, sessionKey);
|
|
103
|
+
const subject = (0, subject_js_1.resolveUserSubject)(client);
|
|
104
|
+
const subjectId = (0, subject_js_1.subjectLabel)(subject);
|
|
100
105
|
if (subjectId === "agent:unknown")
|
|
101
106
|
return undefined;
|
|
102
|
-
const agentSubject = (0,
|
|
107
|
+
const agentSubject = (0, subject_js_1.resolveAgentSubject)(client);
|
|
103
108
|
const live = await (0, permission_mode_js_1.resolvePermissionMode)(client, subject, {
|
|
104
109
|
additionalSubjects: agentSubject ? [{ scope: "agent", subject: agentSubject }] : [],
|
|
105
110
|
});
|
|
@@ -177,78 +182,41 @@ function collectUser() {
|
|
|
177
182
|
clientId: tokens.clientId,
|
|
178
183
|
};
|
|
179
184
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
* harness and (for sub-agents) type. Reconstruction uses the current hostname,
|
|
184
|
-
* which may differ from the registration host for credentials saved before the
|
|
185
|
-
* name was persisted — acceptable for a display-only label.
|
|
186
|
-
*/
|
|
187
|
-
function resolveDynamicName(creds, subAgentType, harness) {
|
|
188
|
-
return (creds.clientName ??
|
|
189
|
-
(0, branding_js_1.agentClientName)({
|
|
190
|
-
harness: creds.harness ?? harness,
|
|
191
|
-
host: (0, node_os_1.hostname)() || "unknown-host",
|
|
192
|
-
subAgentType,
|
|
193
|
-
}));
|
|
185
|
+
function latestRuntimeSession(harness) {
|
|
186
|
+
const sessions = Object.keys((0, config_js_1.loadConfig)().delegationAnchors?.[harness] ?? {});
|
|
187
|
+
return sessions.at(-1) ?? config_js_1.SESSIONLESS_KEY;
|
|
194
188
|
}
|
|
195
|
-
function
|
|
196
|
-
|
|
189
|
+
async function inspectRuntimeAgentIdentity(harness, sessionKey = latestRuntimeSession(harness), credentialStore) {
|
|
190
|
+
const credentials = await (0, agent_auth_js_1.resolveRuntimeAgentCredentials)({
|
|
191
|
+
projectUrl: (0, config_js_1.resolveConfig)().projectUrl,
|
|
192
|
+
harness,
|
|
193
|
+
sessionId: sessionKey,
|
|
194
|
+
credentialStore,
|
|
195
|
+
});
|
|
196
|
+
if (credentials.kind === "talos") {
|
|
197
|
+
const source = process.env.ORY_AGENT_API_KEY?.trim()
|
|
198
|
+
? "talos_environment"
|
|
199
|
+
: "talos_os_store";
|
|
197
200
|
return {
|
|
198
|
-
source
|
|
199
|
-
|
|
200
|
-
subject:
|
|
201
|
+
source,
|
|
202
|
+
sessionKey,
|
|
203
|
+
subject: credentials.subject,
|
|
204
|
+
reason: credentials.reason,
|
|
201
205
|
};
|
|
202
206
|
}
|
|
203
|
-
const selected = sessionKey
|
|
204
|
-
? (() => {
|
|
205
|
-
const credentials = (0, agent_auth_js_1.loadAgentDynamicCredentials)(harness, sessionKey);
|
|
206
|
-
return credentials ? { sessionKey, credentials } : undefined;
|
|
207
|
-
})()
|
|
208
|
-
: (0, agent_auth_js_1.latestAgentRegistration)(harness);
|
|
209
|
-
if (!selected)
|
|
210
|
-
return { source: "unregistered" };
|
|
211
|
-
const { sessionKey: credentialSession, credentials: persisted } = selected;
|
|
212
|
-
const resolved = (0, config_js_1.resolveConfig)();
|
|
213
|
-
const mismatch = resolved.projectUrl && persisted.projectUrl !== resolved.projectUrl
|
|
214
|
-
? { registeredAgainst: persisted.projectUrl, current: resolved.projectUrl }
|
|
215
|
-
: undefined;
|
|
216
|
-
const subject = (0, subject_js_2.readAgentSubjectOverride)() ?? persisted.clientId;
|
|
217
207
|
return {
|
|
218
|
-
source: "
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
...(credentialSession === config_js_1.SESSIONLESS_KEY
|
|
222
|
-
? {}
|
|
223
|
-
: { sessionSubject: `${subject_js_1.AGENT_NAMESPACE}:${subject}|${credentialSession}` }),
|
|
224
|
-
clientId: persisted.clientId,
|
|
225
|
-
subject,
|
|
226
|
-
registeredAt: new Date(persisted.registeredAt * 1000).toISOString(),
|
|
227
|
-
projectUrlMismatch: mismatch,
|
|
208
|
+
source: "unavailable",
|
|
209
|
+
sessionKey,
|
|
210
|
+
reason: credentials.reason,
|
|
228
211
|
};
|
|
229
212
|
}
|
|
230
213
|
function collectSubAgents(harness, requestedSession) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
.map(([subAgentType, creds]) => {
|
|
238
|
-
const mismatch = resolved.projectUrl && creds.projectUrl !== resolved.projectUrl
|
|
239
|
-
? { registeredAgainst: creds.projectUrl, current: resolved.projectUrl }
|
|
240
|
-
: undefined;
|
|
241
|
-
return {
|
|
242
|
-
subAgentType,
|
|
243
|
-
name: resolveDynamicName(creds, subAgentType, harness),
|
|
244
|
-
clientId: creds.clientId,
|
|
245
|
-
subject: creds.clientId,
|
|
246
|
-
registeredAt: new Date(creds.registeredAt * 1000).toISOString(),
|
|
247
|
-
delegatedBy: creds.delegation?.delegatedBy,
|
|
248
|
-
projectUrlMismatch: mismatch,
|
|
249
|
-
};
|
|
250
|
-
})
|
|
251
|
-
.sort((a, b) => a.subAgentType.localeCompare(b.subAgentType));
|
|
214
|
+
return [{
|
|
215
|
+
source: "talos_os_store",
|
|
216
|
+
scope: "per_spawn",
|
|
217
|
+
sessionKey: requestedSession ?? latestRuntimeSession(harness),
|
|
218
|
+
reason: "Child credentials are resolved by stable sub-agent type and spawn id at runtime",
|
|
219
|
+
}];
|
|
252
220
|
}
|
|
253
221
|
async function collectPermissions(harness) {
|
|
254
222
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
@@ -325,7 +293,7 @@ async function collectStatusReport(harness, sessionKey) {
|
|
|
325
293
|
harness,
|
|
326
294
|
config: collectConfig(harness),
|
|
327
295
|
user: collectUser(),
|
|
328
|
-
agent:
|
|
296
|
+
agent: await inspectRuntimeAgentIdentity(harness, sessionKey ?? latestRuntimeSession(harness)),
|
|
329
297
|
subAgents: collectSubAgents(harness, sessionKey),
|
|
330
298
|
permissions: await collectPermissions(harness),
|
|
331
299
|
activity: collectActivity(harness),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Ory Argus: the core API for building authentication, authorization, and audit into AI agent harness plugins, extensions, and custom integrations",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ory.com",
|