@ory/codex 0.13.9 → 0.14.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 +10 -7
- package/dist/cli/main.js +7 -0
- package/dist/cli/setup.js +5 -5
- package/dist/handlers.js +5 -77
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,12 +21,14 @@ Run one command. It installs the plugin and walks you through connecting:
|
|
|
21
21
|
npx -y -p @ory/codex ory-codex install
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
This registers the Ory plugin with Codex (hooks, skills, and a bundled Ory tool server) and then
|
|
24
|
+
This registers the Ory plugin with Codex (hooks, skills, and a bundled Ory tool server) and then opens a guided setup **in your browser** where you pick how to connect — the default takes just a click:
|
|
25
25
|
|
|
26
26
|
- **Ory Network** *(default)* — sign in, or create a free account, in your browser. The project, keys, permissions, and login are all set up for you. Nothing to configure by hand.
|
|
27
27
|
- **Local** — run a complete Ory on your laptop with Docker. No account, no signup, no keys. Great for trying it out.
|
|
28
28
|
- **Audit-only** — skip Ory entirely and just log what Codex does.
|
|
29
29
|
|
|
30
|
+
> No browser available (CI, SSH, headless)? The same walkthrough runs right in your terminal instead — or force it with `--no-web`.
|
|
31
|
+
|
|
30
32
|
That's it. Confirm everything landed with:
|
|
31
33
|
|
|
32
34
|
```bash
|
|
@@ -54,6 +56,7 @@ If Ory is ever unreachable, the plugin gets out of the way and lets Codex keep w
|
|
|
54
56
|
Everything the plugin does is observable out of the box — no configuration required:
|
|
55
57
|
|
|
56
58
|
- **Status at a glance.** `npx -y -p @ory/codex ory-codex status` shows what's configured, who's signed in, how many built-in tools your permissions cover, and the most recent tool-call activity.
|
|
59
|
+
- **Live dashboard.** `npx -y -p @ory/codex ory-codex dashboard` opens the same picture in your browser — configuration, identities, permission coverage, Ory service health, and the latest tool-call activity, all refreshing live. From there you can flip **enforcement** on or off, toggle **user login**, and use **Change stack** to reconnect to a different Ory — no CLI required.
|
|
57
60
|
- **Live traces.** Every tool call is recorded as an OpenTelemetry-style span. Watch them stream as the agent works:
|
|
58
61
|
|
|
59
62
|
```bash
|
|
@@ -71,7 +74,7 @@ When the watch-mode logs look right, turn on blocking with one command (setup al
|
|
|
71
74
|
npx -y -p @ory/codex ory-codex permissions enforce
|
|
72
75
|
```
|
|
73
76
|
|
|
74
|
-
Now a denied tool is actually blocked and Codex shows why. Go back to watch mode anytime with `permissions observe`. Use `permissions status` to see what's covered and `permissions bootstrap` to (re-)grant the built-in tools — or just ask Codex in chat, e.g. *"grant me use of the shell tool."*
|
|
77
|
+
Now a denied tool is actually blocked and Codex shows why. Go back to watch mode anytime with `permissions observe`. Prefer clicking? The dashboard has the same **Enforce** switch — flip it on, or back to watch mode, without touching the CLI. Use `permissions status` to see what's covered and `permissions bootstrap` to (re-)grant the built-in tools — or just ask Codex in chat, e.g. *"grant me use of the shell tool."*
|
|
75
78
|
|
|
76
79
|
## Also: add login to your own app
|
|
77
80
|
|
|
@@ -86,8 +89,7 @@ The guided setup covers most people. For scripted or CI setups, or to point at a
|
|
|
86
89
|
```bash
|
|
87
90
|
npx -y -p @ory/codex ory-codex configure \
|
|
88
91
|
--project-url https://<slug>.projects.oryapis.com \
|
|
89
|
-
--oauth2-client-id <sign-in client id>
|
|
90
|
-
--user-login
|
|
92
|
+
--oauth2-client-id <sign-in client id>
|
|
91
93
|
```
|
|
92
94
|
|
|
93
95
|
Codex's own identity registers itself automatically on first run — nothing to create. The `--oauth2-client-id` is the one piece browser sign-in needs; the guided setup makes it for you, or see below to do it by hand. For logging-only with no checks, use `--audit-only`.
|
|
@@ -99,7 +101,7 @@ The guided setup normally does this. To do it yourself, create a **public** OAut
|
|
|
99
101
|
|
|
100
102
|
```bash
|
|
101
103
|
ory create oauth2-client --project <project-id> \
|
|
102
|
-
--name "
|
|
104
|
+
--name "Ory Agent Security · user login (PKCE)" \
|
|
103
105
|
--grant-type authorization_code,refresh_token \
|
|
104
106
|
--response-type code \
|
|
105
107
|
--scope openid,offline_access \
|
|
@@ -119,11 +121,12 @@ With nothing configured, the plugin still loads and runs in **pass-through mode*
|
|
|
119
121
|
## Commands
|
|
120
122
|
|
|
121
123
|
```
|
|
122
|
-
ory-codex install | uninstall Install/remove; --reconfigure re-runs setup, --no-configure skips it
|
|
124
|
+
ory-codex install | uninstall Install/remove; --reconfigure re-runs setup, --no-web forces the terminal wizard, --no-configure skips it
|
|
123
125
|
ory-codex status Show configuration, identities, permission coverage, recent activity
|
|
126
|
+
ory-codex dashboard Open the live browser dashboard (status + service health + Change stack)
|
|
124
127
|
ory-codex watch Tail the live trace stream (OTel spans)
|
|
125
128
|
ory-codex permissions <cmd> status | bootstrap | observe (watch) | enforce (block)
|
|
126
|
-
ory-codex configure <flags> Point at a project by hand (--project-url, --oauth2-client-id, --
|
|
129
|
+
ory-codex configure <flags> Point at a project by hand (--project-url, --oauth2-client-id, --audit-only)
|
|
127
130
|
ory-codex agent <status|unregister> Manage Codex's own auto-created identity
|
|
128
131
|
ory-codex local <up|down|status|…> Run / manage a local Ory in Docker
|
|
129
132
|
```
|
package/dist/cli/main.js
CHANGED
|
@@ -99,6 +99,12 @@ function main() {
|
|
|
99
99
|
case "watch":
|
|
100
100
|
(0, argus_1.runWatchCommand)("codex", args);
|
|
101
101
|
break;
|
|
102
|
+
case "dashboard":
|
|
103
|
+
(0, argus_1.runDashboardCommand)("ory-codex", "codex", args).then((code) => process.exit(code), (err) => {
|
|
104
|
+
console.error(err.message ?? err);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
});
|
|
107
|
+
break;
|
|
102
108
|
case "version":
|
|
103
109
|
case "--version":
|
|
104
110
|
case "-v":
|
|
@@ -143,6 +149,7 @@ Commands:
|
|
|
143
149
|
local <cmd> Manage local Ory dev environment
|
|
144
150
|
(up, down, status, seed, logs, env, configure, reset)
|
|
145
151
|
status Show plugin status, config, and recent log lines
|
|
152
|
+
dashboard Open the Ory Agent dashboard (system health + configuration)
|
|
146
153
|
watch [trace-file] Tail the trace stream (OTel spans) live
|
|
147
154
|
version Show version and the ory-agent-plugins build commit
|
|
148
155
|
|
package/dist/cli/setup.js
CHANGED
|
@@ -183,7 +183,7 @@ function renderCommands() {
|
|
|
183
183
|
function hookGroup(timeoutSec) {
|
|
184
184
|
return [
|
|
185
185
|
{
|
|
186
|
-
hooks: [{ type: "command", command: HOOK_COMMAND, timeout: timeoutSec }],
|
|
186
|
+
hooks: [{ type: "command", command: (0, argus_1.pinHookToLocalRegistry)(HOOK_COMMAND), timeout: timeoutSec }],
|
|
187
187
|
},
|
|
188
188
|
];
|
|
189
189
|
}
|
|
@@ -331,10 +331,10 @@ function printNextStepsNow() {
|
|
|
331
331
|
console.log("");
|
|
332
332
|
console.log(" 2. Or spin up the local Ory stack from inside Codex (`/skills` -> `ory-local-up`).");
|
|
333
333
|
console.log("");
|
|
334
|
-
console.log(" 3.
|
|
335
|
-
console.log(" export
|
|
336
|
-
console.log("
|
|
337
|
-
console.log("
|
|
334
|
+
console.log(" 3. Provide the OAuth2 client id for the per-session user login:");
|
|
335
|
+
console.log(" export ORY_OAUTH2_CLIENT_ID=<public OAuth2 client id>");
|
|
336
|
+
console.log(" The user login runs every session; without a client id Codex runs without a");
|
|
337
|
+
console.log(" human Ory identity attached and permission checks fall back to a session:<id> subject.");
|
|
338
338
|
console.log("");
|
|
339
339
|
console.log(" 4. Start a Codex session. Codex treats freshly installed plugin");
|
|
340
340
|
console.log(" hooks as untrusted, so it will prompt you to review and trust");
|
package/dist/handlers.js
CHANGED
|
@@ -59,11 +59,14 @@ async function handleSessionStart(input, client, deps) {
|
|
|
59
59
|
client.tracer.record("session.start", "ok", {
|
|
60
60
|
attributes: { model: input.model },
|
|
61
61
|
});
|
|
62
|
+
// The user login flow runs on every session and never blocks. It refreshes
|
|
63
|
+
// persisted tokens / launches the PKCE login and populates the user
|
|
64
|
+
// principal; enforcement is governed solely by permissionMode at tool-call
|
|
65
|
+
// time.
|
|
62
66
|
const userGate = deps.userLogin ?? argus_1.ensureUserAuthenticated;
|
|
63
|
-
|
|
67
|
+
await userGate(client, {
|
|
64
68
|
binName: "ory-codex",
|
|
65
69
|
harness: "codex",
|
|
66
|
-
allowBlock: true,
|
|
67
70
|
});
|
|
68
71
|
// Resolve the agent identity (machine credentials). Never blocks;
|
|
69
72
|
// attaches the agent's bearer token to outgoing Ory API calls.
|
|
@@ -75,83 +78,8 @@ async function handleSessionStart(input, client, deps) {
|
|
|
75
78
|
// any failure is logged and swallowed (fail-open — delegation tracking is
|
|
76
79
|
// for audit, not enforcement).
|
|
77
80
|
await (0, argus_1.writeUserDelegatesAgent)(client);
|
|
78
|
-
if (!decision.proceed) {
|
|
79
|
-
return { decision: "block", reason: decision.reason };
|
|
80
|
-
}
|
|
81
|
-
if (decision.mode !== "disabled") {
|
|
82
|
-
return {};
|
|
83
|
-
}
|
|
84
|
-
const resolved = (0, argus_1.resolveConfig)();
|
|
85
|
-
if (resolved.auditOnly) {
|
|
86
|
-
client.logger.info("config.audit_only", {
|
|
87
|
-
message: "Audit-only mode enabled. Auth and permission checks are disabled.",
|
|
88
|
-
});
|
|
89
|
-
return {};
|
|
90
|
-
}
|
|
91
|
-
if (!resolved.projectUrl) {
|
|
92
|
-
client.logger.warn("config.not_configured", {
|
|
93
|
-
message: "Ory plugin is not configured. Auth and permission checks are disabled. " +
|
|
94
|
-
"Run 'npx ory-codex configure' to connect to an Ory project.",
|
|
95
|
-
});
|
|
96
|
-
return {};
|
|
97
|
-
}
|
|
98
|
-
// Try session token first, then OAuth2 token
|
|
99
|
-
const sessionToken = process.env.ORY_SESSION_TOKEN;
|
|
100
|
-
const oauth2Token = process.env.ORY_OAUTH2_TOKEN;
|
|
101
|
-
if (sessionToken) {
|
|
102
|
-
await verifySessionToken(sessionToken, client);
|
|
103
|
-
return {};
|
|
104
|
-
}
|
|
105
|
-
if (oauth2Token) {
|
|
106
|
-
await verifyOAuth2Token(oauth2Token, client);
|
|
107
|
-
return {};
|
|
108
|
-
}
|
|
109
|
-
client.logger.warn("session.no_credentials", {
|
|
110
|
-
message: "Neither ORY_SESSION_TOKEN nor ORY_OAUTH2_TOKEN is set. " +
|
|
111
|
-
"Skipping authentication.",
|
|
112
|
-
});
|
|
113
81
|
return {};
|
|
114
82
|
}
|
|
115
|
-
async function verifySessionToken(token, client) {
|
|
116
|
-
try {
|
|
117
|
-
const session = await client.verifySession(token);
|
|
118
|
-
if (!session.active) {
|
|
119
|
-
client.logger.warn("session.inactive", {
|
|
120
|
-
message: "Ory session is not active. Re-authenticate to enable auth checks.",
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
catch (err) {
|
|
125
|
-
const oryErr = err;
|
|
126
|
-
client.logger.warn("session.verify_failed", {
|
|
127
|
-
code: oryErr.code,
|
|
128
|
-
message: oryErr.message,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
async function verifyOAuth2Token(token, client) {
|
|
133
|
-
try {
|
|
134
|
-
const tokenInfo = await client.introspectToken(token);
|
|
135
|
-
if (!tokenInfo.active) {
|
|
136
|
-
client.logger.warn("oauth2.token_inactive", {
|
|
137
|
-
message: "Ory OAuth2 token is not active. Obtain a new token to enable auth checks.",
|
|
138
|
-
});
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
client.logger.info("oauth2.session_authenticated", {
|
|
142
|
-
clientId: tokenInfo.clientId,
|
|
143
|
-
subject: tokenInfo.subject,
|
|
144
|
-
scope: tokenInfo.scope,
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
catch (err) {
|
|
148
|
-
const oryErr = err;
|
|
149
|
-
client.logger.warn("oauth2.introspect_failed", {
|
|
150
|
-
code: oryErr.code,
|
|
151
|
-
message: oryErr.message,
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
83
|
// ─── PreToolUse ─────────────────────────────────────────────────────
|
|
156
84
|
async function handlePreToolUse(input, client) {
|
|
157
85
|
// No default. Codex always sets `tool_name` to the canonical value
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/codex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Ory plugin for Codex: scaffolding skills, a local Ory instance, and authentication, authorization, and audit for every tool call",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ory.com",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
],
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"reo-census": "^1.2.8",
|
|
70
|
-
"@ory/argus": "0.
|
|
70
|
+
"@ory/argus": "0.14.0"
|
|
71
71
|
},
|
|
72
72
|
"engines": {
|
|
73
73
|
"node": ">=22"
|