@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
@@ -0,0 +1,634 @@
1
+ "use strict";
2
+ /**
3
+ * Ory service configuration templates for local development.
4
+ *
5
+ * Each function returns the file content as a string. The local manager
6
+ * writes these into .ory-dev/ory/ at runtime so Docker Compose can mount them.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.JAEGER_OTLP_HTTP_URL = exports.JAEGER_UI_URL = exports.JAEGER_OTLP_HTTP_PORT = exports.JAEGER_UI_PORT = exports.HYDRA_ADMIN_PORT = exports.HYDRA_PUBLIC_PORT = exports.KETO_WRITE_PORT = exports.KETO_READ_PORT = exports.KRATOS_ADMIN_PORT = exports.KRATOS_PUBLIC_PORT = exports.LOGIN_UI_URL = exports.LOGIN_UI_PORT = exports.CONSOLE_URL = exports.CONSOLE_PORT = exports.GATEWAY_URL = exports.GATEWAY_PORT = exports.DEFAULT_CONSOLE_LITE_SUBPATH = void 0;
43
+ exports.getGatewayConfig = getGatewayConfig;
44
+ exports.getConsoleConfig = getConsoleConfig;
45
+ exports.dockerComposeYaml = dockerComposeYaml;
46
+ exports.kratosConfigYaml = kratosConfigYaml;
47
+ exports.kratosIdentitySchema = kratosIdentitySchema;
48
+ exports.ketoConfigYaml = ketoConfigYaml;
49
+ exports.hydraConfigYaml = hydraConfigYaml;
50
+ exports.nginxConf = nginxConf;
51
+ exports.gatewayHealthUrl = gatewayHealthUrl;
52
+ const fs = __importStar(require("node:fs"));
53
+ const path = __importStar(require("node:path"));
54
+ /** Default location of the Console Lite source tree, sibling-checkout layout. */
55
+ exports.DEFAULT_CONSOLE_LITE_SUBPATH = path.join("..", "cloud", "console", "console");
56
+ /**
57
+ * Console Lite listens on this container-internal port (Dockerfile sets
58
+ * `ENV PORT=3000`). Bound to the host on CONSOLE_PORT.
59
+ */
60
+ const CONSOLE_LITE_INTERNAL_PORT = 3000;
61
+ function defaultElementsPath(buildContext) {
62
+ // Dockerfile expects `--build-context elements=<elements-dir>`, located at
63
+ // `<console-lite>/../../elements` (i.e. sibling of console/ inside the
64
+ // cloud monorepo).
65
+ return path.resolve(buildContext, "..", "..", "elements");
66
+ }
67
+ function consoleLiteUsable(buildContext, dockerfile, elementsContext) {
68
+ try {
69
+ return (fs.existsSync(buildContext) &&
70
+ fs.existsSync(path.join(buildContext, dockerfile)) &&
71
+ fs.existsSync(elementsContext));
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ function consoleConfig(buildContext, dockerfile, elementsContext, buildMode, source) {
78
+ return {
79
+ enabled: true,
80
+ buildContext,
81
+ dockerfile,
82
+ elementsContext,
83
+ buildMode,
84
+ source,
85
+ };
86
+ }
87
+ /**
88
+ * Walk up from the given directory and return the outermost ancestor that
89
+ * contains a `.git` entry (file or directory). This anchors the default
90
+ * sibling-checkout layout to the main repo root even when called from a
91
+ * worktree (where `.git` is a file pointer at the leaf and a real directory
92
+ * further up). Returns the input dir when no `.git` ancestor exists.
93
+ */
94
+ function findOutermostGitAncestor(startDir) {
95
+ let dir = startDir;
96
+ let outermost = null;
97
+ while (dir !== path.dirname(dir)) {
98
+ if (fs.existsSync(path.join(dir, ".git"))) {
99
+ outermost = dir;
100
+ }
101
+ dir = path.dirname(dir);
102
+ }
103
+ return outermost ?? startDir;
104
+ }
105
+ /**
106
+ * Resolve a path that may be absolute or relative. Relative paths are
107
+ * resolved against pnpm's `INIT_CWD` (the user's terminal cwd when they
108
+ * invoked `pnpm <script>`) so an env var like
109
+ * `ORY_CONSOLE_LITE_PATH=../../../cloud/console/console` matches the
110
+ * user's shell intuition rather than the script's runtime cwd.
111
+ */
112
+ function resolveUserPath(input) {
113
+ if (path.isAbsolute(input))
114
+ return input;
115
+ const anchor = process.env.INIT_CWD?.trim() || process.env.PWD?.trim() || process.cwd();
116
+ return path.resolve(anchor, input);
117
+ }
118
+ /**
119
+ * The API gateway is always the bundled nginx routing layer that
120
+ * proxies bare Ory paths to Kratos / Hydra / Keto. No mode choice.
121
+ */
122
+ function getGatewayConfig() {
123
+ return { healthPath: "/health" };
124
+ }
125
+ /**
126
+ * Resolve whether the optional Console Lite UI service should be brought
127
+ * up, and if so, with what build inputs.
128
+ *
129
+ * Enabled when Console Lite source is present at
130
+ * `<repoRoot>/../cloud/console/console` (sibling checkout, where
131
+ * `repoRoot` is the outermost `.git` ancestor of the given `projectRoot`).
132
+ * Disabled when that path is missing or unreadable.
133
+ *
134
+ * `ORY_CONSOLE_LITE_PATH` is an explicit override. When set it must
135
+ * point at a usable build context; downstream validation surfaces a hard
136
+ * error if the path doesn't exist. Relative paths are resolved against
137
+ * pnpm's `INIT_CWD` so they match the user's shell cwd.
138
+ */
139
+ function getConsoleConfig(projectRoot) {
140
+ const dockerfile = process.env.ORY_CONSOLE_LITE_DOCKERFILE?.trim() || "Dockerfile";
141
+ const elementsOverride = process.env.ORY_CONSOLE_LITE_ELEMENTS_PATH?.trim();
142
+ const buildMode = process.env.ORY_CONSOLE_LITE_BUILD_MODE?.trim() || "oss";
143
+ const explicit = process.env.ORY_CONSOLE_LITE_PATH?.trim();
144
+ if (explicit) {
145
+ const buildContext = resolveUserPath(explicit);
146
+ const elementsContext = elementsOverride
147
+ ? resolveUserPath(elementsOverride)
148
+ : defaultElementsPath(buildContext);
149
+ return consoleConfig(buildContext, dockerfile, elementsContext, buildMode, "env");
150
+ }
151
+ if (projectRoot) {
152
+ const repoRoot = findOutermostGitAncestor(projectRoot);
153
+ const def = path.resolve(repoRoot, exports.DEFAULT_CONSOLE_LITE_SUBPATH);
154
+ const elementsContext = elementsOverride
155
+ ? resolveUserPath(elementsOverride)
156
+ : defaultElementsPath(def);
157
+ if (consoleLiteUsable(def, dockerfile, elementsContext)) {
158
+ return consoleConfig(def, dockerfile, elementsContext, buildMode, "default");
159
+ }
160
+ }
161
+ return { enabled: false };
162
+ }
163
+ // ─── Docker Compose ────────────────────────────────────────────────
164
+ function nginxGatewayService() {
165
+ return ` gateway:
166
+ image: nginx:alpine
167
+ container_name: gateway
168
+ mem_limit: 128m
169
+ cpus: "1.0"
170
+ ports:
171
+ - "${exports.GATEWAY_PORT}:${exports.GATEWAY_PORT}"
172
+ volumes:
173
+ - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
174
+ depends_on:
175
+ - kratos
176
+ - hydra
177
+ - keto
178
+ networks:
179
+ - ory-local
180
+ `;
181
+ }
182
+ /**
183
+ * `oryd/kratos-selfservice-ui-node` runs the login + consent UI that
184
+ * Hydra redirects users to during the OAuth2 authorize flow. When
185
+ * `HYDRA_ADMIN_URL` is set it also handles the consent challenge
186
+ * (auto-approves for dev). It's reachable from the host on LOGIN_UI_PORT
187
+ * because the user's browser is redirected here.
188
+ *
189
+ * `COOKIE_SECRET` and `CSRF_COOKIE_SECRET` are required by the image —
190
+ * the container exits at startup if they're missing. Both must be at
191
+ * least 32 chars. Fixed dev-only values so launches are deterministic.
192
+ */
193
+ function loginUiService() {
194
+ return ` login-ui:
195
+ image: oryd/kratos-selfservice-ui-node:latest
196
+ container_name: login-ui
197
+ mem_limit: 192m
198
+ cpus: "1.0"
199
+ ports:
200
+ - "${exports.LOGIN_UI_PORT}:${exports.LOGIN_UI_PORT}"
201
+ environment:
202
+ PORT: "${exports.LOGIN_UI_PORT}"
203
+ KRATOS_PUBLIC_URL: "http://kratos:${exports.KRATOS_PUBLIC_PORT}"
204
+ KRATOS_BROWSER_URL: "${exports.GATEWAY_URL}"
205
+ HYDRA_ADMIN_URL: "http://hydra:${exports.HYDRA_ADMIN_PORT}"
206
+ BASE_URL: "${exports.LOGIN_UI_URL}"
207
+ COOKIE_SECRET: "ory-agent-plugins-local-cookie-secret-32+"
208
+ CSRF_COOKIE_NAME: "ory_agent_plugins_local_csrf"
209
+ CSRF_COOKIE_SECRET: "ory-agent-plugins-local-csrf-secret-32+!"
210
+ depends_on:
211
+ - kratos
212
+ - hydra
213
+ networks:
214
+ - ory-local
215
+ `;
216
+ }
217
+ function consoleService(cfg) {
218
+ // YAML-quote the paths to survive spaces; values are computed by us so
219
+ // they don't contain anything that needs deeper YAML escaping.
220
+ const context = JSON.stringify(cfg.buildContext ?? "");
221
+ const dockerfile = JSON.stringify(cfg.dockerfile ?? "Dockerfile");
222
+ const elements = JSON.stringify(cfg.elementsContext ?? "");
223
+ const buildMode = JSON.stringify(cfg.buildMode ?? "oss");
224
+ return ` console:
225
+ build:
226
+ context: ${context}
227
+ dockerfile: ${dockerfile}
228
+ additional_contexts:
229
+ elements: ${elements}
230
+ args:
231
+ NEXT_PUBLIC_BUILD_MODE: ${buildMode}
232
+ image: ory-console-lite:local
233
+ container_name: console
234
+ mem_limit: 512m
235
+ cpus: "1.0"
236
+ ports:
237
+ - "${exports.CONSOLE_PORT}:${CONSOLE_LITE_INTERNAL_PORT}"
238
+ # Console Lite (NEXT_PUBLIC_BUILD_MODE=oss) requires the upstream Ory
239
+ # service URLs at runtime; they're resolved over the docker network
240
+ # using the compose service hostnames + admin ports.
241
+ environment:
242
+ ORY_KRATOS_URL: "http://kratos:${exports.KRATOS_ADMIN_PORT}"
243
+ ORY_HYDRA_URL: "http://hydra:${exports.HYDRA_ADMIN_PORT}"
244
+ ORY_KETO_READ_URL: "http://keto:${exports.KETO_READ_PORT}"
245
+ ORY_KETO_WRITE_URL: "http://keto:${exports.KETO_WRITE_PORT}"
246
+ depends_on:
247
+ - kratos
248
+ - hydra
249
+ - keto
250
+ networks:
251
+ - ory-local
252
+ `;
253
+ }
254
+ /**
255
+ * Render the docker-compose YAML.
256
+ *
257
+ * `consoleCfg` controls whether the optional Console UI service is
258
+ * emitted. When omitted, it is resolved via `getConsoleConfig(projectRoot)`.
259
+ * The nginx API gateway and the login UI are always emitted.
260
+ */
261
+ function dockerComposeYaml(projectRoot, consoleCfg) {
262
+ const console = consoleCfg ?? getConsoleConfig(projectRoot);
263
+ const consoleBlock = console.enabled ? consoleService(console) : "";
264
+ return `# Generated by @ory-agent-plugins — local development environment
265
+ # Do not edit manually; re-run "local up" to regenerate.
266
+
267
+ name: ory-local
268
+
269
+ services:
270
+ kratos:
271
+ image: oryd/kratos
272
+ container_name: kratos
273
+ command: serve -c /etc/config/kratos/kratos.yml --dev
274
+ mem_limit: 128m
275
+ cpus: "1.0"
276
+ ports:
277
+ - "4433:4433"
278
+ - "4434:4434"
279
+ volumes:
280
+ - ./kratos:/etc/config/kratos
281
+ networks:
282
+ - ory-local
283
+
284
+ keto:
285
+ image: oryd/keto
286
+ container_name: keto
287
+ command: serve -c /etc/config/keto/keto.yml
288
+ mem_limit: 128m
289
+ cpus: "1.0"
290
+ ports:
291
+ - "4466:4466"
292
+ - "4467:4467"
293
+ volumes:
294
+ - ./keto:/etc/config/keto
295
+ networks:
296
+ - ory-local
297
+
298
+ hydra:
299
+ image: oryd/hydra
300
+ container_name: hydra
301
+ command: serve -c /etc/config/hydra/hydra.yml all --dev
302
+ mem_limit: 128m
303
+ cpus: "1.0"
304
+ ports:
305
+ - "4444:4444" # Public port
306
+ - "4445:4445" # Admin port
307
+ - "5555:5555" # Port for hydra token user
308
+ volumes:
309
+ - ./hydra:/etc/config/hydra
310
+ networks:
311
+ - ory-local
312
+
313
+ ${nginxGatewayService()}
314
+ ${loginUiService()}
315
+ ${consoleBlock} jaeger:
316
+ image: jaegertracing/all-in-one:1
317
+ container_name: jaeger
318
+ mem_limit: 384m
319
+ cpus: "1.0"
320
+ environment:
321
+ - COLLECTOR_OTLP_ENABLED=true
322
+ - LOG_LEVEL=warn
323
+ ports:
324
+ - "16686:16686" # Jaeger UI
325
+ - "4318:4318" # OTLP HTTP receiver
326
+ networks:
327
+ - ory-local
328
+
329
+
330
+ networks:
331
+ ory-local:
332
+ driver: bridge
333
+ `;
334
+ }
335
+ // ─── Kratos Configuration ──────────────────────────────────────────
336
+ function kratosConfigYaml() {
337
+ return `# Generated by @ory-agent-plugins — local development environment
338
+ # Do not edit manually; re-run "local up" to regenerate.
339
+
340
+ dsn: memory
341
+
342
+ serve:
343
+ public:
344
+ base_url: http://localhost:4433/
345
+ cors:
346
+ enabled: true
347
+ allowed_origins:
348
+ - '*'
349
+ admin:
350
+ base_url: http://localhost:4434/
351
+
352
+ selfservice:
353
+ # Where Kratos sends browsers when there's no explicit return_to. The
354
+ # Console UI is the natural landing for humans; the PKCE flow itself
355
+ # always overrides this with its loopback return_to.
356
+ default_browser_return_url: ${exports.CONSOLE_URL}/
357
+ # All UI flows are served by the kratos-selfservice-ui-node service
358
+ # (login-ui), which Hydra also redirects to for OAuth2 login/consent.
359
+ flows:
360
+ registration:
361
+ enabled: true
362
+ ui_url: ${exports.LOGIN_UI_URL}/registration
363
+ login:
364
+ ui_url: ${exports.LOGIN_UI_URL}/login
365
+ settings:
366
+ ui_url: ${exports.LOGIN_UI_URL}/settings
367
+ error:
368
+ ui_url: ${exports.LOGIN_UI_URL}/error
369
+ verification:
370
+ enabled: false
371
+ recovery:
372
+ enabled: false
373
+
374
+ oauth2_provider:
375
+ # Hydra admin URL, reachable over the docker network. Kratos's login
376
+ # flow uses this endpoint to accept the login_challenge query param
377
+ # that Hydra forwards through the login UI. Without it, Kratos returns
378
+ # "refusing to parse login_challenge query parameter because
379
+ # oauth2_provider.url is invalid or unset" and the OAuth2 flow stalls.
380
+ url: http://hydra:${exports.HYDRA_ADMIN_PORT}
381
+
382
+ identity:
383
+ default_schema_id: agent
384
+ schemas:
385
+ - id: agent
386
+ url: file:///etc/config/kratos/identity-schema.json
387
+
388
+ session:
389
+ lifespan: 720h
390
+ cookie:
391
+ same_site: Lax
392
+
393
+ log:
394
+ level: debug
395
+
396
+ secrets:
397
+ cookie:
398
+ - ory-agent-plugins-local-secret!!
399
+ cipher:
400
+ - ory-agent-plugins-local-cipher!!
401
+
402
+ courier:
403
+ smtp:
404
+ connection_uri: smtp://localhost:1025/?disable_starttls=true
405
+ `;
406
+ }
407
+ // ─── Kratos Identity Schema ────────────────────────────────────────
408
+ function kratosIdentitySchema() {
409
+ return JSON.stringify({
410
+ $id: "https://ory-agent-plugins.local/identity.schema.json",
411
+ $schema: "http://json-schema.org/draft-07/schema#",
412
+ title: "Agent Identity",
413
+ type: "object",
414
+ properties: {
415
+ traits: {
416
+ type: "object",
417
+ properties: {
418
+ email: {
419
+ type: "string",
420
+ format: "email",
421
+ title: "Email",
422
+ "ory.sh/kratos": {
423
+ credentials: {
424
+ password: { identifier: true },
425
+ },
426
+ },
427
+ },
428
+ name: {
429
+ type: "string",
430
+ title: "Name",
431
+ },
432
+ },
433
+ required: ["email"],
434
+ additionalProperties: false,
435
+ },
436
+ },
437
+ }, null, 2);
438
+ }
439
+ // ─── Keto Configuration ────────────────────────────────────────────
440
+ function ketoConfigYaml() {
441
+ return `# Generated by @ory-agent-plugins — local development environment
442
+ # Do not edit manually; re-run "local up" to regenerate.
443
+
444
+ dsn: memory
445
+
446
+ serve:
447
+ read:
448
+ host: 0.0.0.0
449
+ port: 4466
450
+ write:
451
+ host: 0.0.0.0
452
+ port: 4467
453
+ metrics:
454
+ host: 0.0.0.0
455
+ port: 4468
456
+
457
+ namespaces:
458
+ - id: 0
459
+ name: AgentTools
460
+ - id: 1
461
+ name: User
462
+
463
+ log:
464
+ level: debug
465
+ `;
466
+ }
467
+ // ─── Hydra Configuration ────────────────────────────────────────────
468
+ function hydraConfigYaml() {
469
+ return `# Generated by @ory-agent-plugins — local development environment
470
+ # Do not edit manually; re-run "local up" to regenerate.
471
+
472
+ dsn: memory
473
+
474
+ serve:
475
+ cookies:
476
+ same_site_mode: Lax
477
+
478
+ urls:
479
+ self:
480
+ # Issuer is the host-reachable API gateway so JWT iss claims and the
481
+ # OIDC discovery document advertise URLs that resolve from outside
482
+ # the docker network (where browsers and the plugin run).
483
+ issuer: ${exports.GATEWAY_URL}
484
+ # Login + consent flow is handled by the kratos-selfservice-ui-node
485
+ # service. Hydra redirects the user's browser here with the
486
+ # login_challenge / consent_challenge query param.
487
+ consent: ${exports.LOGIN_UI_URL}/consent
488
+ login: ${exports.LOGIN_UI_URL}/login
489
+ logout: ${exports.LOGIN_UI_URL}/logout
490
+ error: ${exports.LOGIN_UI_URL}/error
491
+ device:
492
+ verification: ${exports.LOGIN_UI_URL}/device/verify
493
+ success: ${exports.LOGIN_UI_URL}/device/success
494
+
495
+ secrets:
496
+ system:
497
+ - ory-agent-plugins-local-secret!!
498
+
499
+ oidc:
500
+ subject_identifiers:
501
+ supported_types:
502
+ - pairwise
503
+ - public
504
+ pairwise:
505
+ salt: ory-agent-plugins-local-secret!!
506
+ dynamic_client_registration:
507
+ enabled: true
508
+ default_scope:
509
+ - openid
510
+ - offline_access
511
+
512
+ log:
513
+ level: debug
514
+ `;
515
+ }
516
+ // ─── Nginx Gateway ─────────────────────────────────────────────────
517
+ /**
518
+ * Nginx config that acts as a unified API gateway, replicating what
519
+ * Ory Network does: route all API paths to the correct backend service
520
+ * so the @ory/client SDK works with a single basePath.
521
+ */
522
+ function nginxConf() {
523
+ return `# Generated by @ory-agent-plugins — local development environment
524
+ # Do not edit manually; re-run "local up" to regenerate.
525
+
526
+ events {
527
+ worker_connections 256;
528
+ }
529
+
530
+ http {
531
+ resolver 127.0.0.11 valid=5s;
532
+
533
+ # Shared proxy settings
534
+ proxy_http_version 1.1;
535
+ proxy_set_header Host $host;
536
+ proxy_set_header X-Real-IP $remote_addr;
537
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
538
+ proxy_set_header X-Forwarded-Proto $scheme;
539
+
540
+ server {
541
+ listen 4000;
542
+ server_name localhost;
543
+
544
+ # ── Kratos public API ──────────────────────────────────
545
+ # Sessions (FrontendApi.toSession → GET /sessions/whoami)
546
+ location /sessions/ {
547
+ proxy_pass http://kratos:4433;
548
+ }
549
+
550
+ # Self-service flows (login, registration, etc.)
551
+ location /self-service/ {
552
+ proxy_pass http://kratos:4433;
553
+ }
554
+
555
+ # ── Kratos admin API ──────────────────────────────────
556
+ # Identity management
557
+ location /admin/identities {
558
+ proxy_pass http://kratos:4434;
559
+ }
560
+
561
+ # ── Hydra admin API ───────────────────────────────────
562
+ # Token introspection (OAuth2Api.introspectOAuth2Token → POST /admin/oauth2/introspect)
563
+ location /admin/oauth2/ {
564
+ proxy_pass http://hydra:4445;
565
+ }
566
+
567
+ # ── Hydra public API ──────────────────────────────────
568
+ location /oauth2/ {
569
+ proxy_pass http://hydra:4444;
570
+ }
571
+
572
+ location /.well-known/ {
573
+ proxy_pass http://hydra:4444;
574
+ }
575
+
576
+ # ── Keto read API ─────────────────────────────────────
577
+ # Permission checks (PermissionApi.checkPermission → GET /relation-tuples/check/openapi)
578
+ # Batch checks (PermissionApi.batchCheckPermission → POST /relation-tuples/batch-check)
579
+ # No trailing slash on the location so a bare GET /relation-tuples
580
+ # (the listing endpoint) also matches and proxies through.
581
+ location /relation-tuples {
582
+ proxy_pass http://keto:4466;
583
+ }
584
+
585
+ # ── Keto write API ────────────────────────────────────
586
+ # RelationshipApi.createRelationship issues PUT /admin/relation-tuples
587
+ # (no trailing slash), and deleteRelationships issues DELETE on the
588
+ # same path with query params. The location must match both the
589
+ # slashless form and any sub-path; dropping the trailing slash on
590
+ # the nginx location does both.
591
+ location /admin/relation-tuples {
592
+ proxy_pass http://keto:4467;
593
+ }
594
+
595
+ location /opl/ {
596
+ proxy_pass http://keto:4467;
597
+ }
598
+
599
+ # ── Gateway health ────────────────────────────────────
600
+ location /health {
601
+ default_type application/json;
602
+ return 200 '{"status":"ok","gateway":"ory-local"}';
603
+ }
604
+
605
+ # ── Fallback ──────────────────────────────────────────
606
+ location / {
607
+ default_type application/json;
608
+ return 404 '{"error":"not_found","message":"No Ory service handles this path"}';
609
+ }
610
+ }
611
+ }
612
+ `;
613
+ }
614
+ // ─── Default Ports ─────────────────────────────────────────────────
615
+ exports.GATEWAY_PORT = 4000;
616
+ exports.GATEWAY_URL = `http://localhost:${exports.GATEWAY_PORT}`;
617
+ exports.CONSOLE_PORT = 4100;
618
+ exports.CONSOLE_URL = `http://localhost:${exports.CONSOLE_PORT}`;
619
+ exports.LOGIN_UI_PORT = 3000;
620
+ exports.LOGIN_UI_URL = `http://localhost:${exports.LOGIN_UI_PORT}`;
621
+ exports.KRATOS_PUBLIC_PORT = 4433;
622
+ exports.KRATOS_ADMIN_PORT = 4434;
623
+ exports.KETO_READ_PORT = 4466;
624
+ exports.KETO_WRITE_PORT = 4467;
625
+ exports.HYDRA_PUBLIC_PORT = 4444;
626
+ exports.HYDRA_ADMIN_PORT = 4445;
627
+ exports.JAEGER_UI_PORT = 16686;
628
+ exports.JAEGER_OTLP_HTTP_PORT = 4318;
629
+ exports.JAEGER_UI_URL = `http://localhost:${exports.JAEGER_UI_PORT}`;
630
+ exports.JAEGER_OTLP_HTTP_URL = `http://localhost:${exports.JAEGER_OTLP_HTTP_PORT}`;
631
+ /** URL the manager probes to confirm the gateway is healthy. */
632
+ function gatewayHealthUrl() {
633
+ return `${exports.GATEWAY_URL}${getGatewayConfig().healthPath}`;
634
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Health-checking utilities for the local Ory development environment.
3
+ */
4
+ export interface ServiceHealth {
5
+ name: string;
6
+ url: string;
7
+ healthy: boolean;
8
+ error?: string;
9
+ }
10
+ /**
11
+ * Check the health of all local Ory services.
12
+ *
13
+ * `gatewayUrl` overrides the gateway probe URL (used by the manager after
14
+ * a runtime gateway-mode fallback, where re-resolving via env var would
15
+ * give a stale path). When omitted, falls back to env-var resolution
16
+ * anchored at `projectRoot`.
17
+ */
18
+ export declare function checkAllServices(options?: {
19
+ projectRoot?: string;
20
+ gatewayUrl?: string;
21
+ }): Promise<ServiceHealth[]>;
22
+ /**
23
+ * Wait for the gateway to become healthy, polling at the given interval.
24
+ * Returns true if healthy within the timeout, false otherwise.
25
+ *
26
+ * `gatewayUrl` overrides the probe URL (see `checkAllServices`). Otherwise
27
+ * the URL is computed from env-var resolution anchored at `projectRoot`.
28
+ */
29
+ export declare function waitForGateway(timeoutMs?: number, intervalMs?: number, options?: {
30
+ projectRoot?: string;
31
+ gatewayUrl?: string;
32
+ }): Promise<boolean>;