@ory/argus 0.2.0 → 0.2.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/dist/dev.js +1 -1
- package/dist/local/cli.js +1 -1
- package/dist/local/manager.js +1 -1
- package/dist/local/seed.js +3 -3
- package/dist/permissions-cli.js +59 -17
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -485,7 +485,7 @@ async function bootstrapLocalOry(localDir) {
|
|
|
485
485
|
return { active: false };
|
|
486
486
|
}
|
|
487
487
|
console.log(`[ory-dev] Local Ory: agent ${seed.agent.identity.email}, user ${seed.user.identity.email}, ` +
|
|
488
|
-
`${seed.permissions.tuples}
|
|
488
|
+
`${seed.permissions.tuples} permissions in '${namespace}' for ${seed.permissions.subject}.`);
|
|
489
489
|
return { active: true, gatewayUrl, seed };
|
|
490
490
|
}
|
|
491
491
|
/**
|
package/dist/local/cli.js
CHANGED
|
@@ -63,7 +63,7 @@ Commands:
|
|
|
63
63
|
up [--no-seed] Start local Ory services (Kratos, Keto, Hydra, gateway)
|
|
64
64
|
down Stop all local services (preserves data)
|
|
65
65
|
status Show service health and container states
|
|
66
|
-
seed Create test identity, session, and
|
|
66
|
+
seed Create test identity, session, and permissions
|
|
67
67
|
logs [service] [-f] View service logs (optionally follow, optionally filter)
|
|
68
68
|
reset Stop services and remove all data
|
|
69
69
|
env Print environment variables for connecting to local services
|
package/dist/local/manager.js
CHANGED
|
@@ -642,7 +642,7 @@ function printSeedResult(result) {
|
|
|
642
642
|
console.log(` User password: ${result.user.password}`);
|
|
643
643
|
console.log(` User OAuth2: ${result.user.client.clientId} (PKCE)`);
|
|
644
644
|
console.log("");
|
|
645
|
-
console.log(` Permissions: ${result.permissions.tuples}
|
|
645
|
+
console.log(` Permissions: ${result.permissions.tuples} entries in '${result.permissions.namespace}' for ${result.permissions.subject}`);
|
|
646
646
|
console.log("");
|
|
647
647
|
console.log("To use with any Ory agent plugin, set these environment variables:");
|
|
648
648
|
console.log("");
|
package/dist/local/seed.js
CHANGED
|
@@ -110,7 +110,7 @@ async function seedPermissions(userId, namespace) {
|
|
|
110
110
|
catch (err) {
|
|
111
111
|
const msg = err instanceof Error ? err.message : String(err);
|
|
112
112
|
if (!msg.includes("409")) {
|
|
113
|
-
process.stderr.write(` Warning: failed to create
|
|
113
|
+
process.stderr.write(` Warning: failed to create permission for ${tool}: ${msg}\n`);
|
|
114
114
|
}
|
|
115
115
|
else {
|
|
116
116
|
created++;
|
|
@@ -185,9 +185,9 @@ async function seedLocalEnvironment(namespace = "AgentTools") {
|
|
|
185
185
|
// Subject is a SubjectSet `User:<id>` so the Console UI can rewrite
|
|
186
186
|
// the same tuple shape by hand during the runbook demo.
|
|
187
187
|
const subjectLabel = `${exports.USER_SUBJECT_NAMESPACE}:${userIdentity.id}`;
|
|
188
|
-
process.stderr.write(` Creating
|
|
188
|
+
process.stderr.write(` Creating permissions for ${COMMON_TOOLS.length} tools...\n`);
|
|
189
189
|
const tupleCount = await seedPermissions(userIdentity.id, namespace);
|
|
190
|
-
process.stderr.write(` Permissions: ${tupleCount}
|
|
190
|
+
process.stderr.write(` Permissions: ${tupleCount} entries in '${namespace}' for ${subjectLabel}\n`);
|
|
191
191
|
// 3. User OAuth2 client (PKCE) — pre-registered so the user gate's
|
|
192
192
|
// PKCE flow has somewhere to authenticate against. The agent's
|
|
193
193
|
// OAuth2 client is intentionally NOT pre-registered; the harness
|
package/dist/permissions-cli.js
CHANGED
|
@@ -84,7 +84,7 @@ function printPermissionsHelp(binName) {
|
|
|
84
84
|
console.log("");
|
|
85
85
|
console.log("Subcommands:");
|
|
86
86
|
console.log(" status Show permission mode and tool coverage for the current user");
|
|
87
|
-
console.log(" bootstrap
|
|
87
|
+
console.log(" bootstrap Grant the current user 'use' on every built-in tool (idempotent)");
|
|
88
88
|
console.log(" observe Switch to observe mode (denies log but don't block)");
|
|
89
89
|
console.log(" enforce Switch to enforce mode (denies block — production posture)");
|
|
90
90
|
console.log("");
|
|
@@ -104,7 +104,7 @@ function runPermissionsSetMode(binName, mode) {
|
|
|
104
104
|
console.log("Denies will be logged and recorded as `permission.observe_deny` spans,");
|
|
105
105
|
console.log("but tools will be allowed through. Run");
|
|
106
106
|
console.log(` ${binName} permissions enforce`);
|
|
107
|
-
console.log("once your
|
|
107
|
+
console.log("once your permission set is correct.");
|
|
108
108
|
}
|
|
109
109
|
else {
|
|
110
110
|
console.log("Denies will block tool execution. The plugin is now enforcing.");
|
|
@@ -121,9 +121,10 @@ async function runPermissionsStatus(binName, harness) {
|
|
|
121
121
|
console.log(`Permission status (${harness})`);
|
|
122
122
|
console.log("==========================================");
|
|
123
123
|
console.log("");
|
|
124
|
-
console.log(`Mode: ${resolved.permissionMode}
|
|
124
|
+
console.log(`Mode: ${resolved.permissionMode}${formatModeSource(resolved.permissionModeSource)}`);
|
|
125
|
+
console.log(` (other modes: ${otherModes(resolved.permissionMode).join(", ")})`);
|
|
125
126
|
console.log(`Namespace: ${namespace}`);
|
|
126
|
-
console.log(`Project URL: ${resolved.projectUrl ?? "(not set)"}
|
|
127
|
+
console.log(`Project URL: ${resolved.projectUrl ?? "(not set)"}${formatSourceSuffix(resolved.projectUrlSource)}`);
|
|
127
128
|
console.log(`Audit-only: ${resolved.auditOnly ? "yes (Ory disabled)" : "no"}`);
|
|
128
129
|
console.log("");
|
|
129
130
|
if (resolved.auditOnly) {
|
|
@@ -132,7 +133,7 @@ async function runPermissionsStatus(binName, harness) {
|
|
|
132
133
|
return 0;
|
|
133
134
|
}
|
|
134
135
|
if (!resolved.projectUrl) {
|
|
135
|
-
console.log("No project URL configured — cannot probe
|
|
136
|
+
console.log("No project URL configured — cannot probe permission coverage.");
|
|
136
137
|
console.log(`Configure first: ${binName} configure --project-url <URL> --api-key <KEY>`);
|
|
137
138
|
return 0;
|
|
138
139
|
}
|
|
@@ -214,7 +215,7 @@ async function runPermissionsBootstrap(binName, harness, args) {
|
|
|
214
215
|
return 1;
|
|
215
216
|
}
|
|
216
217
|
if (!resolved.projectUrl) {
|
|
217
|
-
console.error("No ORY_PROJECT_URL configured — cannot write
|
|
218
|
+
console.error("No ORY_PROJECT_URL configured — cannot write permissions.");
|
|
218
219
|
console.error(`Configure first: ${binName} configure --project-url <URL> --api-key <KEY>`);
|
|
219
220
|
return 1;
|
|
220
221
|
}
|
|
@@ -231,14 +232,14 @@ async function runPermissionsBootstrap(binName, harness, args) {
|
|
|
231
232
|
const subject = (0, subject_js_1.resolveUserSubject)(client);
|
|
232
233
|
const subjectId = (0, subject_js_1.subjectLabel)(subject);
|
|
233
234
|
if (subjectId === "agent:unknown") {
|
|
234
|
-
console.error("No user identity resolved — refusing to write
|
|
235
|
+
console.error("No user identity resolved — refusing to write permissions for an unknown subject.");
|
|
235
236
|
console.error("");
|
|
236
237
|
console.error("Either:");
|
|
237
238
|
console.error(" - run the harness once with ORY_AUTH_GATE=1 so a user token is cached, or");
|
|
238
239
|
console.error(" - set ORY_USER_SUBJECT_ID=<id> to target a known subject.");
|
|
239
240
|
return 1;
|
|
240
241
|
}
|
|
241
|
-
console.log(`Bootstrapping ${catalog.length}
|
|
242
|
+
console.log(`Bootstrapping ${catalog.length} permissions for ${harness}`);
|
|
242
243
|
console.log("==========================================");
|
|
243
244
|
console.log("");
|
|
244
245
|
console.log(`Namespace: ${namespace}`);
|
|
@@ -246,7 +247,7 @@ async function runPermissionsBootstrap(binName, harness, args) {
|
|
|
246
247
|
console.log(`Tools: ${catalog.join(", ")}`);
|
|
247
248
|
if (dryRun) {
|
|
248
249
|
console.log("");
|
|
249
|
-
console.log("(--dry-run) No
|
|
250
|
+
console.log("(--dry-run) No permissions will be written.");
|
|
250
251
|
}
|
|
251
252
|
console.log("");
|
|
252
253
|
let created = 0;
|
|
@@ -285,7 +286,7 @@ async function runPermissionsBootstrap(binName, harness, args) {
|
|
|
285
286
|
}
|
|
286
287
|
console.log("");
|
|
287
288
|
if (dryRun) {
|
|
288
|
-
console.log(`Dry run: ${catalog.length}
|
|
289
|
+
console.log(`Dry run: ${catalog.length} permissions would be written.`);
|
|
289
290
|
return 0;
|
|
290
291
|
}
|
|
291
292
|
console.log(`Created: ${created} Already existed: ${existed} Failed: ${failures.length}`);
|
|
@@ -296,7 +297,7 @@ async function runPermissionsBootstrap(binName, harness, args) {
|
|
|
296
297
|
console.log("");
|
|
297
298
|
console.log("Some writes were rejected — your current credentials may lack");
|
|
298
299
|
console.log("write scope on the permission namespace. You can apply the");
|
|
299
|
-
console.log("
|
|
300
|
+
console.log("permissions manually using the snippet below (one per line):");
|
|
300
301
|
console.log("");
|
|
301
302
|
for (const tool of catalog) {
|
|
302
303
|
console.log(` ${namespace}:${tool}#use@${subjectId}`);
|
|
@@ -309,7 +310,7 @@ async function runPermissionsBootstrap(binName, harness, args) {
|
|
|
309
310
|
return failures.length === catalog.length ? 1 : 0;
|
|
310
311
|
}
|
|
311
312
|
console.log("");
|
|
312
|
-
console.log(`
|
|
313
|
+
console.log(`Permissions are in place. Promote to enforce mode when ready:`);
|
|
313
314
|
console.log(` ${binName} permissions enforce`);
|
|
314
315
|
return 0;
|
|
315
316
|
}
|
|
@@ -342,21 +343,22 @@ function printPermissionsOnboardingHelp(binName, harness, opts = {}) {
|
|
|
342
343
|
const catalog = (0, tool_catalog_js_1.getToolCatalog)(harness);
|
|
343
344
|
console.log("");
|
|
344
345
|
console.log("Permissions:");
|
|
345
|
-
console.log(` Mode: ${resolved.permissionMode}
|
|
346
|
+
console.log(` Mode: ${resolved.permissionMode}${formatModeSource(resolved.permissionModeSource)}`);
|
|
347
|
+
console.log(` Other modes: ${otherModes(resolved.permissionMode).join(", ")}`);
|
|
346
348
|
if (resolved.auditOnly) {
|
|
347
349
|
console.log(" Ory is in audit-only mode (kill switch). Permission checks are disabled.");
|
|
348
350
|
return;
|
|
349
351
|
}
|
|
350
352
|
if (resolved.permissionMode === "observe") {
|
|
351
353
|
console.log(" Observe mode: permission denies are logged + traced, but tools still run.");
|
|
352
|
-
console.log(" This is the safe default — promote once your
|
|
354
|
+
console.log(" This is the safe default — promote to 'enforce' once your permission set is correct.");
|
|
353
355
|
}
|
|
354
356
|
else {
|
|
355
357
|
console.log(" Enforce mode: permission denies block tool execution.");
|
|
356
358
|
}
|
|
357
359
|
if (opts.bootstrappedAutomatically) {
|
|
358
360
|
console.log("");
|
|
359
|
-
console.log(`
|
|
361
|
+
console.log(` Permissions bootstrapped for ${catalog.length} built-in tools.`);
|
|
360
362
|
}
|
|
361
363
|
else if (catalog.length > 0) {
|
|
362
364
|
console.log("");
|
|
@@ -364,12 +366,52 @@ function printPermissionsOnboardingHelp(binName, harness, opts = {}) {
|
|
|
364
366
|
console.log(` npx ${binName} permissions bootstrap`);
|
|
365
367
|
}
|
|
366
368
|
console.log("");
|
|
367
|
-
console.log(" Inspect
|
|
369
|
+
console.log(" Inspect permission coverage:");
|
|
368
370
|
console.log(` npx ${binName} permissions status`);
|
|
369
371
|
console.log("");
|
|
370
372
|
console.log(" Promote to enforcing once observe-mode logs look right:");
|
|
371
373
|
console.log(` npx ${binName} permissions enforce`);
|
|
372
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Render the trailing source annotation on a Mode line. Stays silent
|
|
377
|
+
* when the mode came from the built-in default, since saying "default"
|
|
378
|
+
* just adds noise. When the mode was overridden by env or config, name
|
|
379
|
+
* the override so the reader knows where to look.
|
|
380
|
+
*/
|
|
381
|
+
function formatModeSource(source) {
|
|
382
|
+
switch (source) {
|
|
383
|
+
case "env":
|
|
384
|
+
return ` (set via ${ENV_PERMISSION_MODE} env var)`;
|
|
385
|
+
case "config":
|
|
386
|
+
return " (saved in config; change with: permissions observe|enforce)";
|
|
387
|
+
case "default":
|
|
388
|
+
return " (built-in default)";
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Generic source-suffix helper for other config fields (project URL,
|
|
393
|
+
* API key). Source 'none' means the value is unset — don't add a suffix.
|
|
394
|
+
*/
|
|
395
|
+
function formatSourceSuffix(source) {
|
|
396
|
+
switch (source) {
|
|
397
|
+
case "env":
|
|
398
|
+
return " (from env)";
|
|
399
|
+
case "config":
|
|
400
|
+
return " (from config)";
|
|
401
|
+
case "none":
|
|
402
|
+
return "";
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Lists the modes other than the active one, in stable order, so the
|
|
407
|
+
* banner can hint "Other modes: …" without re-listing the active one.
|
|
408
|
+
* Audit-only is a separate kill switch (config.auditOnly), but we still
|
|
409
|
+
* mention it here so first-time readers learn the full set.
|
|
410
|
+
*/
|
|
411
|
+
function otherModes(active) {
|
|
412
|
+
const all = ["observe", "enforce", "audit-only"];
|
|
413
|
+
return all.filter((m) => m !== active);
|
|
414
|
+
}
|
|
373
415
|
/**
|
|
374
416
|
* If a user identity is already cached and the plugin is configured,
|
|
375
417
|
* opportunistically run `permissions bootstrap` so the user lands in a
|
|
@@ -391,7 +433,7 @@ async function maybeAutoBootstrap(binName, harness) {
|
|
|
391
433
|
return false;
|
|
392
434
|
try {
|
|
393
435
|
console.log("");
|
|
394
|
-
console.log("Bootstrapping
|
|
436
|
+
console.log("Bootstrapping permissions (cached user identity detected)...");
|
|
395
437
|
const code = await runPermissionsCommand(binName, harness, ["bootstrap"]);
|
|
396
438
|
return code === 0;
|
|
397
439
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
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",
|