@ory/argus 1.4.1 → 1.4.3
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/assets/skills/ory-deploy-agent/SKILL.md +31 -36
- package/assets/skills/ory-deploy-openai-e2b/SKILL.md +23 -17
- package/dist/build-info.json +4 -4
- package/dist/client.js +8 -1
- package/dist/event-reporter.d.ts +11 -1
- package/dist/event-reporter.js +21 -3
- package/dist/subject.d.ts +10 -1
- package/dist/subject.js +16 -2
- package/package.json +1 -1
|
@@ -25,13 +25,14 @@ print, inspect, commit, or place in a prompt:
|
|
|
25
25
|
|
|
26
26
|
- `ORY_USER_OAUTH2_TOKEN`
|
|
27
27
|
- `ANTHROPIC_API_KEY`
|
|
28
|
-
- any
|
|
28
|
+
- any streamed deployment credential value
|
|
29
29
|
- SPIFFE private keys or SVID file contents
|
|
30
30
|
|
|
31
31
|
The user OAuth2 token administers deployments as the signed-in identity. The
|
|
32
32
|
generated `ORY_AGENT_API_KEY` or customer-issued SVID is a separate runtime
|
|
33
33
|
credential. Never exchange their roles. Do not revoke a deployment or workload
|
|
34
|
-
registration
|
|
34
|
+
registration that predates the current run. Always revoke the fresh deployment
|
|
35
|
+
created for the current streamed-credential run during cleanup.
|
|
35
36
|
|
|
36
37
|
## Prerequisites
|
|
37
38
|
|
|
@@ -145,8 +146,9 @@ to `0.0.0.0`, expose the application port, and define a health check. Ignore
|
|
|
145
146
|
credentials, deployment state, dependencies, build output, and local environment
|
|
146
147
|
files in Git and the Docker context.
|
|
147
148
|
|
|
148
|
-
For Talos,
|
|
149
|
-
|
|
149
|
+
For Talos, the trusted deployment controller must inject the streamed values
|
|
150
|
+
directly into the workload's runtime secret facility without creating a local
|
|
151
|
+
credential file. For SPIFFE, use the file-backed environment contract in
|
|
150
152
|
`examples/spiffe`: mount the parent of the atomically switched `current`
|
|
151
153
|
generation read-only, and point `ORY_AGENT_SPIFFE_GENERATION_PATH` at `current`.
|
|
152
154
|
TypeScript `OryAgentClient.fromEnv()` and Python `OryAgentClient.from_env()` use
|
|
@@ -212,39 +214,31 @@ explicit owner must equal the authenticated identity.
|
|
|
212
214
|
|
|
213
215
|
## Create and deploy
|
|
214
216
|
|
|
215
|
-
|
|
217
|
+
Let the CLI create a fresh deployment and launch the trusted deployment
|
|
218
|
+
controller:
|
|
216
219
|
|
|
217
220
|
```bash
|
|
218
|
-
ory-agent deployment
|
|
221
|
+
ory-agent deployment run \
|
|
222
|
+
--result-file "$RUNNER_TEMP/ory-agent-result.json" \
|
|
223
|
+
-- trusted-deployer --credentials-stdin
|
|
219
224
|
```
|
|
220
225
|
|
|
221
|
-
The CLI
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
Verify `/healthz` and invoke `/probe` first. The guarded probe makes the first
|
|
239
|
-
authenticated runtime request that activates a ready deployment. Then run:
|
|
240
|
-
|
|
241
|
-
```bash
|
|
242
|
-
ory-agent deployment wait --for active --timeout 10m
|
|
243
|
-
ory-agent deployment status
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
Finally invoke `/run` with a prompt that calls `deployment_probe`. Diagnose
|
|
247
|
-
failures with secret-redacted logs.
|
|
226
|
+
The CLI sends the exact credential only to the child process's anonymous stdin,
|
|
227
|
+
never public stdout, a shell variable, log, or intermediate file. It strips its
|
|
228
|
+
deployment-administration credentials from the child environment. The optional
|
|
229
|
+
mode-`0600` result is non-secret and contains the newly created deployment ID.
|
|
230
|
+
Every invocation issues a new deployment and writes no credential, state,
|
|
231
|
+
pending journal, plaintext stage, or age identity.
|
|
232
|
+
|
|
233
|
+
The trusted controller must load stdin in memory, inject the values into the
|
|
234
|
+
workload secret facility, start and supervise the workload, verify `/healthz`,
|
|
235
|
+
invoke the guarded `/probe`, and exit only when that bounded workload run is
|
|
236
|
+
finished. For a long-running service, the controller must remain its supervisor;
|
|
237
|
+
do not detach and exit while the workload still needs the credential. After a
|
|
238
|
+
successful controller exit, the CLI waits for **Active** and automatically revokes.
|
|
239
|
+
It also revokes after controller failure, and a revoke failure makes the command
|
|
240
|
+
fail. Process termination before cleanup can still orphan a deployment; inventory
|
|
241
|
+
and explicitly revoke it rather than assuming a rerun will recover or reuse it.
|
|
248
242
|
|
|
249
243
|
## Customer-operated SPIFFE
|
|
250
244
|
|
|
@@ -257,7 +251,7 @@ customer exclusively owns and operates:
|
|
|
257
251
|
- helper/CSI/sidecar availability and the permissions on mounted key material
|
|
258
252
|
|
|
259
253
|
Ory records the expected workload identity and authenticates broker requests.
|
|
260
|
-
Neither `ory-agent deployment
|
|
254
|
+
Neither `ory-agent deployment run` nor the Ory packages install SPIRE, choose
|
|
261
255
|
selectors, create registrations, issue SVIDs, rotate files, or revoke workload
|
|
262
256
|
entries.
|
|
263
257
|
|
|
@@ -311,5 +305,6 @@ in the customer's non-production identity domain:
|
|
|
311
305
|
Report changed files, format/typecheck/test/build results, Docker health,
|
|
312
306
|
non-secret deployment ID and status, fixed-query and user-query probe results,
|
|
313
307
|
activation status, and blockers. Never report credentials, environment values,
|
|
314
|
-
authorization headers, or credential-file contents.
|
|
315
|
-
|
|
308
|
+
authorization headers, or credential-file contents. The trusted controller must
|
|
309
|
+
clean up its bounded workload before exiting; `deployment run` then revokes the
|
|
310
|
+
fresh Agent Security deployment automatically.
|
|
@@ -16,8 +16,9 @@ Use this playbook to turn the user's intent into a complete, secured deployment:
|
|
|
16
16
|
The user should be able to ask for an agent in product terms. Inspect the repository,
|
|
17
17
|
preserve its package manager and conventions, scaffold the application and controller,
|
|
18
18
|
run validation, and deploy it through the commands below. Ask before overwriting an
|
|
19
|
-
existing application or revoking a deployment
|
|
20
|
-
|
|
19
|
+
existing application or revoking a deployment that predates the current run. Always
|
|
20
|
+
revoke the fresh streamed-credential deployment during cleanup. Ask for missing
|
|
21
|
+
credentials; never fabricate them.
|
|
21
22
|
|
|
22
23
|
Use `ory-build-agent` for another SDK and `ory-deploy-agent` for the canonical Claude
|
|
23
24
|
Agent SDK Docker/Kubernetes deployment. Use `ory-e2b-sandbox` only when installing an
|
|
@@ -28,8 +29,8 @@ SDK application deployment.
|
|
|
28
29
|
|
|
29
30
|
Keep these components separate:
|
|
30
31
|
|
|
31
|
-
1. The trusted controller holds `E2B_API_KEY`, `OPENAI_API_KEY`, and the
|
|
32
|
-
|
|
32
|
+
1. The trusted controller holds `E2B_API_KEY`, `OPENAI_API_KEY`, and the streamed
|
|
33
|
+
deployment values in memory.
|
|
33
34
|
2. The E2B template contains only source and pinned dependencies. It contains no
|
|
34
35
|
credentials and no Agent start command.
|
|
35
36
|
3. The sandbox receives `OPENAI_API_KEY` and `ORY_*` only in the Agent command's
|
|
@@ -41,7 +42,7 @@ Never print, inspect, commit, upload, or place in a prompt:
|
|
|
41
42
|
|
|
42
43
|
- `OPENAI_API_KEY` or `E2B_API_KEY`
|
|
43
44
|
- `ORY_AGENT_API_KEY`
|
|
44
|
-
- any
|
|
45
|
+
- any streamed deployment credential value
|
|
45
46
|
- a user OAuth2 token
|
|
46
47
|
|
|
47
48
|
Never inject `ORY_USER_OAUTH2_TOKEN` into E2B. The deployment package is a complete
|
|
@@ -222,22 +223,28 @@ package_recipe_version: v1
|
|
|
222
223
|
credential_method: talos_api_key
|
|
223
224
|
```
|
|
224
225
|
|
|
225
|
-
Review the plan. Then
|
|
226
|
+
Review the plan. Then let the CLI create a fresh deployment and launch the
|
|
227
|
+
trusted E2B controller:
|
|
226
228
|
|
|
227
229
|
```bash
|
|
228
|
-
ory-agent deployment
|
|
230
|
+
ory-agent deployment run \
|
|
231
|
+
--result-file "$RUNNER_TEMP/ory-agent-result.json" \
|
|
232
|
+
-- trusted-e2b-controller --credentials-stdin
|
|
229
233
|
```
|
|
230
234
|
|
|
231
|
-
The CLI
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
credential
|
|
236
|
-
|
|
235
|
+
The CLI sends credentials only through the child process's anonymous stdin,
|
|
236
|
+
never public stdout, a shell variable, log, or intermediate file. It strips
|
|
237
|
+
deployment-administration credentials from the child environment. The atomic
|
|
238
|
+
mode-`0600` result contains the non-secret new deployment ID. `run` writes no
|
|
239
|
+
credential, state, pending journal, plaintext stage, or age identity. It waits
|
|
240
|
+
for **Active** after the controller succeeds and automatically revokes on every
|
|
241
|
+
normal success or failure path. A failed revoke fails the command. Process
|
|
242
|
+
termination before cleanup can still orphan a deployment, so inventory and
|
|
243
|
+
explicitly revoke it rather than assuming a rerun will recover it.
|
|
237
244
|
|
|
238
245
|
## Launch through the trusted controller
|
|
239
246
|
|
|
240
|
-
Load
|
|
247
|
+
Load credential stdin into a validated in-memory map without logging it. Require
|
|
241
248
|
exactly the deployment variables emitted by Agent Security, including
|
|
242
249
|
`ORY_AGENT_API_KEY`, `ORY_AGENT_SUBJECT_ID`, and `ORY_AGENT_ROOT_DELEGATION`. Add
|
|
243
250
|
`OPENAI_API_KEY` only to the Agent command environment.
|
|
@@ -271,9 +278,8 @@ runtime request. Therefore use this order:
|
|
|
271
278
|
1. Launch a canary sandbox from the immutable build.
|
|
272
279
|
2. Run the fixed guarded probe inside it with command-scoped credentials.
|
|
273
280
|
3. Verify the expected output files exist without dumping process environment.
|
|
274
|
-
4. Run
|
|
275
|
-
5.
|
|
276
|
-
6. Run the user's page-generation prompt and validate the static output.
|
|
281
|
+
4. Run the user's page-generation prompt and validate the static output.
|
|
282
|
+
5. Exit successfully so `ory-agent deployment run` verifies **Active** and revokes.
|
|
277
283
|
|
|
278
284
|
Start in Agent Security `observe`, review the recorded decision and activity, grant the
|
|
279
285
|
expected tool, deliberately promote policy to `enforce`, and prove an explicit deny keeps
|
package/dist/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repo": "ory-agent-plugins",
|
|
3
|
-
"commit": "
|
|
4
|
-
"commitShort": "
|
|
3
|
+
"commit": "6c598d14487dbc18be2d815b2014776642150ca0",
|
|
4
|
+
"commitShort": "6c598d1",
|
|
5
5
|
"branch": "main",
|
|
6
|
-
"commitDate": "2026-10-
|
|
6
|
+
"commitDate": "2026-10-02T18:32:54-07:00",
|
|
7
7
|
"dirty": false,
|
|
8
|
-
"builtAt": "2026-10-
|
|
8
|
+
"builtAt": "2026-10-03T01:37:16.649Z"
|
|
9
9
|
}
|
package/dist/client.js
CHANGED
|
@@ -44,6 +44,7 @@ const agent_auth_js_1 = require("./agent-auth.js");
|
|
|
44
44
|
const context_js_1 = require("./context.js");
|
|
45
45
|
const config_js_1 = require("./config.js");
|
|
46
46
|
const auth_store_js_1 = require("./auth-store.js");
|
|
47
|
+
const subject_js_1 = require("./subject.js");
|
|
47
48
|
const runtime_credential_js_1 = require("./runtime-credential.js");
|
|
48
49
|
const BROKER_PERMISSION_BATCH_SIZE = 10;
|
|
49
50
|
function permissionCheckFromRequest(request) {
|
|
@@ -261,7 +262,13 @@ class OryAgentClient {
|
|
|
261
262
|
|| this.config.userSubjectNamespace
|
|
262
263
|
|| "User";
|
|
263
264
|
if (subject.namespace === ownerNamespace) {
|
|
264
|
-
|
|
265
|
+
const userSubject = this.userPrincipal.subject;
|
|
266
|
+
if (subject.object === userSubject) {
|
|
267
|
+
return { kind: "owner", namespace: subject.namespace };
|
|
268
|
+
}
|
|
269
|
+
// A preprovisioned runtime with no local user: the broker derives the
|
|
270
|
+
// owner from the authenticated runtime, and no owner ID is sent.
|
|
271
|
+
if (userSubject === undefined && subject.object === subject_js_1.RUNTIME_OWNER_SUBJECT && this._runtimeContext) {
|
|
265
272
|
return { kind: "owner", namespace: subject.namespace };
|
|
266
273
|
}
|
|
267
274
|
throw httpError(403, "Permission owner does not match the authenticated user");
|
package/dist/event-reporter.d.ts
CHANGED
|
@@ -43,7 +43,12 @@ export declare class AgentSecurityEventReporter {
|
|
|
43
43
|
private scheduled;
|
|
44
44
|
private activeRequest;
|
|
45
45
|
private flushDeadline;
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Set when a flush deadline passes. The current delivery stops starting new
|
|
48
|
+
* requests so a short-lived hook process can exit on time; undelivered events
|
|
49
|
+
* stay queued (and in the durable outbox) for a later delivery.
|
|
50
|
+
*/
|
|
51
|
+
private flushExpired;
|
|
47
52
|
private retryTimer;
|
|
48
53
|
private retryAttempt;
|
|
49
54
|
private readonly retryBaseMs;
|
|
@@ -56,6 +61,11 @@ export declare class AgentSecurityEventReporter {
|
|
|
56
61
|
enqueue(entry: ActivityEntry, principalKey?: string): void;
|
|
57
62
|
/** Attempt all currently deliverable batches, bounded by the caller's deadline. */
|
|
58
63
|
flush(timeoutMs?: number): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* The request timeout shares the flush deadline and can abort a request before
|
|
66
|
+
* the flush timer fires, so check the deadline itself as well as the flag.
|
|
67
|
+
*/
|
|
68
|
+
private flushDeadlinePassed;
|
|
59
69
|
private schedule;
|
|
60
70
|
private startDelivery;
|
|
61
71
|
private scheduleRetry;
|
package/dist/event-reporter.js
CHANGED
|
@@ -99,7 +99,12 @@ class AgentSecurityEventReporter {
|
|
|
99
99
|
scheduled = false;
|
|
100
100
|
activeRequest;
|
|
101
101
|
flushDeadline;
|
|
102
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Set when a flush deadline passes. The current delivery stops starting new
|
|
104
|
+
* requests so a short-lived hook process can exit on time; undelivered events
|
|
105
|
+
* stay queued (and in the durable outbox) for a later delivery.
|
|
106
|
+
*/
|
|
107
|
+
flushExpired = false;
|
|
103
108
|
retryTimer;
|
|
104
109
|
retryAttempt = 0;
|
|
105
110
|
retryBaseMs;
|
|
@@ -173,7 +178,7 @@ class AgentSecurityEventReporter {
|
|
|
173
178
|
work,
|
|
174
179
|
new Promise((resolve) => {
|
|
175
180
|
timer = setTimeout(() => {
|
|
176
|
-
this.
|
|
181
|
+
this.flushExpired = true;
|
|
177
182
|
this.activeRequest?.abort();
|
|
178
183
|
resolve();
|
|
179
184
|
}, timeoutMs);
|
|
@@ -185,6 +190,13 @@ class AgentSecurityEventReporter {
|
|
|
185
190
|
if (this.flushDeadline === deadline)
|
|
186
191
|
this.flushDeadline = undefined;
|
|
187
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* The request timeout shares the flush deadline and can abort a request before
|
|
195
|
+
* the flush timer fires, so check the deadline itself as well as the flag.
|
|
196
|
+
*/
|
|
197
|
+
flushDeadlinePassed() {
|
|
198
|
+
return this.flushExpired || (this.flushDeadline !== undefined && Date.now() >= this.flushDeadline);
|
|
199
|
+
}
|
|
188
200
|
schedule() {
|
|
189
201
|
if (this.scheduled || this.delivery)
|
|
190
202
|
return;
|
|
@@ -207,7 +219,7 @@ class AgentSecurityEventReporter {
|
|
|
207
219
|
void work.finally(() => {
|
|
208
220
|
if (this.delivery === work)
|
|
209
221
|
this.delivery = undefined;
|
|
210
|
-
this.
|
|
222
|
+
this.flushExpired = false;
|
|
211
223
|
if (this.queue.length === 0)
|
|
212
224
|
this.retryAttempt = 0;
|
|
213
225
|
else if (shouldRetry)
|
|
@@ -236,6 +248,8 @@ class AgentSecurityEventReporter {
|
|
|
236
248
|
this.prune();
|
|
237
249
|
const retainedScopes = new Set();
|
|
238
250
|
while (this.queue.length > 0) {
|
|
251
|
+
if (this.flushDeadlinePassed())
|
|
252
|
+
return true;
|
|
239
253
|
const first = this.queue.find((pending) => !retainedScopes.has(scopeKey(pendingScope(pending))));
|
|
240
254
|
if (!first)
|
|
241
255
|
return shouldRetry;
|
|
@@ -280,6 +294,10 @@ class AgentSecurityEventReporter {
|
|
|
280
294
|
const remove = new Set();
|
|
281
295
|
let retry = false;
|
|
282
296
|
for (const event of batch) {
|
|
297
|
+
if (this.flushDeadlinePassed()) {
|
|
298
|
+
retry = true;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
283
301
|
const isolated = await this.deliver([event], scope);
|
|
284
302
|
for (const eventId of isolated.remove)
|
|
285
303
|
remove.add(eventId);
|
package/dist/subject.d.ts
CHANGED
|
@@ -23,6 +23,14 @@ import type { OryAgentClient } from "./client.js";
|
|
|
23
23
|
* provisioning all use `User`, so it is the out-of-the-box default.
|
|
24
24
|
*/
|
|
25
25
|
export declare const DEFAULT_USER_SUBJECT_NAMESPACE = "User";
|
|
26
|
+
/**
|
|
27
|
+
* Owner object for a preprovisioned runtime (a Talos, SPIFFE or mTLS agent
|
|
28
|
+
* deployment) that has no local user principal. The client never knows that
|
|
29
|
+
* owner's identity; the broker derives it from the authenticated runtime, so
|
|
30
|
+
* this object is only ever sent as `{ kind: "owner" }`. It is not a UUID, so it
|
|
31
|
+
* cannot collide with a real identity ID.
|
|
32
|
+
*/
|
|
33
|
+
export declare const RUNTIME_OWNER_SUBJECT = "runtime-owner";
|
|
26
34
|
/** Namespace the agent principal is addressed under (delegation subjects). */
|
|
27
35
|
export declare const AGENT_NAMESPACE = "Agent";
|
|
28
36
|
/** Namespace a sub-agent principal is addressed under. */
|
|
@@ -53,7 +61,8 @@ export declare function runWithUserSubject<T>(subject: string | undefined, fn: (
|
|
|
53
61
|
* Resolve the user subject for permission checks. Prefers a per-call
|
|
54
62
|
* override installed via {@link runWithUserSubject}, then the user
|
|
55
63
|
* login's `userPrincipal.subject`, falls back to `ORY_USER_SUBJECT_ID`, then the
|
|
56
|
-
* legacy `ORY_AGENT_SUBJECT_ID`, then the
|
|
64
|
+
* legacy `ORY_AGENT_SUBJECT_ID`, then the deployment owner of a preprovisioned
|
|
65
|
+
* runtime ({@link RUNTIME_OWNER_SUBJECT}), then the caller-supplied `fallback`
|
|
57
66
|
* (typically `session:<id>`).
|
|
58
67
|
*
|
|
59
68
|
* Always returns a SubjectSet. A resolved principal is addressed under the
|
package/dist/subject.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* toggles between SubjectSet and a legacy direct SubjectID.
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.AGENT_SUBJECT_ID_ENV_VAR = exports.SUBJECT_AXIS_SEPARATOR = exports.SESSION_NAMESPACE = exports.SUBAGENT_NAMESPACE = exports.AGENT_NAMESPACE = exports.DEFAULT_USER_SUBJECT_NAMESPACE = void 0;
|
|
21
|
+
exports.AGENT_SUBJECT_ID_ENV_VAR = exports.SUBJECT_AXIS_SEPARATOR = exports.SESSION_NAMESPACE = exports.SUBAGENT_NAMESPACE = exports.AGENT_NAMESPACE = exports.RUNTIME_OWNER_SUBJECT = exports.DEFAULT_USER_SUBJECT_NAMESPACE = void 0;
|
|
22
22
|
exports.runWithUserSubject = runWithUserSubject;
|
|
23
23
|
exports.resolveUserSubject = resolveUserSubject;
|
|
24
24
|
exports.subjectLabel = subjectLabel;
|
|
@@ -35,6 +35,14 @@ const node_async_hooks_1 = require("node:async_hooks");
|
|
|
35
35
|
* provisioning all use `User`, so it is the out-of-the-box default.
|
|
36
36
|
*/
|
|
37
37
|
exports.DEFAULT_USER_SUBJECT_NAMESPACE = "User";
|
|
38
|
+
/**
|
|
39
|
+
* Owner object for a preprovisioned runtime (a Talos, SPIFFE or mTLS agent
|
|
40
|
+
* deployment) that has no local user principal. The client never knows that
|
|
41
|
+
* owner's identity; the broker derives it from the authenticated runtime, so
|
|
42
|
+
* this object is only ever sent as `{ kind: "owner" }`. It is not a UUID, so it
|
|
43
|
+
* cannot collide with a real identity ID.
|
|
44
|
+
*/
|
|
45
|
+
exports.RUNTIME_OWNER_SUBJECT = "runtime-owner";
|
|
38
46
|
/** Namespace the agent principal is addressed under (delegation subjects). */
|
|
39
47
|
exports.AGENT_NAMESPACE = "Agent";
|
|
40
48
|
/** Namespace a sub-agent principal is addressed under. */
|
|
@@ -72,7 +80,8 @@ function subjectSet(namespace, object) {
|
|
|
72
80
|
* Resolve the user subject for permission checks. Prefers a per-call
|
|
73
81
|
* override installed via {@link runWithUserSubject}, then the user
|
|
74
82
|
* login's `userPrincipal.subject`, falls back to `ORY_USER_SUBJECT_ID`, then the
|
|
75
|
-
* legacy `ORY_AGENT_SUBJECT_ID`, then the
|
|
83
|
+
* legacy `ORY_AGENT_SUBJECT_ID`, then the deployment owner of a preprovisioned
|
|
84
|
+
* runtime ({@link RUNTIME_OWNER_SUBJECT}), then the caller-supplied `fallback`
|
|
76
85
|
* (typically `session:<id>`).
|
|
77
86
|
*
|
|
78
87
|
* Always returns a SubjectSet. A resolved principal is addressed under the
|
|
@@ -94,6 +103,11 @@ function resolveUserSubject(client, fallback) {
|
|
|
94
103
|
|| exports.DEFAULT_USER_SUBJECT_NAMESPACE;
|
|
95
104
|
if (principal)
|
|
96
105
|
return subjectSet(ns, principal);
|
|
106
|
+
// A preprovisioned runtime acts for its deployment's owner, whom only the
|
|
107
|
+
// broker knows. Without this, a headless deployment resolves no subject and
|
|
108
|
+
// every native tool is denied in enforce mode (#338).
|
|
109
|
+
if (client.runtimeContext)
|
|
110
|
+
return subjectSet(ns, exports.RUNTIME_OWNER_SUBJECT);
|
|
97
111
|
// No principal — use the caller's fallback. A `session:<id>` fallback is
|
|
98
112
|
// addressed under the Session namespace so it is a well-formed SubjectSet that
|
|
99
113
|
// could match a Session-scoped grant, rather than being wrapped under `User`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
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",
|