@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 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 asks how you want to connect — **press Enter for the default**:
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 "ory-agent-plugin" \
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, --user-login, --audit-only)
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. Turn on the interactive user login (opt-in):");
335
- console.log(" export ORY_USER_LOGIN=true");
336
- console.log(" Without this, Codex runs without a human Ory identity attached to the");
337
- console.log(" session and permission checks fall back to a session:<id> subject.");
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
- const decision = await userGate(client, {
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.13.9",
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.13.9"
70
+ "@ory/argus": "0.14.0"
71
71
  },
72
72
  "engines": {
73
73
  "node": ">=22"