okengine 0.18.4 → 0.19.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/AGENTS.md +18 -10
- package/README.md +2 -2
- package/package.json +51 -50
- package/site/content/docs/ai/index.mdx +25 -6
- package/site/content/docs/ai/llms-txt.mdx +1 -1
- package/site/content/docs/ai/meta.json +1 -1
- package/site/content/docs/ai/skills.mdx +4 -1
- package/site/content/docs/ai/try-it.mdx +58 -0
- package/site/content/docs/client/auth.mdx +208 -0
- package/site/content/docs/client/calling.mdx +451 -0
- package/site/content/docs/client/index.mdx +209 -0
- package/site/content/docs/client/live.mdx +234 -0
- package/site/content/docs/client/meta.json +5 -0
- package/site/content/docs/client/react.mdx +249 -0
- package/site/content/docs/elements/ai/agents.mdx +232 -0
- package/site/content/docs/elements/ai/index.mdx +341 -0
- package/site/content/docs/elements/ai/mcp.mdx +275 -0
- package/site/content/docs/elements/ai/meta.json +5 -0
- package/site/content/docs/elements/ai/models.mdx +283 -0
- package/site/content/docs/elements/ai/prompts.mdx +256 -0
- package/site/content/docs/elements/channel/email.mdx +266 -0
- package/site/content/docs/elements/channel/index.mdx +344 -0
- package/site/content/docs/elements/channel/meta.json +5 -0
- package/site/content/docs/elements/channel/push.mdx +218 -0
- package/site/content/docs/elements/channel/receipts.mdx +206 -0
- package/site/content/docs/elements/channel/sms.mdx +264 -0
- package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
- package/site/content/docs/elements/clock/index.mdx +300 -0
- package/site/content/docs/elements/clock/meta.json +5 -0
- package/site/content/docs/elements/clock/schedules.mdx +508 -0
- package/site/content/docs/elements/clock/sleep.mdx +445 -0
- package/site/content/docs/elements/flow/consumers.mdx +707 -0
- package/site/content/docs/elements/flow/http.mdx +1080 -0
- package/site/content/docs/elements/flow/index.mdx +618 -0
- package/site/content/docs/elements/flow/meta.json +5 -0
- package/site/content/docs/elements/flow/routing.mdx +559 -0
- package/site/content/docs/elements/flow/workflows.mdx +640 -0
- package/site/content/docs/elements/gate/auth.mdx +371 -0
- package/site/content/docs/elements/gate/authorization.mdx +298 -0
- package/site/content/docs/elements/gate/index.mdx +418 -0
- package/site/content/docs/elements/gate/meta.json +5 -0
- package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
- package/site/content/docs/elements/gate/rls.mdx +303 -0
- package/site/content/docs/elements/gate/tenancy.mdx +372 -0
- package/site/content/docs/elements/index.mdx +52 -11
- package/site/content/docs/elements/signal/broadcast.mdx +517 -0
- package/site/content/docs/elements/signal/index.mdx +352 -0
- package/site/content/docs/elements/signal/live.mdx +590 -0
- package/site/content/docs/elements/signal/meta.json +5 -0
- package/site/content/docs/elements/signal/once.mdx +596 -0
- package/site/content/docs/elements/store/files.mdx +659 -0
- package/site/content/docs/elements/store/index.mdx +310 -0
- package/site/content/docs/elements/store/kv.mdx +629 -0
- package/site/content/docs/elements/store/meta.json +5 -0
- package/site/content/docs/elements/store/search.mdx +946 -0
- package/site/content/docs/elements/store/sql.mdx +937 -0
- package/site/content/docs/elements/vault/config.mdx +256 -0
- package/site/content/docs/elements/vault/index.mdx +356 -0
- package/site/content/docs/elements/vault/meta.json +5 -0
- package/site/content/docs/elements/vault/rotation.mdx +273 -0
- package/site/content/docs/elements/vault/secrets.mdx +285 -0
- package/site/content/docs/index.mdx +78 -30
- package/site/content/docs/meta.json +11 -8
- package/site/content/docs/plugins/cors.mdx +2 -1
- package/site/content/docs/plugins/csrf.mdx +4 -1
- package/site/content/docs/plugins/headers.mdx +2 -1
- package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
- package/site/content/docs/plugins/magic-link.mdx +6 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
- package/site/content/docs/plugins/oauth.mdx +1 -1
- package/site/content/docs/plugins/otp.mdx +12 -1
- package/site/content/docs/plugins/passkey.mdx +39 -15
- package/site/content/docs/plugins/two-factor.mdx +91 -34
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +3 -3
- package/site/content/docs/recipes/index.mdx +18 -28
- package/site/content/docs/recipes/mailpit.mdx +1 -1
- package/site/content/docs/recipes/meilisearch.mdx +3 -3
- package/site/content/docs/recipes/meta.json +1 -4
- package/site/content/docs/recipes/nginx.mdx +2 -2
- package/site/content/docs/recipes/openrouter.mdx +283 -0
- package/site/content/docs/recipes/pgdog.mdx +3 -3
- package/site/content/docs/recipes/postgres.mdx +1 -2
- package/site/content/docs/recipes/rustfs.mdx +2 -2
- package/site/content/docs/recipes/traefik.mdx +3 -3
- package/site/content/docs/reference/cli.mdx +231 -0
- package/site/content/docs/reference/configuration.mdx +30 -10
- package/site/content/docs/reference/environment-variables.mdx +93 -20
- package/site/content/docs/reference/errors.mdx +132 -29
- package/site/content/docs/reference/fx.mdx +137 -73
- package/site/content/docs/reference/index.mdx +13 -21
- package/site/content/docs/reference/meta.json +4 -5
- package/site/content/docs/reference/okid.mdx +42 -17
- package/site/content/docs/reference/plugins.mdx +4 -3
- package/site/content/docs/reference/security.mdx +197 -0
- package/site/content/docs/understand/meta.json +5 -0
- package/site/content/docs/understand/the-anatomy.mdx +132 -0
- package/site/content/docs/understand/the-model.mdx +32 -0
- package/site/content/docs/understand/the-problem.mdx +74 -0
- package/site/content/docs/understand/the-vocabulary.mdx +26 -0
- package/src/auth/api-keys.ts +2 -1
- package/src/auth/bindings.ts +64 -16
- package/src/auth/gate-auth.test.ts +6 -1
- package/src/auth/identity.ts +152 -5
- package/src/auth/index.ts +29 -0
- package/src/auth/invites.ts +2 -1
- package/src/auth/method-context.ts +41 -0
- package/src/auth/oauth-as/crypto.ts +2 -1
- package/src/auth/oauth-as/stores.ts +2 -1
- package/src/auth/operator.ts +2 -1
- package/src/auth/sessions-jwt.test.ts +77 -0
- package/src/auth/sessions.ts +20 -4
- package/src/auth/tenants.ts +3 -2
- package/src/auth/two-factor-challenge.test.ts +61 -0
- package/src/auth/two-factor-challenge.ts +284 -0
- package/src/auth/verification.ts +5 -0
- package/src/bench/REPORT.md +49 -0
- package/src/bench/g03-signal-once.bench.ts +1 -1
- package/src/bench/g10-observability-contention.bench.ts +1 -1
- package/src/bench/g17-hybrid-search.bench.ts +572 -0
- package/src/bench/load-app.ts +2 -10
- package/src/cli/ai-setup/ai-setup.test.ts +331 -42
- package/src/cli/ai-setup/apply.ts +294 -52
- package/src/cli/ai-setup/catalog.ts +238 -1342
- package/src/cli/ai-setup/index.ts +14 -99
- package/src/cli/ai-setup/prompts.ts +60 -443
- package/src/cli/ask-seed.test.ts +96 -0
- package/src/cli/ask-seed.ts +82 -0
- package/src/cli/ask-vault-gaps.test.ts +84 -0
- package/src/cli/ask-vault-gaps.ts +146 -0
- package/src/cli/build.ts +2 -2
- package/src/cli/client-add.test.ts +26 -1
- package/src/cli/client-add.ts +106 -27
- package/src/cli/competitor-mention-removal.test.ts +1 -1
- package/src/cli/db-seed.ts +2 -0
- package/src/cli/db.ts +150 -11
- package/src/cli/dev.ts +119 -211
- package/src/cli/docker-clean.ts +2 -2
- package/src/cli/docker-cli.test.ts +1 -1
- package/src/cli/doctor-diff.ts +4 -2
- package/src/cli/doctor-pii.test.ts +1 -1
- package/src/cli/doctor.ts +14 -1
- package/src/cli/hero-meta.test.ts +4 -2
- package/src/cli/load-config.images.test.ts +8 -10
- package/src/cli/load-config.ts +1 -1
- package/src/cli/registry.ts +22 -10
- package/src/cli/replay.ts +3 -1
- package/src/cli/start.ts +1 -1
- package/src/cli/tui/keys.ts +2 -3
- package/src/client/auth/cookies.ts +74 -0
- package/src/client/auth/create-auth-client.ts +636 -0
- package/src/client/auth/denials.ts +99 -0
- package/src/client/auth/session.ts +283 -0
- package/src/client/auth.test.ts +251 -0
- package/src/client/auth.ts +39 -114
- package/src/client/create-with-session.ts +245 -0
- package/src/client/create.ts +51 -5
- package/src/client/index.ts +11 -1
- package/src/client/live.ts +11 -79
- package/src/client/notes-contract.test.ts +5 -10
- package/src/client/sse.ts +137 -0
- package/src/client/stream.ts +147 -0
- package/src/client/transport.test.ts +32 -0
- package/src/client/transport.ts +123 -26
- package/src/client/types.ts +118 -14
- package/src/client-react/index.ts +185 -24
- package/src/client-react/use-live-query.ts +13 -3
- package/src/compiler/aot.test.ts +7 -4
- package/src/compiler/effects-embed.test.ts +56 -0
- package/src/compiler/effects-fetch.test.ts +43 -0
- package/src/compiler/effects-infer.ts +58 -2
- package/src/compiler/extract.test.ts +258 -44
- package/src/compiler/extract.ts +566 -48
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
- package/src/compiler/fixtures/skyport.expected.json +4 -4
- package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
- package/src/compiler/response.ts +2 -2
- package/src/compiler/search-writer-isolation.test.ts +40 -0
- package/src/config/index.ts +11 -0
- package/src/console/server/app.ts +17 -23
- package/src/console/server/bind.ts +4 -0
- package/src/console/server/console.test.ts +2 -2
- package/src/console/server/flows-invoke.test.ts +50 -34
- package/src/console/server/flows.ts +436 -255
- package/src/console/server/runs-ingest.test.ts +6 -3
- package/src/console/server/serve.ts +1 -1
- package/src/console/server/signals.test.ts +1 -5
- package/src/console/server/signals.ts +8 -6
- package/src/console/server/state.ts +6 -1
- package/src/console/server/store.ts +1 -1
- package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
- package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
- package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
- package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
- package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
- package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
- package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
- package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
- package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
- package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
- package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
- package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
- package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
- package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
- package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
- package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
- package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
- package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
- package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
- package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
- package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
- package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
- package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
- package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
- package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
- package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
- package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
- package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
- package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
- package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
- package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
- package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
- package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
- package/src/console/ui-next/dist/index.html +6 -13
- package/src/console/ui-next/seed-invoke-host.ts +21 -18
- package/src/console/ui-next/src/client.ts +7 -2
- package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
- package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
- package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
- package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
- package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
- package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
- package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
- package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
- package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
- package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
- package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
- package/src/docker/ai-model-status.test.ts +1 -12
- package/src/docker/ai-model-status.ts +10 -38
- package/src/docker/compose-up.test.ts +100 -0
- package/src/docker/compose-up.ts +292 -0
- package/src/docker/compose.ts +4 -14
- package/src/docker/derive.ts +9 -34
- package/src/docker/docker.test.ts +16 -261
- package/src/docker/images-config.test.ts +13 -25
- package/src/docker/index.ts +1 -24
- package/src/docker/recipes/index.ts +0 -23
- package/src/docker/recipes/pgdog.ts +6 -4
- package/src/docker/stack-id.test.ts +2 -2
- package/src/docker/stack-id.ts +0 -1
- package/src/docker/types.ts +2 -2
- package/src/drivers/ai-anthropic.ts +10 -0
- package/src/drivers/ai-openai-compatible.ts +34 -7
- package/src/drivers/ai-providers.test.ts +0 -107
- package/src/drivers/ai-stream.test.ts +0 -34
- package/src/drivers/ai-types.ts +17 -8
- package/src/drivers/channel-fcm.ts +6 -1
- package/src/drivers/channel-msegat.ts +6 -1
- package/src/drivers/channel-resend.ts +5 -1
- package/src/drivers/channel-smtp.ts +5 -1
- package/src/drivers/channel-sndr.ts +10 -1
- package/src/drivers/channel-taqnyat-mail.ts +5 -1
- package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
- package/src/drivers/channel-taqnyat.ts +6 -1
- package/src/drivers/channel-types.ts +10 -0
- package/src/drivers/channel-unifonic.ts +6 -1
- package/src/drivers/channel-wa-cloud.ts +6 -1
- package/src/drivers/channel-webpush.ts +6 -1
- package/src/drivers/external.ts +33 -0
- package/src/drivers/index.ts +0 -10
- package/src/drivers/meilisearch.ts +6 -0
- package/src/drivers/oauth-types.ts +4 -0
- package/src/drivers/postgres.test.ts +74 -3
- package/src/drivers/postgres.ts +175 -6
- package/src/drivers/signal-types.ts +5 -5
- package/src/drivers/types.ts +7 -0
- package/src/drivers/vault-types.ts +5 -0
- package/src/elements/ai/declare.ts +17 -4
- package/src/elements/ai/eval.ts +1 -1
- package/src/elements/ai/mcp-http.ts +1 -1
- package/src/elements/ai/pii.ts +1 -1
- package/src/elements/ai/providers.test.ts +289 -0
- package/src/elements/ai/providers.ts +169 -0
- package/src/elements/ai/runtime.ts +68 -5
- package/src/elements/ai/schema.ts +2 -2
- package/src/elements/ai.test.ts +7 -7
- package/src/elements/ai.ts +17 -1
- package/src/elements/channel/runtime.ts +105 -12
- package/src/elements/clock/cron-fields.test.ts +144 -0
- package/src/elements/clock/cron-fields.ts +185 -0
- package/src/elements/clock/declare.ts +247 -3
- package/src/elements/clock.ts +21 -1
- package/src/elements/index.ts +15 -0
- package/src/elements/signal/chaos-child.ts +1 -2
- package/src/elements/signal/declare.ts +65 -37
- package/src/elements/signal/delivery-modes.test.ts +11 -31
- package/src/elements/signal/dry-run-replay.test.ts +1 -7
- package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
- package/src/elements/signal/key-ordering.test.ts +6 -26
- package/src/elements/signal/lease-reclaim.test.ts +2 -6
- package/src/elements/signal/optional-emit.test.ts +6 -9
- package/src/elements/signal/order-lifecycle.test.ts +4 -17
- package/src/elements/signal/orphan-messages.test.ts +4 -15
- package/src/elements/signal/reconcile.test.ts +2 -2
- package/src/elements/signal/runtime.ts +1 -1
- package/src/elements/signal/schema-emit.test.ts +4 -8
- package/src/elements/signal.test.ts +24 -49
- package/src/elements/signal.ts +9 -2
- package/src/elements/store/domain-ddl.test.ts +1 -1
- package/src/elements/store/live-http.test.ts +9 -4
- package/src/elements/store/prepare-row.test.ts +123 -0
- package/src/elements/store/resource.ts +43 -12
- package/src/elements/store/schema-decl.ts +117 -0
- package/src/elements/store/search-backfill.ts +205 -0
- package/src/elements/store/search-bind.ts +66 -0
- package/src/elements/store/search-bm25.ts +78 -0
- package/src/elements/store/search-ddl.ts +156 -0
- package/src/elements/store/search-embed-flow.ts +141 -0
- package/src/elements/store/search-errors.ts +34 -0
- package/src/elements/store/search-fusion.ts +112 -0
- package/src/elements/store/search-lsh.ts +179 -0
- package/src/elements/store/search-runtime.ts +300 -0
- package/src/elements/store/search.test.ts +144 -0
- package/src/elements/store/sql-session.test.ts +1 -0
- package/src/elements/store/sql-session.ts +83 -3
- package/src/elements/store/table.ts +23 -2
- package/src/elements/store/upsert-app.test.ts +1 -3
- package/src/elements/store.ts +50 -0
- package/src/full.ts +4 -2
- package/src/http.ts +4 -1
- package/src/i18n/catalogs/ar.ts +14 -6
- package/src/i18n/catalogs/en.ts +14 -6
- package/src/index.ts +6 -1
- package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
- package/src/kernel/adopt-routes.ts +9 -1
- package/src/kernel/app-auth.ts +5 -0
- package/src/kernel/app.ts +102 -9
- package/src/kernel/auto-cache.test.ts +6 -12
- package/src/kernel/auto-registry.test.ts +3 -3
- package/src/kernel/boot-bind/ai.test.ts +22 -19
- package/src/kernel/boot-bind/ai.ts +5 -43
- package/src/kernel/boot-bind/clock.ts +23 -5
- package/src/kernel/boot-bind/honor-config.test.ts +4 -4
- package/src/kernel/boot.test.ts +11 -6
- package/src/kernel/boot.ts +66 -16
- package/src/kernel/boundary-contract.ts +93 -0
- package/src/kernel/budget.test.ts +1 -1
- package/src/kernel/call.ts +89 -0
- package/src/kernel/capability.ts +6 -0
- package/src/kernel/client-descriptor.ts +123 -0
- package/src/kernel/clock-timezone.test.ts +80 -0
- package/src/kernel/correlation.test.ts +1 -1
- package/src/kernel/dry-run.ts +11 -8
- package/src/kernel/effects-stamping.test.ts +42 -9
- package/src/kernel/effects.test.ts +4 -2
- package/src/kernel/effects.ts +51 -9
- package/src/kernel/errors-channel.ts +17 -0
- package/src/kernel/errors-live-resume.ts +3 -2
- package/src/kernel/errors-tenant.ts +7 -4
- package/src/kernel/errors.registry-helpers.ts +96 -0
- package/src/kernel/errors.registry.test.ts +139 -25
- package/src/kernel/errors.ts +102 -23
- package/src/kernel/external-effects.test.ts +196 -0
- package/src/kernel/flow.test.ts +13 -4
- package/src/kernel/flow.ts +69 -71
- package/src/kernel/fx-ask-telemetry.test.ts +2 -2
- package/src/kernel/fx-dead-letters.test.ts +3 -3
- package/src/kernel/fx-fetch.ts +55 -0
- package/src/kernel/fx-live-stream.ts +2 -2
- package/src/kernel/fx-live.test.ts +8 -8
- package/src/kernel/fx.test.ts +17 -11
- package/src/kernel/fx.ts +180 -57
- package/src/kernel/horizontal-child.ts +1 -1
- package/src/kernel/http-query.test.ts +3 -6
- package/src/kernel/index.ts +13 -3
- package/src/kernel/instance-id.ts +1 -1
- package/src/kernel/instances.test.ts +40 -0
- package/src/kernel/instances.ts +47 -9
- package/src/kernel/live-http.test.ts +6 -7
- package/src/kernel/live-http.ts +6 -2
- package/src/kernel/live-resume.test.ts +1 -1
- package/src/kernel/mcp-tool.test.ts +3 -3
- package/src/kernel/on.ts +98 -4
- package/src/kernel/pipeline.test.ts +12 -15
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/stamp-http.test.ts +3 -3
- package/src/kernel/triggers.ts +210 -95
- package/src/kernel-entry.ts +0 -1
- package/src/manifest/diff.ts +11 -1
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/types.ts +46 -2
- package/src/mcp/docs-index.ts +3 -3
- package/src/mcp/docs-mcp.test.ts +2 -2
- package/src/mcp/docs-tools.ts +1 -1
- package/src/okid.test.ts +56 -0
- package/src/okid.ts +55 -11
- package/src/plugins/anonymous.ts +8 -4
- package/src/plugins/auth/shared.ts +27 -3
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/auth-methods.security.test.ts +561 -23
- package/src/plugins/config-source.ts +1 -1
- package/src/plugins/csrf.test.ts +65 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/magic-link.ts +36 -16
- package/src/plugins/oauth/shared.ts +3 -1
- package/src/plugins/oauth.ts +22 -14
- package/src/plugins/otp.ts +37 -21
- package/src/plugins/passkey-webauthn.ts +9 -6
- package/src/plugins/passkey.ts +98 -26
- package/src/plugins/pre-account-hijack.test.ts +223 -0
- package/src/plugins/two-factor.ts +466 -37
- package/src/plugins/username.ts +19 -7
- package/src/release/build-lib.ts +1 -0
- package/src/release/limits.ts +2 -2
- package/src/release/measure.ts +1 -1
- package/src/runs/collect.test.ts +0 -2
- package/src/runtime/json-code-block.test.ts +250 -20
- package/src/runtime/json-code-block.ts +1261 -41
- package/src/term.test.ts +1 -1
- package/src/test/create-test-app.test.ts +12 -12
- package/src/test/live-signals.test.ts +6 -6
- package/src/test/provisions.integration.test.ts +10 -14
- package/src/test/reset-element-registries.ts +1 -1
- package/src/test/tenant-isolation.test.ts +12 -6
- package/site/content/docs/deployment/docker-swarm.mdx +0 -164
- package/site/content/docs/deployment/docker.mdx +0 -227
- package/site/content/docs/deployment/index.mdx +0 -83
- package/site/content/docs/deployment/kubernetes.mdx +0 -176
- package/site/content/docs/deployment/meta.json +0 -5
- package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
- package/site/content/docs/elements/ai.mdx +0 -385
- package/site/content/docs/elements/channel.mdx +0 -346
- package/site/content/docs/elements/clock.mdx +0 -244
- package/site/content/docs/elements/flow.mdx +0 -420
- package/site/content/docs/elements/gate.mdx +0 -436
- package/site/content/docs/elements/signal.mdx +0 -380
- package/site/content/docs/elements/store.mdx +0 -1099
- package/site/content/docs/elements/vault.mdx +0 -405
- package/site/content/docs/get-started/basic-usage.mdx +0 -173
- package/site/content/docs/get-started/index.mdx +0 -43
- package/site/content/docs/get-started/installation.mdx +0 -220
- package/site/content/docs/get-started/introduction.mdx +0 -132
- package/site/content/docs/get-started/meta.json +0 -13
- package/site/content/docs/get-started/project-structure.mdx +0 -925
- package/site/content/docs/get-started/testing.mdx +0 -328
- package/site/content/docs/get-started/why.mdx +0 -162
- package/site/content/docs/recipes/llama-cpp.mdx +0 -151
- package/site/content/docs/recipes/ollama.mdx +0 -142
- package/site/content/docs/recipes/sglang.mdx +0 -105
- package/site/content/docs/recipes/vllm.mdx +0 -106
- package/site/content/docs/reference/cli.md +0 -232
- package/site/content/docs/reference/client.mdx +0 -469
- package/site/content/docs/reference/security.md +0 -74
- package/src/cli/ai-setup/detect-ollama.ts +0 -213
- package/src/cli/ai-setup/recommend.test.ts +0 -225
- package/src/cli/ai-setup/recommend.ts +0 -225
- package/src/cli/dev-controls.test.ts +0 -122
- package/src/cli/dev-controls.ts +0 -164
- package/src/cli/tui/DevLive.tsx +0 -126
- package/src/console/ui-next/dist/assets/access-page-De7Lc2JC.js +0 -4
- package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
- package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
- package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
- package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
- package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
- package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
- package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
- package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
- package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
- package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
- package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
- package/src/console/ui-next/dist/assets/flows-page-RGy7VEA_.js +0 -1
- package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
- package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
- package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
- package/src/console/ui-next/dist/assets/index-_rgpdVzo.js +0 -66
- package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
- package/src/console/ui-next/dist/assets/observability-page-Ds6pcnh-.js +0 -4
- package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
- package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
- package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
- package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
- package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
- package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
- package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
- package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
- package/src/console/ui-next/dist/assets/units-page-4rHOePuE.js +0 -1
- package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
- package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
- package/src/console/ui-next/dist/assets/vault-page-DISPgxLM.js +0 -2
- package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
- package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
- package/src/docker/ollama-pull.ts +0 -232
- package/src/docker/recipes/llama-cpp.ts +0 -298
- package/src/docker/recipes/ollama.ts +0 -44
- package/src/docker/recipes/sglang.ts +0 -55
- package/src/docker/recipes/vllm.ts +0 -44
- package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
- package/src/drivers/ai-ollama.integration.test.ts +0 -184
- package/src/drivers/ai-ollama.ts +0 -389
- package/src/drivers/ollama.ts +0 -14
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Overview"
|
|
3
|
+
description: "Permission to act — policy and rate gates on the trigger, left to right, first denial wins."
|
|
4
|
+
icon: "ShieldCheck"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Gate is how your backend **decides whether a caller may run a Flow**. Policies and rate limits
|
|
9
|
+
attach to the trigger with `.gate(...)`. Identity comes from `oke({ gate: { auth } })` into
|
|
10
|
+
`fx.auth`; Gate policies read that principal — they do not invent a separate middleware layer.
|
|
11
|
+
|
|
12
|
+
For developers protecting APIs on okengine — declare the check, chain it on the trigger, keep
|
|
13
|
+
`do` behind the first denial.
|
|
14
|
+
|
|
15
|
+
<Callout title="The one rule">
|
|
16
|
+
**First denial wins.** Gates on a trigger evaluate left to right. The first reject stops the chain
|
|
17
|
+
— later gates are skipped, and `do` never runs.
|
|
18
|
+
</Callout>
|
|
19
|
+
|
|
20
|
+
<GatePipeline />
|
|
21
|
+
|
|
22
|
+
## Smallest Example
|
|
23
|
+
|
|
24
|
+
<Steps>
|
|
25
|
+
|
|
26
|
+
<Step>
|
|
27
|
+
### Declare a policy and attach it
|
|
28
|
+
|
|
29
|
+
```typescript title="src/core/gate.ts"
|
|
30
|
+
import { gate } from "okengine";
|
|
31
|
+
|
|
32
|
+
export const member = gate.policy("member", {
|
|
33
|
+
description: "Signed-in workspace member",
|
|
34
|
+
check: ({ auth }) => !!auth.verified,
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```typescript title="src/flows/profile/get.ts"
|
|
39
|
+
import { on, flow, http } from "okengine";
|
|
40
|
+
import { member } from "@/core/gate";
|
|
41
|
+
|
|
42
|
+
export const get = on(
|
|
43
|
+
http.get().gate(member),
|
|
44
|
+
flow({
|
|
45
|
+
do: async (_, fx) => ({ userId: fx.auth.userId }),
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
</Step>
|
|
51
|
+
|
|
52
|
+
<Step>
|
|
53
|
+
### Call with and without a session
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Anonymous → 401 Unauthorized (policy denied, no userId)
|
|
57
|
+
curl -X GET http://localhost:6530/profile -H "accept: application/json"
|
|
58
|
+
|
|
59
|
+
# Signed-in → 200 with principal
|
|
60
|
+
curl -X GET http://localhost:6530/profile \
|
|
61
|
+
-H "accept: application/json" \
|
|
62
|
+
-H "authorization: Bearer …"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Anonymous denial envelope:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"data": null,
|
|
70
|
+
"error": { "code": "Unauthorized", "message": "Authentication required.", "data": {} }
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
</Step>
|
|
75
|
+
|
|
76
|
+
</Steps>
|
|
77
|
+
|
|
78
|
+
<Callout title="Auth posture is required">
|
|
79
|
+
Every HTTP (and MCP tool) trigger must declare a gate chain **or** `.public()`. Omitting both
|
|
80
|
+
fails boot with `GateBootError`. See [Boot Posture](#boot-posture).
|
|
81
|
+
</Callout>
|
|
82
|
+
|
|
83
|
+
## Progressive Patterns
|
|
84
|
+
|
|
85
|
+
From a single policy to scopes, rates, and reusable chains:
|
|
86
|
+
|
|
87
|
+
<Tabs items={["Policy", "Scope", "Rate", "Compose"]}>
|
|
88
|
+
|
|
89
|
+
<Tab value="Policy">
|
|
90
|
+
|
|
91
|
+
Named ABAC check over `auth` / `operator` / optional `meta`:
|
|
92
|
+
|
|
93
|
+
```typescript title="src/core/gate.ts"
|
|
94
|
+
import { gate } from "okengine";
|
|
95
|
+
|
|
96
|
+
export const member = gate.policy("member", ({ auth }) => !!auth.verified);
|
|
97
|
+
|
|
98
|
+
export const adminOnly = gate.policy("adminOnly", {
|
|
99
|
+
description: "Admin scope required",
|
|
100
|
+
check: ({ auth }) => auth.scopes.has("admin"),
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Both forms are valid: a bare predicate, or `{ check, description? }`.
|
|
105
|
+
|
|
106
|
+
</Tab>
|
|
107
|
+
|
|
108
|
+
<Tab value="Scope">
|
|
109
|
+
|
|
110
|
+
`gate.scope(name)` is shorthand for
|
|
111
|
+
`gate.policy(name, ({ auth }) => auth.scopes.has(name))` with `scopes: [name]` recorded:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
export const notesWrite = gate.scope("notes:write");
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Consequence:** the scope string is the policy id — one source of truth for Manifest and Console.
|
|
118
|
+
|
|
119
|
+
</Tab>
|
|
120
|
+
|
|
121
|
+
<Tab value="Rate">
|
|
122
|
+
|
|
123
|
+
KV-backed throttle. Pass one options object — there is no `gate.rate(name, { limit })` form:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
export const notesWriteRate = gate.rate({
|
|
127
|
+
max: 60,
|
|
128
|
+
per: "1m",
|
|
129
|
+
keyBy: "user",
|
|
130
|
+
description: "Note write throttle",
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Default strategy is `sliding-window-counter`. See [Rate Limits](/docs/elements/gate/rate-limits).
|
|
135
|
+
|
|
136
|
+
</Tab>
|
|
137
|
+
|
|
138
|
+
<Tab value="Compose">
|
|
139
|
+
|
|
140
|
+
`gate.all` builds a reusable chain. Nested `all` handles flatten at `.gate(...)`:
|
|
141
|
+
|
|
142
|
+
```typescript title="src/core/gate.ts"
|
|
143
|
+
import { gate } from "okengine";
|
|
144
|
+
|
|
145
|
+
export const member = gate.policy("member", ({ auth }) => !!auth.verified);
|
|
146
|
+
export const notesWrite = gate.scope("notes:write");
|
|
147
|
+
export const notesWriteRate = gate.rate({ max: 60, per: "1m", keyBy: "user" });
|
|
148
|
+
|
|
149
|
+
export const notesMutate = gate.all(member, notesWrite, notesWriteRate);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```typescript title="src/flows/notes/create.ts"
|
|
153
|
+
import { on, flow, http } from "okengine";
|
|
154
|
+
import { notesMutate } from "@/core/gate";
|
|
155
|
+
|
|
156
|
+
export const create = on(
|
|
157
|
+
http.post().gate(notesMutate),
|
|
158
|
+
// or: .gate(member, notesWrite, notesWriteRate)
|
|
159
|
+
flow({
|
|
160
|
+
do: async (input, fx) => fx.json.create({ id: fx.id(), ...input }),
|
|
161
|
+
}),
|
|
162
|
+
);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
</Tab>
|
|
166
|
+
|
|
167
|
+
</Tabs>
|
|
168
|
+
|
|
169
|
+
## Declaration Reference
|
|
170
|
+
|
|
171
|
+
| Declaration | Signature | Purpose |
|
|
172
|
+
| ------------- | ----------------------------------------------------- | -------------------------------------- |
|
|
173
|
+
| `gate.policy` | `gate.policy(name, check \| { check, description? })` | Named ABAC / auth predicate |
|
|
174
|
+
| `gate.scope` | `gate.scope(name)` | Require `auth.scopes.has(name)` |
|
|
175
|
+
| `gate.public` | `gate.public` (handle) | Intentionally unauthenticated sentinel |
|
|
176
|
+
| `gate.rate` | `gate.rate({ max, per, keyBy?, … })` | KV-backed throttle |
|
|
177
|
+
| `gate.all` | `gate.all(...members)` | Reusable left-to-right chain |
|
|
178
|
+
|
|
179
|
+
| `oke({ gate })` option | Type | Default | Meaning |
|
|
180
|
+
| ---------------------- | --------------------- | ------------------- | --------------------------------------------------------------------------------- |
|
|
181
|
+
| `auth` | bag / omitted | off | Sessions, keys, optional tenancy — see [Authentication](/docs/elements/gate/auth) |
|
|
182
|
+
| `policies` | decls / `all` handles | auto from registry | Explicit bag; usually unnecessary |
|
|
183
|
+
| `rateLimit.enabled` | `boolean` | `true` when auth on | Stricter presets on auth Flows |
|
|
184
|
+
| `unguardedHttp` | `"deny"` \| `"allow"` | `"deny"` | `"allow"` only when `env === "test"` |
|
|
185
|
+
|
|
186
|
+
## Attaching Gates
|
|
187
|
+
|
|
188
|
+
Gates chain on the **trigger**, not on a `gates: [...]` field inside `flow()`:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
http.post().gate(member, gate.scope("editor"), gate.rate({ max: 100, per: "1m", keyBy: "user" }));
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Public** — open the route without authentication:
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
http.get().public();
|
|
198
|
+
// equivalent: http.get().gate(gate.public)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Resource mounts accept `.gate(...)` / `.public()` once — every CRUD verb (and live, when
|
|
202
|
+
present) gets the same chain. See [HTTP · Resources](/docs/elements/flow/http#resources).
|
|
203
|
+
|
|
204
|
+
## Evaluation Order
|
|
205
|
+
|
|
206
|
+
<Callout title="Detailed section">
|
|
207
|
+
If you only need “attach and go”, the Smallest Example is enough. This section is the walk the
|
|
208
|
+
runtime takes before `do`.
|
|
209
|
+
</Callout>
|
|
210
|
+
|
|
211
|
+
On each request the pipeline:
|
|
212
|
+
|
|
213
|
+
1. Resolves identity into `fx.auth` (Bearer / cookie / API key when `gate.auth` is on).
|
|
214
|
+
2. Resolves `fx.tenant.id` when `gate.auth.tenant` is enabled.
|
|
215
|
+
3. Evaluates the trigger’s gate names **in declaration order**.
|
|
216
|
+
4. Stops on the first denial — maps to a typed envelope; later gates never run.
|
|
217
|
+
5. Invokes `do` only when every gate allowed.
|
|
218
|
+
|
|
219
|
+
```typescript title="src/flows/notes/create.ts"
|
|
220
|
+
import { on, flow, http, gate } from "okengine";
|
|
221
|
+
|
|
222
|
+
const member = gate.policy("member", ({ auth }) => !!auth.verified);
|
|
223
|
+
const write = gate.scope("notes:write");
|
|
224
|
+
const throttle = gate.rate({ max: 60, per: "1m", keyBy: "user" });
|
|
225
|
+
|
|
226
|
+
// Order matters: identity → capability → quota
|
|
227
|
+
export const create = on(
|
|
228
|
+
http.post().gate(member, write, throttle),
|
|
229
|
+
flow({
|
|
230
|
+
do: async (input, fx) => fx.json.create({ id: fx.id(), ...input }),
|
|
231
|
+
}),
|
|
232
|
+
);
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
| Caller | First denial | Later gates |
|
|
236
|
+
| ------------------------------- | -------------------------- | ---------------------------- |
|
|
237
|
+
| Anonymous | `member` → `Unauthorized` | `write` / `throttle` skipped |
|
|
238
|
+
| Signed-in, no `notes:write` | `write` → `Forbidden` | `throttle` skipped |
|
|
239
|
+
| Signed-in + scope, quota burned | `throttle` → `RateLimited` | — |
|
|
240
|
+
| All pass | — | `do` runs |
|
|
241
|
+
|
|
242
|
+
**Consequence:** put identity policies **before** rates so anonymous traffic 401s instead of
|
|
243
|
+
burning a shared `"anon"` quota under `keyBy: "user"`.
|
|
244
|
+
|
|
245
|
+
<Accordions>
|
|
246
|
+
|
|
247
|
+
<Accordion title="What policies may read">
|
|
248
|
+
Predicates receive `GatePolicyContext` only — `auth`, `operator`, optional `meta` (`ip`, `userId`,
|
|
249
|
+
…). They must not touch Store, Vault, or the network. World access stays in `do` via `fx`. See
|
|
250
|
+
[Authorization](/docs/elements/gate/authorization).
|
|
251
|
+
</Accordion>
|
|
252
|
+
|
|
253
|
+
<Accordion title="Rate evaluation fields">
|
|
254
|
+
A rate take records `remaining` and `retryAfterMs` on the evaluation. A burn maps to
|
|
255
|
+
`RateLimited` with `{ retryAfterMs }` in `error.data`.
|
|
256
|
+
|
|
257
|
+
Missing KV still uses kind `rate` → typed `RateLimited` (often `retryAfterMs: 0`);
|
|
258
|
+
telemetry reason is `"rate gate requires kv"`.
|
|
259
|
+
|
|
260
|
+
</Accordion>
|
|
261
|
+
|
|
262
|
+
<Accordion title="Unknown gate names">
|
|
263
|
+
A name that is not registered denies with reason `unknown gate: …`. Prefer attaching the declared
|
|
264
|
+
handle (`member`) rather than a raw string so the registry always knows the predicate.
|
|
265
|
+
</Accordion>
|
|
266
|
+
|
|
267
|
+
</Accordions>
|
|
268
|
+
|
|
269
|
+
## Denial Mapping
|
|
270
|
+
|
|
271
|
+
Denials are typed error values — never thrown stacks mid-pipeline:
|
|
272
|
+
|
|
273
|
+
| Situation | Code | Status | Typical `error.data` |
|
|
274
|
+
| -------------------------------- | -------------- | ------ | ---------------------------------- |
|
|
275
|
+
| Policy denied, no `auth.userId` | `Unauthorized` | 401 | `{}` |
|
|
276
|
+
| Policy denied, principal present | `Forbidden` | 403 | `{ gate, reason }` |
|
|
277
|
+
| Rate gate burned / no KV | `RateLimited` | 429 | `{ retryAfterMs }` |
|
|
278
|
+
| Tenant required / not a member | `Forbidden` | 403 | `{ gate: "auth:tenants", reason }` |
|
|
279
|
+
|
|
280
|
+
Authenticated policy denial:
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"data": null,
|
|
285
|
+
"error": {
|
|
286
|
+
"code": "Forbidden",
|
|
287
|
+
"message": "You are not allowed to perform this action.",
|
|
288
|
+
"data": { "gate": "notes:write", "reason": "policy denied" }
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Rate burn:
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
{
|
|
297
|
+
"data": null,
|
|
298
|
+
"error": {
|
|
299
|
+
"code": "RateLimited",
|
|
300
|
+
"message": "Too many requests. Try again later.",
|
|
301
|
+
"data": { "retryAfterMs": 42000 }
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Boot Posture
|
|
307
|
+
|
|
308
|
+
Every HTTP and MCP-tool trigger must carry at least one gate (including `gate.public`) or
|
|
309
|
+
`.public()`. Missing posture throws `GateBootError` listing every gap:
|
|
310
|
+
|
|
311
|
+
```text
|
|
312
|
+
gate boot failed — 2 trigger(s) missing auth posture (attach a gate or .public()):
|
|
313
|
+
- notes.list GET /notes
|
|
314
|
+
- notes.create POST /notes
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
`unguardedHttp: "allow"` skips the audit **only** when `env === "test"`. Outside test it has no
|
|
318
|
+
effect — migrate real apps with per-trigger `.public()`.
|
|
319
|
+
|
|
320
|
+
MCP tools follow the same rule: a tool trigger with an empty gate list fails the same boot
|
|
321
|
+
audit (listed as `mcp` + tool name).
|
|
322
|
+
|
|
323
|
+
## The Capabilities of Gate
|
|
324
|
+
|
|
325
|
+
<Cards>
|
|
326
|
+
<Card
|
|
327
|
+
title="Authentication"
|
|
328
|
+
description="Enable gate.auth, populate fx.auth, then protect Flows with policies."
|
|
329
|
+
href="/docs/elements/gate/auth"
|
|
330
|
+
/>
|
|
331
|
+
<Card
|
|
332
|
+
title="Authorization Policies"
|
|
333
|
+
description="gate.policy and gate.scope for RBAC / ABAC; compose with gate.all."
|
|
334
|
+
href="/docs/elements/gate/authorization"
|
|
335
|
+
/>
|
|
336
|
+
<Card
|
|
337
|
+
title="RLS"
|
|
338
|
+
description="Stamp Gate identity into SQL — store.schema.policy helpers filter rows."
|
|
339
|
+
href="/docs/elements/gate/rls"
|
|
340
|
+
/>
|
|
341
|
+
<Card
|
|
342
|
+
title="Rate Limits"
|
|
343
|
+
description="gate.rate with five KV strategies — sliding-window-counter by default."
|
|
344
|
+
href="/docs/elements/gate/rate-limits"
|
|
345
|
+
/>
|
|
346
|
+
<Card
|
|
347
|
+
title="Tenancy"
|
|
348
|
+
description="Opt into gate.auth.tenant and read fx.tenant.id for isolation."
|
|
349
|
+
href="/docs/elements/gate/tenancy"
|
|
350
|
+
/>
|
|
351
|
+
</Cards>
|
|
352
|
+
|
|
353
|
+
## Troubleshooting
|
|
354
|
+
|
|
355
|
+
<Accordions>
|
|
356
|
+
|
|
357
|
+
<Accordion title="GateBootError — missing auth posture">
|
|
358
|
+
Cause: `gate boot failed — N trigger(s) missing auth posture (attach a gate or .public()):`. Every
|
|
359
|
+
listed HTTP/MCP trigger needs `.gate(...)` or `.public()`. `unguardedHttp: "allow"` only works
|
|
360
|
+
when `env === "test"`.
|
|
361
|
+
</Accordion>
|
|
362
|
+
|
|
363
|
+
<Accordion title="401 Unauthorized on a gated route">
|
|
364
|
+
A policy denied and `auth.userId` is null — or Bearer forge / expiry mapped to `Unauthorized`
|
|
365
|
+
before gates. Send a valid Bearer (or cookie when enabled), or mark the route `.public()` if it
|
|
366
|
+
should be open.
|
|
367
|
+
</Accordion>
|
|
368
|
+
|
|
369
|
+
<Accordion title="403 Forbidden with gate + reason">
|
|
370
|
+
The principal is authenticated but failed a later policy (`error.data.gate` names it). Check
|
|
371
|
+
scopes on the session / API key, or the predicate in that policy.
|
|
372
|
+
</Accordion>
|
|
373
|
+
|
|
374
|
+
<Accordion title="429 RateLimited with retryAfterMs">
|
|
375
|
+
A `gate.rate` burned its quota (or ran without KV). Wait `retryAfterMs`, raise `max` / widen
|
|
376
|
+
`per`, or configure a KV driver when reason telemetry shows `"rate gate requires kv"`.
|
|
377
|
+
</Accordion>
|
|
378
|
+
|
|
379
|
+
<Accordion title='TypeError: gate.policy name "public" is reserved'>
|
|
380
|
+
Use `gate.public` or `.public()` for open surfaces. Do not declare `gate.policy("public", …)` or
|
|
381
|
+
`gate.scope("public")`.
|
|
382
|
+
</Accordion>
|
|
383
|
+
|
|
384
|
+
<Accordion title="TypeError: gate.all: at least one member is required">
|
|
385
|
+
`gate.all()` with zero members is invalid. Pass one or more policy / rate / nested `all` handles.
|
|
386
|
+
</Accordion>
|
|
387
|
+
|
|
388
|
+
</Accordions>
|
|
389
|
+
|
|
390
|
+
## Learn more
|
|
391
|
+
|
|
392
|
+
- [Authentication](/docs/elements/gate/auth) — `gate.auth`, `fx.auth`, sessions and keys
|
|
393
|
+
- [Authorization](/docs/elements/gate/authorization) — policies, scopes, `gate.all`
|
|
394
|
+
- [RLS](/docs/elements/gate/rls) — Gate identity stamped into SQL row policies
|
|
395
|
+
- [Rate Limits](/docs/elements/gate/rate-limits) — strategies, `keyBy`, KV
|
|
396
|
+
- [Tenancy](/docs/elements/gate/tenancy) — `fx.tenant.id` and isolation
|
|
397
|
+
- [HTTP](/docs/elements/flow/http) — `.gate(...)` / `.public()` on triggers
|
|
398
|
+
- [Errors](/docs/reference/errors) — `Unauthorized` · `Forbidden` · `RateLimited`
|
|
399
|
+
|
|
400
|
+
## Next
|
|
401
|
+
|
|
402
|
+
<Cards>
|
|
403
|
+
<Card
|
|
404
|
+
title="Authentication"
|
|
405
|
+
description="Configure gate.auth and session identity."
|
|
406
|
+
href="/docs/elements/gate/auth"
|
|
407
|
+
/>
|
|
408
|
+
<Card
|
|
409
|
+
title="HTTP triggers"
|
|
410
|
+
description="Attach .gate(...) and .public() on REST routes."
|
|
411
|
+
href="/docs/elements/flow/http"
|
|
412
|
+
/>
|
|
413
|
+
<Card
|
|
414
|
+
title="Vault Element"
|
|
415
|
+
description="Declare secrets and protected configuration."
|
|
416
|
+
href="/docs/elements/vault"
|
|
417
|
+
/>
|
|
418
|
+
</Cards>
|