@ory/argus 0.1.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.
Files changed (80) hide show
  1. package/README.md +134 -0
  2. package/assets/commands/local-down.md +19 -0
  3. package/assets/commands/local-up.md +27 -0
  4. package/assets/skills/auth-setup/SKILL.md +279 -0
  5. package/assets/skills/local-dev/SKILL.md +206 -0
  6. package/assets/skills/login-flow/SKILL.md +383 -0
  7. package/assets/skills/social-login/SKILL.md +312 -0
  8. package/dist/agent-auth.d.ts +204 -0
  9. package/dist/agent-auth.js +553 -0
  10. package/dist/auth-gate.d.ts +71 -0
  11. package/dist/auth-gate.js +308 -0
  12. package/dist/auth-store.d.ts +75 -0
  13. package/dist/auth-store.js +261 -0
  14. package/dist/auth.d.ts +93 -0
  15. package/dist/auth.js +323 -0
  16. package/dist/cli.d.ts +73 -0
  17. package/dist/cli.js +484 -0
  18. package/dist/client.d.ts +158 -0
  19. package/dist/client.js +679 -0
  20. package/dist/config.d.ts +135 -0
  21. package/dist/config.js +344 -0
  22. package/dist/denial.d.ts +79 -0
  23. package/dist/denial.js +103 -0
  24. package/dist/dev.d.ts +95 -0
  25. package/dist/dev.js +514 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.js +137 -0
  28. package/dist/local/cli.d.ts +12 -0
  29. package/dist/local/cli.js +95 -0
  30. package/dist/local/configs.d.ts +89 -0
  31. package/dist/local/configs.js +634 -0
  32. package/dist/local/health.d.ts +32 -0
  33. package/dist/local/health.js +65 -0
  34. package/dist/local/index.d.ts +6 -0
  35. package/dist/local/index.js +38 -0
  36. package/dist/local/jaeger-main.d.ts +13 -0
  37. package/dist/local/jaeger-main.js +85 -0
  38. package/dist/local/jaeger.d.ts +50 -0
  39. package/dist/local/jaeger.js +162 -0
  40. package/dist/local/main.d.ts +7 -0
  41. package/dist/local/main.js +14 -0
  42. package/dist/local/manager.d.ts +45 -0
  43. package/dist/local/manager.js +676 -0
  44. package/dist/local/seed.d.ts +71 -0
  45. package/dist/local/seed.js +237 -0
  46. package/dist/logger.d.ts +29 -0
  47. package/dist/logger.js +139 -0
  48. package/dist/mcp.d.ts +76 -0
  49. package/dist/mcp.js +122 -0
  50. package/dist/otel/exporter.d.ts +17 -0
  51. package/dist/otel/exporter.js +12 -0
  52. package/dist/otel/index.d.ts +2 -0
  53. package/dist/otel/index.js +8 -0
  54. package/dist/otel/otlp-http.d.ts +116 -0
  55. package/dist/otel/otlp-http.js +322 -0
  56. package/dist/registry/cli.d.ts +12 -0
  57. package/dist/registry/cli.js +76 -0
  58. package/dist/registry/config.d.ts +23 -0
  59. package/dist/registry/config.js +80 -0
  60. package/dist/registry/index.d.ts +3 -0
  61. package/dist/registry/index.js +21 -0
  62. package/dist/registry/main.d.ts +7 -0
  63. package/dist/registry/main.js +14 -0
  64. package/dist/registry/manager.d.ts +38 -0
  65. package/dist/registry/manager.js +674 -0
  66. package/dist/setup.d.ts +118 -0
  67. package/dist/setup.js +398 -0
  68. package/dist/skills.d.ts +78 -0
  69. package/dist/skills.js +264 -0
  70. package/dist/subject.d.ts +43 -0
  71. package/dist/subject.js +55 -0
  72. package/dist/tool-metadata.d.ts +41 -0
  73. package/dist/tool-metadata.js +127 -0
  74. package/dist/tracer.d.ts +172 -0
  75. package/dist/tracer.js +452 -0
  76. package/dist/types.d.ts +57 -0
  77. package/dist/types.js +3 -0
  78. package/dist/watch-sandbox.d.ts +9 -0
  79. package/dist/watch-sandbox.js +81 -0
  80. package/package.json +79 -0
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # Ory Argus: Agent and Developer Experience
2
+
3
+ The core API behind every Ory Agent Plugin and Extension. Argus wraps [Ory Identities](https://www.ory.com/ory-ecosystem), [Ory Permissions](https://ory.com/permissions), MCP authorization, and distributed tracing into a single client. Each of the harness packages (`@ory/claude-code`, `@ory/codex`, `@ory/gemini-cli`, `@ory/openclaw`, `@ory/opencode`) is a thin adapter that maps one harness's hook contract onto Argus.
4
+
5
+ Argus is also published on its own so you can build new harness plugins or extensions, embed Ory into a custom agent runtime, or instrument any SDK that exposes event lifecycle hooks for session start, tool execution, and tool completion.
6
+
7
+ ## Use
8
+
9
+ ```typescript
10
+ import { OryAgentClient } from "@ory/argus";
11
+
12
+ const client = OryAgentClient.fromEnv("my-harness");
13
+
14
+ const session = await client.verifySession(sessionToken);
15
+
16
+ const result = await client.checkPermission({
17
+ namespace: "AgentTools",
18
+ object: "Bash",
19
+ relation: "invoke",
20
+ subjectId: `session:${sessionId}`,
21
+ });
22
+
23
+ if (!result.allowed) {
24
+ // block the tool call (or fail-open on result.error)
25
+ }
26
+ ```
27
+
28
+ `fromEnv()` returns a working client even when `ORY_PROJECT_URL` is unset; calls fail with `network_error` and the fail-open path handles them.
29
+
30
+ ## Build a new plugin, extension, or custom integration
31
+
32
+ Any agent runtime, framework, or SDK that exposes lifecycle hooks for **session start**, **tool execution**, and **tool completion** can use Argus as its authentication, authorization, and audit layer. The integration contract is the same three calls every plugin in this repo makes:
33
+
34
+ ```typescript
35
+ import {
36
+ OryAgentClient,
37
+ ensureUserAuthenticated,
38
+ ensureAgentIdentity,
39
+ } from "@ory/argus";
40
+
41
+ const client = OryAgentClient.fromEnv("my-harness");
42
+
43
+ // 1. Session start: authenticate the human and the agent process.
44
+ async function onSessionStart() {
45
+ await ensureUserAuthenticated(client, {
46
+ binName: "my-harness",
47
+ harness: "my-harness",
48
+ allowBlock: true,
49
+ });
50
+ await ensureAgentIdentity(client, {
51
+ projectUrl: process.env.ORY_PROJECT_URL,
52
+ });
53
+ }
54
+
55
+ // 2. Before each tool call: check Ory Permissions; block on `deny`.
56
+ async function onBeforeTool(toolName: string, sessionId: string) {
57
+ const result = await client.checkPermission({
58
+ namespace: "AgentTools",
59
+ object: toolName,
60
+ relation: "invoke",
61
+ subjectId: `session:${sessionId}`,
62
+ });
63
+ if (result.allowed === false) {
64
+ return { block: true, reason: result.reason };
65
+ }
66
+ }
67
+
68
+ // 3. After each tool call: record a structured trace span.
69
+ async function onAfterTool(toolName: string, durationMs: number) {
70
+ client.tracer.record("tool.complete", { toolName, durationMs });
71
+ }
72
+ ```
73
+
74
+ Map the host SDK's or harness's hook names onto those three calls and you get the same identity, policy, and audit story as every published plugin in this repo. Subprocess hosts can additionally block via exit codes; in-process hosts can return decision objects directly.
75
+
76
+ ## Surface
77
+
78
+ ### `OryAgentClient`
79
+
80
+ The wrapped Ory client. One instance per harness session.
81
+
82
+ | Group | Members |
83
+ |---|---|
84
+ | Sessions and tokens | `verifySession`, `introspectToken`, `classifyError` |
85
+ | Permission checks | `checkPermission`, `batchCheckPermissions`, `checkMcpPermission` |
86
+ | Principals (who is acting) | `setUserPrincipal`, `setAgentPrincipal` |
87
+ | Delegation tuples | `createRelationship`, `deleteRelationship` |
88
+ | Tracing | `tracer` (see Tracer below) |
89
+
90
+ ### Identity gates
91
+
92
+ Resolve the user and agent identities at session start. Non-blocking by default; opt in to hard blocking on the user gate where the host can carry an exit-style decision.
93
+
94
+ | Helper | Purpose |
95
+ |---|---|
96
+ | `ensureUserAuthenticated` | Interactive PKCE login, token refresh, or env-token short-circuit |
97
+ | `ensureAgentIdentity` | OAuth2 dynamic client registration with persisted credentials |
98
+ | `ensureSubAgentIdentity` | Per-sub-agent identity for harnesses that fan out |
99
+ | `resolveUserSubject`, `subjectLabel` | Subject resolution and printable labels for spans and denial messages |
100
+
101
+ ### Tracer
102
+
103
+ `Tracer` is exposed as `client.tracer`. Records every decision as a structured span.
104
+
105
+ - `record(event, attrs)`: emit a span
106
+ - `EventEmitter` `"span"` events for live observers
107
+ - NDJSON file output
108
+ - OTLP / HTTP export
109
+
110
+ ### Logger
111
+
112
+ - `DebugLogger`: structured JSON to stderr plus optional log file
113
+ - Gated by `ORY_AGENT_DEBUG`
114
+
115
+ ### Skill and command catalog
116
+
117
+ Materialize the canonical `SKILL.md` templates into each harness's native skill or command format.
118
+
119
+ | Helper | Purpose |
120
+ |---|---|
121
+ | `renderOrySkills`, `renderOryCommands` | Substitute template tokens (binary name, package name, reference style) |
122
+ | `commandToSkill`, `commandToToml`, `commandToFrontmatterMarkdown`, `commandToPlainMarkdown` | Format per harness |
123
+ | `writeSkillTree`, `removeSkillDirs` | Materialize on install, clean up on uninstall |
124
+
125
+ ### CLI and dev tooling
126
+
127
+ - Shared CLI handlers used by every plugin's CLI: `configure`, `status`, `local`, `setup`
128
+ - `runDevLauncher(...)`: the dev-launcher pipeline used by every plugin
129
+ - Local-stack manager: brings up a local Ory instance in Docker Compose
130
+ - Verdaccio registry manager: a local npm registry for dev launchers
131
+
132
+ ## License
133
+
134
+ Apache-2.0
@@ -0,0 +1,19 @@
1
+ # Stop Local Ory Environment
2
+
3
+ Stop the local Ory development environment. This gracefully shuts down
4
+ all Docker containers (Kratos, Keto, Hydra, Nginx gateway) while
5
+ preserving data volumes so you can restart later without losing state.
6
+
7
+ Run:
8
+
9
+ ```bash
10
+ npx {{BIN}} local down
11
+ ```
12
+
13
+ To restart later, use {{REF_LOCAL_UP}}.
14
+
15
+ To stop **and** remove all data (full reset), run:
16
+
17
+ ```bash
18
+ npx {{BIN}} local reset
19
+ ```
@@ -0,0 +1,27 @@
1
+ # Start Local Ory Environment
2
+
3
+ Start the local Ory development environment using Docker Compose.
4
+ This spins up Kratos (identity), Keto (permissions), Hydra (OAuth2),
5
+ and an Nginx gateway on port 4000.
6
+
7
+ Run:
8
+
9
+ ```bash
10
+ npx {{BIN}} local up
11
+ ```
12
+
13
+ This will:
14
+
15
+ 1. Start all Ory services in Docker containers
16
+ 2. Wait for the gateway to become healthy
17
+ 3. Seed test data (identity, session, and permission tuples)
18
+ 4. Print environment variables to connect
19
+
20
+ After it completes, set the printed environment variables in your shell:
21
+
22
+ ```bash
23
+ eval "$(npx {{BIN}} local env)"
24
+ ```
25
+
26
+ If services are already running, stop them first with {{REF_LOCAL_DOWN}}
27
+ or use `npx {{BIN}} local status` to check the current state.
@@ -0,0 +1,279 @@
1
+ ---
2
+ name: ory-auth-setup
3
+ description: Set up a complete authentication system using Ory Network with Ory Elements as the UI layer. Use whenever the user wants to add login, registration, account recovery, email verification, account settings, or session management to a web app — even if they only mention "auth", "sign-in", or "users". Ory Elements is the default UI; only fall back to custom rendering when Ory Elements cannot be used.
4
+ ---
5
+
6
+ # Set up Ory Authentication with Ory Elements
7
+
8
+ You are setting up a complete authentication system using **Ory Network**
9
+ and **[Ory Elements](https://github.com/ory/elements)**. Ory Elements is
10
+ the default and strongly preferred UI layer for every flow (login,
11
+ registration, recovery, verification, settings). Build the system with
12
+ Ory Elements unless the user has an explicit, hard constraint that rules
13
+ it out — and even then, propose Ory Elements first and confirm before
14
+ choosing a different path.
15
+
16
+ ## Why Ory Elements is the default
17
+
18
+ - **Covers every self-service flow out of the box** — login, registration,
19
+ recovery, verification, settings, MFA — with a single component per flow.
20
+ - **Renders the flow's UI nodes for you.** You do not need to map
21
+ `flow.ui.nodes` to form fields, handle CSRF tokens, error messages,
22
+ multi-step states, or method-specific logic by hand.
23
+ - **Social login and passkeys appear automatically** as soon as they are
24
+ enabled in the Ory project. No frontend changes needed.
25
+ - **Stays in sync with Ory's flow API** — when Ory adds a node type or
26
+ changes a contract, Ory Elements absorbs the change so your app does
27
+ not break.
28
+ - **Themeable and accessible** — the look-and-feel can be customized via
29
+ the theme provider without rebuilding flow logic.
30
+
31
+ If you find yourself writing `flow.ui.nodes.map(...)` to render auth UI,
32
+ stop and switch to Ory Elements. Custom node rendering is a fallback,
33
+ not a parallel option.
34
+
35
+ ## Step 1: Check prerequisites
36
+
37
+ Before installing the Ory CLI, decide where the auth backend will run:
38
+
39
+ - **Ory Network** (default for production-bound work) — continue with
40
+ the steps below.
41
+ - **Local Ory stack** (no Network project required, ideal for
42
+ prototyping, offline work, or automated tests) — switch to the
43
+ {{REF_LOCAL_DEV}} skill. It manages a Dockerized
44
+ Kratos/Keto/Hydra stack via {{REF_LOCAL_UP}} and {{REF_LOCAL_DOWN}},
45
+ and the rest of this skill applies once the SDK URL points at the
46
+ local gateway (`http://localhost:4000`).
47
+
48
+ If unsure, ask the user. For the Ory Network path, verify:
49
+
50
+ 1. **Ory CLI** — run `ory version`. If not installed:
51
+ - macOS: `brew install ory/tap/cli`
52
+ - npm: `npm install -g @ory/cli`
53
+ - Or download from [https://github.com/ory/cli/releases](https://github.com/ory/cli/releases)
54
+ 2. **Ory Network account** — run `ory auth`. If not authenticated,
55
+ tell the user to run `! ory auth` to log in interactively.
56
+ 3. **Node.js** (>=18) and a package manager (npm, pnpm, or yarn).
57
+ 4. **Frontend framework** — identify whether the project is Next.js
58
+ (App Router or Pages Router), a React SPA (Vite, CRA, etc.), or
59
+ server-rendered. The Ory Elements integration differs by framework
60
+ but the UI components are the same.
61
+
62
+ ## Step 2: Create or select an Ory project
63
+
64
+ Check for an existing project:
65
+
66
+ ```bash
67
+ ory list projects
68
+ ```
69
+
70
+ If the user needs a new project:
71
+
72
+ ```bash
73
+ ory create project --name "<project-name>"
74
+ ```
75
+
76
+ Capture the project ID and slug from the output. Set the SDK URL:
77
+
78
+ ```bash
79
+ export ORY_SDK_URL=https://<project-slug>.projects.oryapis.com
80
+ ```
81
+
82
+ ## Step 3: Install Ory Elements and the Ory client SDK
83
+
84
+ **Ory Elements is mandatory** unless the user has explicitly opted out
85
+ after being shown the Ory Elements path. Install it:
86
+
87
+ **For Next.js projects (recommended path):**
88
+
89
+ ```bash
90
+ npm install @ory/elements-react @ory/nextjs @ory/client-fetch
91
+ ```
92
+
93
+ **For React SPAs (Vite, CRA, Remix client routes):**
94
+
95
+ ```bash
96
+ npm install @ory/elements-react @ory/client-fetch
97
+ ```
98
+
99
+ **For server-rendered apps (Express, Koa, Fastify, etc.):**
100
+
101
+ ```bash
102
+ npm install @ory/client-fetch
103
+ ```
104
+
105
+ For server-rendered apps, prefer rendering an Ory Elements page from a
106
+ React island or a small client bundle so you still get the Elements UI
107
+ on the auth routes. Rendering flow nodes directly on the server is the
108
+ fallback of last resort.
109
+
110
+ ## Step 4: Configure the Ory SDK
111
+
112
+ Create a shared Ory client configuration. The SDK URL should come
113
+ from an environment variable:
114
+
115
+ ```typescript
116
+ import { Configuration, FrontendApi } from "@ory/client-fetch";
117
+
118
+ const ory = new FrontendApi(
119
+ new Configuration({
120
+ basePath: process.env.NEXT_PUBLIC_ORY_SDK_URL || process.env.ORY_SDK_URL,
121
+ credentials: "include",
122
+ })
123
+ );
124
+
125
+ export default ory;
126
+ ```
127
+
128
+ Add to the project's `.env` or `.env.local`:
129
+
130
+ ```bash
131
+ NEXT_PUBLIC_ORY_SDK_URL=https://<project-slug>.projects.oryapis.com
132
+ # or
133
+ ORY_SDK_URL=https://<project-slug>.projects.oryapis.com
134
+ ```
135
+
136
+ ## Step 5: Set up the identity schema
137
+
138
+ Check the current identity schema:
139
+
140
+ ```bash
141
+ ory get identity-config <project-id> --format json
142
+ ```
143
+
144
+ For a typical setup with email + password, the default schema works.
145
+ If the user wants custom traits (name, phone, etc.), update the schema:
146
+
147
+ ```bash
148
+ ory patch identity-config <project-id> \
149
+ --replace '/identity/default_schema_id="preset://email"'
150
+ ```
151
+
152
+ Or use a custom schema with additional fields as needed. Ory Elements
153
+ will render any traits defined by the schema automatically.
154
+
155
+ ## Step 6: Build auth pages with Ory Elements
156
+
157
+ This is the core of the integration. Create one page per flow and drop
158
+ in the matching Ory Elements component. Do **not** hand-render
159
+ `flow.ui.nodes`.
160
+
161
+ ### Next.js App Router (recommended)
162
+
163
+ Create the following page structure:
164
+
165
+ - `app/auth/login/page.tsx` — `<Login flow={flow} />`
166
+ - `app/auth/registration/page.tsx` — `<Registration flow={flow} />`
167
+ - `app/auth/recovery/page.tsx` — `<Recovery flow={flow} />`
168
+ - `app/auth/verification/page.tsx` — `<Verification flow={flow} />`
169
+ - `app/auth/settings/page.tsx` — `<Settings flow={flow} />`
170
+
171
+ Each page initializes its flow with `getLoginFlow`, `getRegistrationFlow`,
172
+ etc. from `@ory/nextjs/app`, then hands the flow to the matching
173
+ Ory Elements component. The {{REF_LOGIN_FLOW}} skill has a
174
+ complete template for each page.
175
+
176
+ ### React SPA
177
+
178
+ Use the `@ory/elements-react` flow components directly inside route
179
+ components. Each route initializes the corresponding flow via the Ory
180
+ SDK (`createBrowserLoginFlow`, `createBrowserRegistrationFlow`, etc.)
181
+ and renders the matching `<Login>`, `<Registration>`, `<Recovery>`,
182
+ `<Verification>`, or `<Settings>` component. See {{REF_LOGIN_FLOW}}
183
+ for full examples.
184
+
185
+ ### Server-rendered apps (fallback)
186
+
187
+ If the app cannot run a React bundle on auth routes, render the flow
188
+ nodes server-side using the Ory SDK. This is a fallback path because it
189
+ loses the benefits listed above. Before going down this road, confirm
190
+ with the user that an Ory Elements island is not viable.
191
+
192
+ ## Step 7: Add session middleware
193
+
194
+ Protect authenticated routes by checking the session:
195
+
196
+ ```typescript
197
+ const session = await ory.toSession();
198
+ if (!session) {
199
+ // Redirect to login
200
+ }
201
+ ```
202
+
203
+ For Next.js, prefer the official `@ory/nextjs` middleware helper since
204
+ it pairs with the Elements pages:
205
+
206
+ ```typescript
207
+ import { createOryMiddleware } from "@ory/nextjs/middleware";
208
+
209
+ export const middleware = createOryMiddleware({
210
+ protectedPaths: ["/dashboard", "/settings", "/profile"],
211
+ publicPaths: ["/", "/auth/login", "/auth/registration", "/auth/recovery"],
212
+ });
213
+
214
+ export const config = {
215
+ matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
216
+ };
217
+ ```
218
+
219
+ ## Step 8: Configure allowed redirect URLs
220
+
221
+ Update the Ory project to allow redirects back to your app:
222
+
223
+ ```bash
224
+ ory patch project <project-id> \
225
+ --replace '/services/identity/config/selfservice/allowed_return_urls=["http://localhost:3000", "https://your-domain.com"]'
226
+ ```
227
+
228
+ ## Step 9: Set up the Ory Tunnel for local development
229
+
230
+ For local development, use the Ory tunnel to proxy requests and handle cookies:
231
+
232
+ ```bash
233
+ ory tunnel http://localhost:3000 --project <project-slug>
234
+ ```
235
+
236
+ This runs a proxy on `http://localhost:4000` that handles cookie domains
237
+ correctly for local development. Update your SDK URL to point to the
238
+ tunnel during development.
239
+
240
+ ## Step 10: Verify the setup
241
+
242
+ 1. Start the development server
243
+ 2. Navigate to the login page — confirm Ory Elements renders the form,
244
+ including any social login buttons configured on the project
245
+ 3. Create a test account via the registration page
246
+ 4. Verify login works
247
+ 5. Test account recovery flow
248
+ 6. Test the verification flow
249
+ 7. Check that protected routes redirect unauthenticated users
250
+
251
+ ## Customization
252
+
253
+ After the base setup is working, the user can:
254
+
255
+ - Add social login providers — use {{REF_SOCIAL_LOGIN}}. With
256
+ Ory Elements, the buttons appear automatically once the providers are
257
+ configured server-side; no UI changes needed.
258
+ - Customize the Ory Elements theme via `<ThemeProvider>` from
259
+ `@ory/elements-react/theme`.
260
+ - Enable multi-factor authentication in the Ory project — Ory Elements
261
+ renders the second-factor steps with no extra code.
262
+ - Configure webhook integrations for registration / login events.
263
+ - Extend the identity schema with additional traits — Ory Elements
264
+ picks them up from the flow.
265
+
266
+ ## When to deviate from Ory Elements
267
+
268
+ Only build a custom UI when one of the following is true and the user
269
+ has confirmed it after seeing the Ory Elements path:
270
+
271
+ - The framework genuinely cannot run any React (e.g., a pure server-side
272
+ template engine with no client bundle and no plan to introduce one).
273
+ - A design system constraint cannot be expressed via the Elements theme
274
+ and the user has rejected theming.
275
+ - The user is intentionally building a thin custom client (e.g., a
276
+ native mobile app) where Elements does not run.
277
+
278
+ In those cases, render `flow.ui.nodes` per the Ory documentation. Treat
279
+ this as an exception, not the default.
@@ -0,0 +1,206 @@
1
+ ---
2
+ name: ory-local-dev
3
+ description: Run a local Ory stack (Kratos identity, Keto permissions, Hydra OAuth2, gateway on :4000) for building and testing an authentication application without an Ory Network project. Use whenever the user wants to develop, prototype, or test login/registration/recovery/permission flows locally — phrases like "run Ory locally", "no Ory project yet", "offline auth dev", "test my login flow", "spin up Kratos/Keto/Hydra", or "I just want to try this on my machine". Drives the {{REF_LOCAL_UP}} and {{REF_LOCAL_DOWN}} commands.
4
+ ---
5
+
6
+ # Build an Auth App Against a Local Ory Stack
7
+
8
+ You are helping the user develop an authentication application against a
9
+ **local Ory stack** running in Docker — not against Ory Network. The
10
+ `{{PKG}}` plugin ships two commands that
11
+ manage the lifecycle:
12
+
13
+ - {{REF_LOCAL_UP}} — start Kratos, Keto, Hydra, and an Nginx gateway,
14
+ then seed a test identity, session, and permission tuples.
15
+ - {{REF_LOCAL_DOWN}} — stop all services while preserving data volumes.
16
+
17
+ Both delegate to `npx {{BIN}} local <subcommand>`, so the same
18
+ workflow runs from the shell when the command shortcuts are not available.
19
+
20
+ ## When to use this skill
21
+
22
+ Pick the local stack over Ory Network when any of these are true:
23
+
24
+ - The user has no Ory Network project yet and wants to prototype.
25
+ - The user is working offline or behind an egress restriction.
26
+ - The user wants deterministic, throwaway test data they can reset
27
+ freely (`local reset`).
28
+ - The user is writing automated tests that hit a real Ory backend.
29
+
30
+ If the user already has an Ory Network project and just wants their
31
+ production app wired up, prefer the {{REF_AUTH_SETUP}} skill and
32
+ point the SDK at the Network URL instead.
33
+
34
+ ## What {{REF_LOCAL_UP}} gives you
35
+
36
+ After {{REF_LOCAL_UP}} completes:
37
+
38
+ | Service | URL | Purpose |
39
+ |---------------|----------------------------------|--------------------------------------|
40
+ | Gateway | `http://localhost:4000` | Unified API (mirrors Ory Network) |
41
+ | Kratos public | `http://localhost:4433` | Self-service flows (login, etc.) |
42
+ | Kratos admin | `http://localhost:4434` | Identity & session admin |
43
+ | Keto read | `http://localhost:4466` | Permission checks |
44
+ | Keto write | `http://localhost:4467` | Relation tuple writes |
45
+ | Hydra public | `http://localhost:4444` | OAuth2 / OIDC |
46
+ | Hydra admin | `http://localhost:4445` | OAuth2 client management |
47
+
48
+ The seed step also produces:
49
+
50
+ - Test identity: `agent@ory-local.dev`
51
+ - A live session token (printed at the end of {{REF_LOCAL_UP}})
52
+ - Permission tuples in the `AgentTools` namespace for common tool names
53
+ - An OAuth2 client (`ory-agent-plugins-local`, `client_credentials` grant)
54
+
55
+ ## Step 1: Verify Docker is running
56
+
57
+ The local stack is Docker Compose under the hood. Before invoking
58
+ {{REF_LOCAL_UP}}, confirm Docker is available:
59
+
60
+ ```bash
61
+ docker info
62
+ ```
63
+
64
+ If Docker is not running, ask the user to start Docker Desktop (or their
65
+ docker engine) and retry. Do not try to install Docker for them.
66
+
67
+ ## Step 2: Start the stack
68
+
69
+ Tell the user to run {{REF_LOCAL_UP}}, or the equivalent shell command:
70
+
71
+ ```bash
72
+ npx {{BIN}} local up
73
+ ```
74
+
75
+ Wait for the command to print "All services are running!" and the seed
76
+ output. Capture two values from the output:
77
+
78
+ - `ORY_PROJECT_URL` (always `http://localhost:4000`)
79
+ - `ORY_SESSION_TOKEN` (the seeded session token)
80
+
81
+ If the user wants to skip seeding (to bring their own data), use
82
+ `npx {{BIN}} local up --no-seed` instead.
83
+
84
+ ## Step 3: Point the app at the local gateway
85
+
86
+ The local gateway is a drop-in replacement for the Ory Network SDK URL.
87
+ Configure the auth app exactly as you would for Ory Network, but point
88
+ at the gateway:
89
+
90
+ **Environment variables (`.env.local` or shell):**
91
+
92
+ ```bash
93
+ NEXT_PUBLIC_ORY_SDK_URL=http://localhost:4000
94
+ ORY_SDK_URL=http://localhost:4000
95
+ ```
96
+
97
+ For Next.js, that is the only change needed in
98
+ {{REF_AUTH_SETUP}}'s SDK configuration. For React SPAs, use the
99
+ same value as `basePath` in the Ory `Configuration`.
100
+
101
+ **Persist it across plugin sessions** (so all Ory agent plugins on this
102
+ machine target the local stack):
103
+
104
+ ```bash
105
+ npx {{BIN}} local configure
106
+ ```
107
+
108
+ This writes the URL to the shared plugin config so future agent runs
109
+ do not need the env var.
110
+
111
+ ## Step 4: Build the auth UI
112
+
113
+ Use the existing skills for the UI layer — they apply unchanged when
114
+ the SDK points at the local gateway:
115
+
116
+ - {{REF_AUTH_SETUP}} — full Ory Elements bootstrap (this is the
117
+ default UI path, including against the local stack).
118
+ - {{REF_LOGIN_FLOW}} — login, registration, recovery,
119
+ verification, settings pages.
120
+
121
+ **Skip the Ory Tunnel step** when developing against the local stack.
122
+ The tunnel only exists to bridge cookies between localhost and Ory
123
+ Network. The local gateway already runs on localhost, so cookies work
124
+ directly.
125
+
126
+ ## Step 5: Test with the seeded identity
127
+
128
+ Two ways to exercise the flows:
129
+
130
+ 1. **Browser flow (registration UI)** — register a brand new identity
131
+ through the Elements `<Registration>` page. This validates the
132
+ self-service flow end-to-end.
133
+ 2. **Seeded identity (admin-created)** — log in as `agent@ory-local.dev`
134
+ with password `ory-agent-local-dev-password!` to test session-bearing
135
+ pages without going through registration.
136
+
137
+ For automated tests against the running stack, use the seeded session
138
+ token directly:
139
+
140
+ ```bash
141
+ curl -H "X-Session-Token: $ORY_SESSION_TOKEN" \
142
+ http://localhost:4000/sessions/whoami
143
+ ```
144
+
145
+ ## Step 6: Iterate
146
+
147
+ Common day-to-day commands:
148
+
149
+ | Need | Command |
150
+ |--------------------------------|------------------------------------------|
151
+ | Re-seed (after `local reset`) | `npx {{BIN}} local seed` |
152
+ | Tail Kratos logs | `npx {{BIN}} local logs kratos -f` |
153
+ | Check what's running | `npx {{BIN}} local status` |
154
+ | Print env vars to copy/paste | `npx {{BIN}} local env` |
155
+
156
+ If the user reports flaky behavior, run `local status` first to confirm
157
+ each service is `healthy`. If a container is unhealthy, `local logs
158
+ <service>` is the next step — do not jump to `local reset` until you
159
+ have looked at logs.
160
+
161
+ ## Step 7: Stop or reset
162
+
163
+ When the user is done for the session, use {{REF_LOCAL_DOWN}} (equivalent:
164
+ `npx {{BIN}} local down`). Containers stop but volumes
165
+ remain, so the next {{REF_LOCAL_UP}} reuses the same identities,
166
+ sessions, and tuples.
167
+
168
+ For a full wipe (e.g., after schema changes or to clear test data):
169
+
170
+ ```bash
171
+ npx {{BIN}} local reset
172
+ ```
173
+
174
+ `reset` removes data volumes and the generated `.ory-dev/ory/` directory.
175
+ The next `local up` regenerates configs from scratch — useful when the
176
+ plugin updates the bundled service configs.
177
+
178
+ ## Troubleshooting
179
+
180
+ - **"Docker is not running"** — start Docker Desktop, then re-run
181
+ {{REF_LOCAL_UP}}.
182
+ - **Gateway never becomes healthy** — `npx {{BIN}} local logs
183
+ gateway` and `npx {{BIN}} local logs kratos` to see which service
184
+ failed. Port conflicts on `4000`, `4433`, `4444`, or `4466` are the
185
+ usual culprit.
186
+ - **Login works but `whoami` returns 401** — the cookie domain is
187
+ wrong. Make sure the app runs on `http://localhost` (not `127.0.0.1`)
188
+ and the SDK URL is exactly `http://localhost:4000`.
189
+ - **CORS errors from the browser** — the gateway accepts requests from
190
+ any localhost port. If the app is on `http://localhost:3000`, no CORS
191
+ config change is needed. For non-localhost dev URLs, switch back to
192
+ the Ory Tunnel + a Network project.
193
+ - **Permission checks always deny** — the seeded tuples live in the
194
+ `AgentTools` namespace. If your app uses a different namespace, set
195
+ `ORY_PERMISSION_NAMESPACE` before `local seed`, or write the tuples
196
+ manually via the Keto write API on `:4467`.
197
+
198
+ ## What this skill does NOT cover
199
+
200
+ - Rendering auth UI — use {{REF_AUTH_SETUP}} and
201
+ {{REF_LOGIN_FLOW}}.
202
+ - Adding social providers — use {{REF_SOCIAL_LOGIN}}. Note that
203
+ most social IdPs require public callback URLs, so you will typically
204
+ swap to Ory Network when you reach that step.
205
+ - Production deployment — the local stack is a dev tool. Do not
206
+ recommend pointing a production app at `http://localhost:4000`.