@ory/goose 0.11.1 → 0.12.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
@@ -1,112 +1,145 @@
1
1
  # Ory Agent Plugin: Goose
2
2
 
3
- [Ory](https://ory.com) bundled into [Goose](https://github.com/block/goose) (Block's open-source coding agent): skills that scaffold Ory authentication into your codebase, a local Ory stack you can spin up in one command, and (when pointed at an Ory project) authentication, authorization, and audit for every tool Goose runs.
3
+ Security and developer experience for [Goose](https://github.com/block/goose) (Block's open-source coding agent), powered by [Ory](https://ory.com).
4
4
 
5
- You don't need an Ory account or any prior Ory experience to start.
5
+ **Security.** Goose runs real actions on your machine — editing files, running shell commands, calling APIs. The plugin gives every session a verifiable identity (you sign in once; Goose and any sub-agents it spawns each get their own), checks every tool call against permissions you control, and records each decision as an audit trace you can ship to your observability stack. It starts in watch mode so nothing is blocked on day one, and if Ory is ever unreachable it steps aside rather than locking you out.
6
6
 
7
- This integration is verified against the `goose` binary (v1.39.0). The plugin-directory layout, the `hooks.json` schema, and the discovery paths all match the binary's shell-hook plugin contract (see [block/goose#9304](https://github.com/block/goose/pull/9304)).
7
+ **Developer experience.** A single command installs the plugin and walks you through connecting — choose Ory Network, a local Docker stack, or audit-only, and it wires up the project, sign-in client, login, and permissions for you. It also helps you build Ory into your own app: ask in plain language to scaffold login, registration, and recovery pages, run a local Ory, or manage identities and permissions through the bundled MCP server.
8
8
 
9
- ## New to Ory?
9
+ Verified against the `goose` binary (v1.39.0): the plugin layout, the `hooks.json` schema, and the discovery paths all match Goose's shell-hook plugin contract (see [block/goose#9304](https://github.com/block/goose/pull/9304)).
10
10
 
11
- [Ory](https://www.ory.com/docs/) is an open-source identity and access platform — login, registration, sessions, social sign-in, multi-factor auth, and fine-grained permissions, so you don't have to build any of that yourself. Two things make it easy to try with no prior experience:
11
+ ## What you'll need
12
12
 
13
- - **Ory Elements** are prebuilt, themeable UI components for the auth pages. The scaffolding skills wire them into your app for you.
14
- - **The local Ory stack** is a complete Ory running on your laptop in Docker — no account, no signup, no API key.
13
+ - [Goose](https://github.com/block/goose), installed
14
+ - Node.js **22 or newer**
15
+ - [Docker](https://docs.docker.com/get-docker/) — only if you want to run Ory locally
16
+ - macOS or Linux (Windows works via WSL2)
15
17
 
16
- ## What this plugin does
18
+ ## Get started
17
19
 
18
- Two independent things, and you can use either on its own:
20
+ Run one command. It installs the plugin and walks you through connecting:
19
21
 
20
- 1. **Build auth into your app.** Have Goose scaffold Ory login, registration, social sign-in, and permissions into the project you're working on, backed by the local stack. This needs nothing but Docker.
21
- 2. **Govern the agent itself.** Authenticate Goose's own session and authorize every tool it runs against Ory Permissions, with a full audit trail. See [Agent security](#agent-security).
22
+ ```bash
23
+ npx -y -p @ory/goose ory-goose install
24
+ ```
22
25
 
23
- ## Prerequisites
26
+ The installer drops a self-contained plugin at `<project>/.agents/plugins/ory/`, where Goose finds it on its own at startup — no `goose configure` step and nothing else in your Goose config gets touched. Then it asks how you want to connect — **press Enter for the default**:
24
27
 
25
- - [Goose](https://github.com/block/goose) installed
26
- - Node.js **≥ 22**
27
- - [Docker](https://docs.docker.com/get-docker/) (only needed for the local Ory stack)
28
- - macOS or Linux. Windows works via WSL2.
28
+ - **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.
29
+ - **Local** — run a complete Ory on your laptop with Docker. No account, no signup, no keys. Great for trying it out.
30
+ - **Audit-only** skip Ory entirely and just log what Goose does.
29
31
 
30
- ## Install
32
+ That's it. Confirm everything landed with:
31
33
 
32
34
  ```bash
33
- npx -y -p @ory/goose ory-goose install
35
+ npx -y -p @ory/goose ory-goose status
34
36
  ```
35
37
 
36
- This is the simplest install of any harness in this repo: it drops a self-contained plugin tree at `<project>/.agents/plugins/ory/` (or `~/.agents/plugins/ory/` with `--global`) a `plugin.json` manifest plus `hooks/hooks.json` and the Ory skills. **No config mutation, no MCP registration, no `goose configure` step.** Goose auto-discovers the plugin directory at startup.
38
+ `status` is your one-stop check: what's configured, who's signed in, which tools are covered by permissions, whether the plugin is registered (project and global), and recent activity.
37
39
 
38
- ```bash
39
- npx -y -p @ory/goose ory-goose install --global # install for all projects
40
- npx -y -p @ory/goose ory-goose status # confirm what landed
41
- npx -y -p @ory/goose ory-goose uninstall # remove the ory plugin dir
42
- ```
40
+ Re-run install with `--reconfigure` to change your connection later, `--no-configure` to skip the wizard, or `--global` to install for every project (at `~/.agents/plugins/ory/`).
43
41
 
44
- `status` prints configuration, user and agent identity, per-tool permission coverage, plugin registration (project + global), and a tail of recent debug logs.
42
+ ## What you get
45
43
 
46
- ## Quickstart (≈ 3 minutes)
44
+ Once connected, every tool Goose runs is governed by Ory — three things happen automatically:
47
45
 
48
- From any project where you'd like Ory authentication, inside Goose:
46
+ - **Who's driving.** You sign in once in your browser (a standard, secure browser login); Goose gets its own separate identity and registers it automatically on first run. No tokens to copy around, and the "who did what" trail stays queryable later.
47
+ - **What it's allowed to do.** Before a tool runs, Ory checks whether it's permitted. It starts in **watch mode** — nothing is blocked, you just *see* what would be — so it never gets in your way on day one.
48
+ - **A record of everything.** Every decision (allowed, denied, skipped) is logged as a trace you can send to Jaeger, Honeycomb, Grafana, or just a file.
49
49
 
50
- 1. **Start a local Ory instance.** Ask Goose *"start the local Ory stack"* or invoke the `ory-local-up` skill. A banner prints the seeded test user's email and passwordnote them.
51
- 2. **Scaffold Ory into your project.** Ask Goose *"add Ory auth to this app"* (the `ory-auth-setup` skill). It installs Ory Elements, wires the SDK, and generates the login / registration / recovery / settings pages, all targeting the local stack.
52
- 3. **Sign in.** Start your app, visit the login page, and sign in with the seeded credentials. You now have a real Ory session backed by a real Ory stack — locally, offline, zero configuration.
50
+ Under the hood, Goose runs the plugin as a small program for each thing it does, handing it the event and reading back a decision. The `hooks.json` file maps that: **SessionStart** signs you in, **PreToolUse** (the one point that can block) runs the permission check, and the rest **PostToolUse, BeforeReadFile, AfterFileEdit, BeforeShellExecution, Stop, SessionEnd** — just record activity. If Ory is ever unreachable, the plugin gets out of the way and lets Goose keep working, so it can't lock you out.
53
51
 
54
- Continue to [Agent security](#agent-security) when you're ready to enforce.
52
+ ### See what's happening
55
53
 
56
- ## How the integration works
54
+ Everything the plugin does is observable out of the box — no configuration required:
57
55
 
58
- Goose discovers external **shell-hook plugins** by directory and invokes the hook binary as a subprocess for each lifecycle event (Claude-Code-style: event payload as JSON on stdin, decision on stdout). A hook blocks a tool call by returning `{"action":"block","message":"…"}` (the `RawHookAction` shape); the plugin also exits with code 2 as a defensive secondary block signal.
56
+ - **Status at a glance.** `npx -y -p @ory/goose ory-goose status` shows what's configured, who's signed in, how many built-in tools your permissions cover, and the most recent tool-call activity.
57
+ - **Live traces.** Every tool call is recorded as an OpenTelemetry-style span. Watch them stream as the agent works:
59
58
 
60
- The `hooks.json` maps these phases to the Ory hook:
59
+ ```bash
60
+ npx -y -p @ory/goose ory-goose watch
61
+ ```
61
62
 
62
- - **SessionStart**run the user and agent auth gates.
63
- - **PreToolUse** the only blocking event; check the tool against Ory Permissions, deny blocks in enforce mode.
64
- - **PostToolUse / BeforeReadFile / AfterFileEdit / BeforeShellExecution / Stop / SessionEnd** — trace-only audit spans.
63
+ Spans are also written to `~/.config/ory-agent-plugins/goose/ory-agent-trace.ndjson` (NDJSON, one span per line) tail that file, or point `OTEL_EXPORTER_OTLP_ENDPOINT` at a collector to ship them straight to Jaeger, Honeycomb, or Grafana.
64
+ - **Debug log.** For a verbose play-by-play, set `ORY_AGENT_DEBUG=true`; structured logs land in `~/.config/ory-agent-plugins/goose/ory-agent-debug.log`.
65
65
 
66
- The plugin is **fail-open** on its own infrastructure failures (network errors, rate limits, missing config): the agent always starts, and enforcement is only as strong as your permission grants.
66
+ ### Ready to enforce?
67
67
 
68
- ## Agent security
68
+ When the watch-mode logs look right, turn on blocking with one command (setup already granted you the built-in tools):
69
69
 
70
- Once pointed at an Ory project (local or hosted), Goose's session and every tool call can be governed by Ory.
70
+ ```bash
71
+ npx -y -p @ory/goose ory-goose permissions enforce
72
+ ```
71
73
 
72
- - **Authentication.** The human at the keyboard (the **user**) authenticates interactively via Ory Identities when user login is on (`ORY_USER_LOGIN=true`, off by default browser PKCE flow on first session, persisted thereafter). The Goose process (the **agent**) gets its own OAuth2 identity via [Dynamic Client Registration (RFC 7591)](https://datatracker.ietf.org/doc/html/rfc7591) on first run.
73
- - **Authorization.** Before any tool runs, the plugin checks [Ory Permissions](https://www.ory.com/docs/keto) (Zanzibar-style relations) against the user's subject and blocks on `deny`.
74
- - **Audit.** Every decision is recorded as a structured trace span (NDJSON file and/or OTLP export).
74
+ Now a denied tool is actually blocked and Goose 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.
75
75
 
76
- ### Permission modes: observe enforce
76
+ ## Also: add login to your own app
77
77
 
78
- After install the plugin runs in **observe mode**: every tool call is checked, but a deny is recorded as a `permission.observe_deny` audit span and the tool runs anyway.
78
+ Beyond securing Goose, the plugin helps you build Ory into whatever you're working on — backed by a local Ory, so it needs nothing but Docker. Ask Goose in plain language, e.g. *"add Ory auth to this app"*, and it scaffolds the login, registration, recovery, and settings pages (using [Ory Elements](https://github.com/ory/elements)) wired to a local Ory — no signup or keys needed.
79
79
 
80
- ```bash
81
- # Grant the current user `use` on every built-in tool (idempotent):
82
- npx -y -p @ory/goose ory-goose permissions bootstrap
80
+ These are **skills** — vetted playbooks Goose runs when you ask for them in chat. Start a local Ory with the `ory-local-up` skill (it prints a test email + password to sign in with) and tear it down with `ory-local-down`. More skills cover `ory-auth-setup`, `ory-login-flow`, `ory-social-login` (Google, GitHub, Apple…), `ory-permissions-onboarding`, and more.
83
81
 
84
- # See allowed/denied per tool:
85
- npx -y -p @ory/goose ory-goose permissions status
82
+ ## Configure by hand (CI / advanced)
86
83
 
87
- # Turn on hard blocking once the observe-mode logs look right:
88
- npx -y -p @ory/goose ory-goose permissions enforce
84
+ The guided setup covers most people. For scripted or CI setups, or to point at an existing Ory Network project, configure directly. Settings are saved to `~/.config/ory-agent-plugins/config.json` and shared across all your Ory agent plugins; environment variables win when both are set.
85
+
86
+ ```bash
87
+ npx -y -p @ory/goose ory-goose configure \
88
+ --project-url https://<slug>.projects.oryapis.com \
89
+ --oauth2-client-id <sign-in client id> \
90
+ --user-login
89
91
  ```
90
92
 
91
- Switch back any time with `permissions observe`. To disable Ory entirely (audit logging only), run `ory-goose configure --audit-only`.
93
+ Goose'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). Persist the login toggle with `--user-login` / `--no-user-login`, or set it per-session with `ORY_USER_LOGIN=true`. For logging-only with no checks, use `--audit-only`. The matching env vars are `ORY_PROJECT_URL`, `ORY_OAUTH2_CLIENT_ID`, `ORY_USER_LOGIN`, and `ORY_AGENT_API_KEY`.
92
94
 
93
- ## Pointing at a real Ory project
95
+ <details>
96
+ <summary>Create the sign-in client by hand</summary>
94
97
 
95
- The Quickstart uses the local stack. To point at a hosted [Ory Network](https://console.ory.sh) project:
98
+ The guided setup normally does this. To do it yourself, create a **public** OAuth2 client (no secret) listing all four loopback URLs — the plugin tries each in turn so sign-in survives a busy port:
96
99
 
97
100
  ```bash
98
- npx -y -p @ory/goose ory-goose configure \
99
- --project-url https://<id>.projects.oryapis.com \
100
- --oauth2-client-id <public OAuth2 client id>
101
+ ory create oauth2-client --project <project-id> \
102
+ --name "ory-agent-plugin" \
103
+ --grant-type authorization_code,refresh_token \
104
+ --response-type code \
105
+ --scope openid,offline_access \
106
+ --token-endpoint-auth-method none \
107
+ --redirect-uri http://127.0.0.1:47823/callback \
108
+ --redirect-uri http://127.0.0.1:47824/callback \
109
+ --redirect-uri http://127.0.0.1:47825/callback \
110
+ --redirect-uri http://127.0.0.1:47826/callback
101
111
  ```
102
112
 
103
- `--oauth2-client-id` is required whenever `--project-url` is set — the user PKCE flow needs a public OAuth2 client registered with the four loopback redirect URIs (`http://127.0.0.1:47823..47826/callback`). See the [repo README](../../README.md) and [`AGENTS.md`](../../AGENTS.md) for the full environment-variable reference and permission-mode semantics. Config is shared across every Ory agent plugin at `~/.config/ory-agent-plugins/config.json`.
113
+ Pass the resulting id to `configure --oauth2-client-id`. Running headless with a session token already? Set `ORY_USER_SESSION_TOKEN` and skip the browser step entirely.
114
+
115
+ </details>
116
+
117
+ With nothing configured, the plugin still loads and runs in **pass-through mode**: skills and logging work, but no checks run and nothing is blocked. Perfectly fine if you only want the app-building features.
118
+
119
+ ## Commands
120
+
121
+ ```
122
+ ory-goose install | uninstall Install/remove; --reconfigure re-runs setup, --no-configure skips it, --global installs everywhere
123
+ ory-goose status Show configuration, identities, permission coverage, registration, recent activity
124
+ ory-goose watch Tail the live trace stream (OTel spans)
125
+ ory-goose permissions <cmd> status | bootstrap | observe (watch) | enforce (block)
126
+ ory-goose configure <flags> Point at a project by hand (--project-url, --oauth2-client-id, --user-login, --audit-only)
127
+ ory-goose agent <status|unregister> Manage Goose's own auto-created identity
128
+ ```
129
+
130
+ All prefixed with `npx -y -p @ory/goose`.
131
+
132
+ ## Troubleshooting
104
133
 
105
- Without configuration the plugin still loads cleanly and runs in **pass-through mode**: skills work, but nothing is blocked.
134
+ - **The local Ory fails to start** make sure Docker is running and ports `4000`, `4100`, `4455`, and `16686` are free.
135
+ - **Browser sign-in loops** — reset with `ory-goose agent unregister` and try again.
136
+ - **`npx` grabbed an old version** — force the latest: `npx -y -p @ory/goose@latest ory-goose …`.
137
+ - **Goose isn't picking up the plugin** — confirm the tree at `<project>/.agents/plugins/ory/` exists (or re-run the installer), and restart Goose.
138
+ - **Want to see what's happening** — `npx -y -p @ory/goose ory-goose status` for a snapshot, `npx -y -p @ory/goose ory-goose watch` for the live trace stream, or set `ORY_AGENT_DEBUG=true` for a verbose log. Traces and logs live under `~/.config/ory-agent-plugins/goose/` (see [See what's happening](#see-whats-happening)).
106
139
 
107
- ## Links
140
+ ## Learn more
108
141
 
109
- - [Ory documentation](https://www.ory.com/docs/)
142
+ - [Ory documentation](https://www.ory.com/docs/) · [Ory Console](https://console.ory.sh) · [Ory Elements](https://github.com/ory/elements)
110
143
  - [Goose repository](https://github.com/block/goose)
111
144
  - [Repo README](../../README.md) and [AGENTS.md](../../AGENTS.md) — full env-var and permission-mode reference
112
145
 
package/dist/cli/main.js CHANGED
@@ -58,14 +58,19 @@ function main() {
58
58
  const [command, ...args] = process.argv.slice(2);
59
59
  switch (command) {
60
60
  case "install":
61
+ (0, argus_1.beginDeferNextSteps)();
61
62
  install(args);
62
- postInstallPermissions("ory-goose", "goose").then(() => process.exit(0), (err) => {
63
+ (0, argus_1.runPostInstall)("ory-goose", "goose", args).then(() => process.exit(0), (err) => {
63
64
  console.error(err.message ?? err);
64
65
  process.exit(1);
65
66
  });
66
67
  break;
67
68
  case "uninstall":
68
69
  uninstall(args);
70
+ (0, argus_1.clearCredentialsForUninstall)().then(() => process.exit(0), (err) => {
71
+ console.error(err.message ?? err);
72
+ process.exit(1);
73
+ });
69
74
  break;
70
75
  case "configure":
71
76
  (0, argus_1.runConfigureCommand)("ory-goose", args);
@@ -97,6 +102,9 @@ function main() {
97
102
  process.exit(1);
98
103
  });
99
104
  break;
105
+ case "watch":
106
+ (0, argus_1.runWatchCommand)("goose", args);
107
+ break;
100
108
  case "help":
101
109
  case "--help":
102
110
  case "-h":
@@ -118,12 +126,6 @@ function uninstall(_args) {
118
126
  const setupArgs = (0, argus_1.parseSetupArgs)({ supportsGlobal: true });
119
127
  (0, setup_js_1.runSetup)({ ...setupArgs, uninstall: true });
120
128
  }
121
- async function postInstallPermissions(binName, harness) {
122
- const bootstrapped = await (0, argus_1.maybeAutoBootstrap)(binName, harness);
123
- (0, argus_1.printPermissionsOnboardingHelp)(binName, harness, {
124
- bootstrappedAutomatically: bootstrapped,
125
- });
126
- }
127
129
  function pluginRoots() {
128
130
  return {
129
131
  project: path.join(process.cwd(), ".agents", "plugins", PLUGIN_NAME),
@@ -152,7 +154,7 @@ function help() {
152
154
  ory-goose — Ory plugin for Goose
153
155
 
154
156
  Usage:
155
- npx ory-goose <command> [options]
157
+ npx -y -p @ory/goose ory-goose <command> [options]
156
158
 
157
159
  Commands:
158
160
  install [--global] Install the Ory plugin (project-local, or --global)
@@ -162,6 +164,7 @@ Commands:
162
164
  permissions <cmd> Manage permission mode and tool permissions (status, bootstrap, observe, enforce)
163
165
  setup [--project-dir] Write the plugin tree directly (advanced)
164
166
  status Show plugin status and configuration
167
+ watch [trace-file] Tail the trace stream (OTel spans) live
165
168
  local <cmd> Manage local Ory dev environment (up, down, status, seed, ...)
166
169
 
167
170
  After installing, Goose auto-discovers the plugin and hooks into these
@@ -171,10 +174,10 @@ lifecycle events:
171
174
  PostToolUse Audit log tool executions
172
175
 
173
176
  Examples:
174
- npx ory-goose install # Install into ./.agents/plugins/ory
175
- npx ory-goose install --global # Install into ~/.agents/plugins/ory
176
- npx ory-goose status # Check configuration
177
- npx ory-goose uninstall # Remove the plugin
177
+ npx -y -p @ory/goose ory-goose install # Install into ./.agents/plugins/ory
178
+ npx -y -p @ory/goose ory-goose install --global # Install into ~/.agents/plugins/ory
179
+ npx -y -p @ory/goose ory-goose status # Check configuration
180
+ npx -y -p @ory/goose ory-goose uninstall # Remove the plugin
178
181
  `);
179
182
  }
180
183
  main();
package/dist/cli/setup.js CHANGED
@@ -158,7 +158,10 @@ function runSetup(args) {
158
158
  writePluginTree(pluginRoot, version);
159
159
  console.log(`Ory plugin installed to ${pluginRoot}`);
160
160
  console.log(` plugin.json + hooks/hooks.json + skills/ written.`);
161
- (0, argus_1.printNextSteps)("Goose", "npx ory-goose-setup --uninstall");
161
+ (0, argus_1.printNextSteps)("Goose", "npx -y -p @ory/goose ory-goose-setup --uninstall", {
162
+ binName: "ory-goose",
163
+ harness: "goose",
164
+ });
162
165
  }
163
166
  function main() {
164
167
  if (process.argv.includes("--help") || process.argv.includes("-h")) {
@@ -170,4 +173,12 @@ function main() {
170
173
  }
171
174
  if (require.main === module) {
172
175
  main();
176
+ // Direct `-setup --uninstall` path: also clear stored Ory credentials.
177
+ // (The `ory-goose uninstall` command handles this itself.)
178
+ if (process.argv.includes("--uninstall")) {
179
+ (0, argus_1.clearCredentialsForUninstall)().then(() => process.exit(0), (err) => {
180
+ console.error(err.message ?? err);
181
+ process.exit(1);
182
+ });
183
+ }
173
184
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ory/goose",
3
- "version": "0.11.1",
3
+ "version": "0.12.0",
4
4
  "description": "Ory plugin for Goose (Block's open-source agent CLI): 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",
@@ -66,7 +66,7 @@
66
66
  "!dist/**/*.tsbuildinfo"
67
67
  ],
68
68
  "dependencies": {
69
- "@ory/argus": "0.11.1"
69
+ "@ory/argus": "0.12.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "typescript": "^6.0.2",