@jimhoyd/urlcode 0.3.0 → 0.4.0-alpha.2
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/.claude/skills/urlcode-authoring/SKILL.md +122 -0
- package/.claude/skills/urlcode-operations/SKILL.md +108 -0
- package/.claude-plugin/marketplace.json +18 -0
- package/CONTRIBUTING.md +30 -2
- package/README.md +195 -255
- package/ROADMAP.md +143 -15
- package/SECURITY.md +31 -9
- package/dist/BUILD-MANIFEST.json +72 -47
- package/dist/adapters.js +4 -23
- package/dist/agent-lists.js +1 -1
- package/dist/agents-guide.js +113 -0
- package/dist/authoring-files.js +60 -0
- package/dist/authoring.js +11 -1
- package/dist/aws.js +4 -3
- package/dist/build-cloudflare.js +11 -24
- package/dist/build-static.js +134 -0
- package/dist/bulk.js +37 -0
- package/dist/capabilities.js +262 -0
- package/dist/capability-query.js +71 -0
- package/dist/catalog.js +105 -0
- package/dist/cli.js +165 -34
- package/dist/client-address.js +1 -1
- package/dist/compliance-rules/baseline.js +9 -17
- package/dist/compliance-rules/privacy.js +7 -18
- package/dist/compliance-rules/shared.js +0 -2
- package/dist/compliance-rules/strict.js +5 -5
- package/dist/compliance.js +6 -8
- package/dist/conditions.js +88 -0
- package/dist/config.js +69 -6
- package/dist/context.js +155 -0
- package/dist/ecosystem-cli.js +88 -0
- package/dist/egress.js +98 -0
- package/dist/examples.js +92 -0
- package/dist/explain-cli.js +64 -0
- package/dist/explain.js +131 -0
- package/dist/extensions.js +231 -0
- package/dist/function-sources.js +49 -5
- package/dist/function-worker.js +3 -1
- package/dist/functions.js +84 -13
- package/dist/guest-api.js +29 -3
- package/dist/index.js +40 -6
- package/dist/init-with.js +165 -0
- package/dist/interchange-cli.js +42 -0
- package/dist/interchange.js +189 -0
- package/dist/manifest.js +109 -0
- package/dist/match.js +2 -2
- package/dist/mcp-authoring.js +147 -0
- package/dist/mcp.js +97 -0
- package/dist/observability.js +7 -21
- package/dist/operator-host.js +29 -0
- package/dist/plugins.js +12 -0
- package/dist/policies/agents.js +2 -2
- package/dist/policies/cache.js +8 -3
- package/dist/policies/compression.js +2 -1
- package/dist/policies/security.js +0 -0
- package/dist/policies.js +1 -1
- package/dist/policy.js +56 -15
- package/dist/prerender.js +100 -41
- package/dist/project-tests.js +3 -3
- package/dist/provider-verification.js +92 -0
- package/dist/proxy.js +44 -0
- package/dist/readiness.js +34 -11
- package/dist/recipes.js +41 -0
- package/dist/route-diff.js +106 -0
- package/dist/router.js +45 -7
- package/dist/runtime.js +164 -64
- package/dist/sandbox.js +48 -0
- package/dist/scaffold.js +0 -0
- package/dist/schema-query.js +62 -0
- package/dist/scripts/operational-drills.js +12 -54
- package/dist/server.js +3 -29
- package/dist/signals.js +24 -0
- package/dist/site.js +0 -0
- package/dist/tooling.js +96 -0
- package/dist/trusted-functions.js +210 -0
- package/dist/types/adapters.d.ts +7 -4
- package/dist/types/agent-lists.d.ts +0 -1
- package/dist/types/agents-guide.d.ts +17 -0
- package/dist/types/authoring-files.d.ts +10 -0
- package/dist/types/aws.d.ts +3 -1
- package/dist/types/build-cloudflare.d.ts +1 -0
- package/dist/types/build-static.d.ts +43 -0
- package/dist/types/bulk.d.ts +27 -0
- package/dist/types/capabilities.d.ts +64 -0
- package/dist/types/capability-query.d.ts +24 -0
- package/dist/types/catalog.d.ts +65 -0
- package/dist/types/client-address.d.ts +0 -1
- package/dist/types/compliance-rules/baseline.d.ts +1 -9
- package/dist/types/compliance-rules/privacy.d.ts +1 -4
- package/dist/types/compliance-rules/shared.d.ts +0 -2
- package/dist/types/compliance-rules/strict.d.ts +0 -5
- package/dist/types/compliance.d.ts +0 -3
- package/dist/types/conditions.d.ts +19 -0
- package/dist/types/config.d.ts +21 -2
- package/dist/types/context.d.ts +66 -0
- package/dist/types/ecosystem-cli.d.ts +17 -0
- package/dist/types/egress.d.ts +46 -0
- package/dist/types/examples.d.ts +50 -0
- package/dist/types/explain-cli.d.ts +11 -0
- package/dist/types/explain.d.ts +95 -0
- package/dist/types/extensions.d.ts +177 -0
- package/dist/types/function-sources.d.ts +9 -0
- package/dist/types/functions.d.ts +48 -5
- package/dist/types/guest-api.d.ts +1 -0
- package/dist/types/index.d.ts +36 -6
- package/dist/types/init-with.d.ts +30 -0
- package/dist/types/interchange-cli.d.ts +16 -0
- package/dist/types/interchange.d.ts +42 -0
- package/dist/types/manifest.d.ts +79 -0
- package/dist/types/match.d.ts +1 -0
- package/dist/types/mcp-authoring.d.ts +92 -0
- package/dist/types/mcp.d.ts +12 -0
- package/dist/types/observability.d.ts +3 -14
- package/dist/types/operator-host.d.ts +8 -0
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/policies/agents.d.ts +0 -2
- package/dist/types/policies/compression.d.ts +2 -0
- package/dist/types/policies/security.d.ts +0 -1
- package/dist/types/policy.d.ts +15 -4
- package/dist/types/project-tests.d.ts +3 -2
- package/dist/types/provider-verification.d.ts +53 -0
- package/dist/types/proxy.d.ts +21 -0
- package/dist/types/readiness.d.ts +10 -3
- package/dist/types/recipes.d.ts +30 -0
- package/dist/types/route-diff.d.ts +27 -0
- package/dist/types/router.d.ts +2 -1
- package/dist/types/runtime.d.ts +11 -27
- package/dist/types/sandbox.d.ts +12 -0
- package/dist/types/scaffold.d.ts +0 -2
- package/dist/types/schema-query.d.ts +12 -0
- package/dist/types/server.d.ts +1 -4
- package/dist/types/signals.d.ts +25 -0
- package/dist/types/site.d.ts +0 -1
- package/dist/types/tooling.d.ts +115 -0
- package/dist/types/trusted-functions.d.ts +29 -0
- package/dist/types/types.d.ts +71 -7
- package/dist/types/typescript-authoring.d.ts +12 -0
- package/dist/types/vercel.d.ts +3 -1
- package/dist/types/verify-deployment.d.ts +47 -0
- package/dist/types.js +37 -5
- package/dist/typescript-authoring.js +142 -0
- package/dist/vercel.js +4 -3
- package/dist/verify-deployment.js +270 -0
- package/docs/AI-AUTHORING.md +232 -15
- package/docs/AWS.md +4 -4
- package/docs/BEST-PRACTICES.md +3 -2
- package/docs/BULK.md +79 -0
- package/docs/CAPABILITIES.md +192 -0
- package/docs/CAPACITY.md +129 -32
- package/docs/CI.md +142 -0
- package/docs/CLOUDFLARE.md +1 -2
- package/docs/COMPLIANCE.md +6 -9
- package/docs/CONDITIONS.md +74 -0
- package/docs/DEPLOYMENT-CHECKS.md +108 -0
- package/docs/EGRESS.md +125 -0
- package/docs/EXTENSIONS.md +398 -0
- package/docs/FRAMEWORK.md +198 -0
- package/docs/FUNCTION-SECURITY.md +129 -32
- package/docs/INSTALL.md +45 -12
- package/docs/INTERCHANGE.md +134 -0
- package/docs/LOAD-TESTING.md +4 -4
- package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
- package/docs/MIDDLEWARE.md +29 -16
- package/docs/MONITORING.md +2 -19
- package/docs/NEXT-PHASE-PLAN.md +98 -0
- package/docs/NEXT-STEPS.md +634 -0
- package/docs/OBSERVABILITY.md +11 -18
- package/docs/OPEN-DECISIONS.md +212 -0
- package/docs/OPERATIONAL-PROOF.md +30 -31
- package/docs/OPERATIONS.md +29 -35
- package/docs/PLUGINS.md +37 -0
- package/docs/POLICIES.md +23 -309
- package/docs/PRERENDER.md +41 -1
- package/docs/PROJECT-DIRECTION.md +75 -8
- package/docs/PROVIDER-VERIFICATION.md +84 -0
- package/docs/READINESS.md +21 -1
- package/docs/README.md +87 -34
- package/docs/RECIPES.md +99 -0
- package/docs/RELEASE-READINESS.md +57 -35
- package/docs/RELEASE-SECURITY.md +116 -7
- package/docs/RESILIENCE.md +16 -15
- package/docs/ROUTING.md +8 -10
- package/docs/SANDBOX-REVIEW.md +19 -6
- package/docs/SCAFFOLDING.md +0 -2
- package/docs/SECURITY-AUDIT.md +41 -1
- package/docs/SPECIFICATION.md +150 -29
- package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +287 -0
- package/docs/SPIKE-BUSINESS-SUITE.md +1021 -0
- package/docs/SPIKE-CORE-LAYERING.md +337 -0
- package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +209 -0
- package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
- package/docs/SPIKE-EXTENSIONS.md +6 -0
- package/docs/SPIKE-LAMBDA-COMPILE.md +201 -0
- package/docs/SPIKE-MONOREPO.md +322 -0
- package/docs/STANDARDS.md +150 -142
- package/docs/STARTERS.md +21 -1
- package/docs/STATIC.md +94 -0
- package/docs/TOOLING.md +295 -0
- package/docs/TUNNELS.md +0 -3
- package/docs/TYPESCRIPT-AUTHORING.md +82 -0
- package/docs/TYPESCRIPT.md +25 -4
- package/docs/USABILITY-REVIEW.md +129 -0
- package/docs/VERCEL.md +4 -5
- package/docs/VERSION-ALIGNMENT.md +205 -0
- package/docs/YAML-GUIDE.md +15 -479
- package/docs/YAML-REFERENCE.md +143 -22
- package/docs/policies/agents.md +1 -1
- package/docs/policies/cache.md +13 -0
- package/docs/policies/contract.md +52 -0
- package/docs/policies/hardened.md +56 -0
- package/docs/policies/interoperability.md +169 -0
- package/docs/policies/operations.md +45 -0
- package/docs/yaml/assets.md +36 -0
- package/docs/yaml/conditions.md +20 -0
- package/docs/yaml/functions.md +160 -0
- package/docs/yaml/middleware.md +29 -0
- package/docs/yaml/organization.md +74 -0
- package/docs/yaml/policies.md +37 -0
- package/docs/yaml/redirects.md +64 -0
- package/docs/yaml/responses.md +57 -0
- package/docs/yaml/site.md +24 -0
- package/examples/assets/example.yaml +17 -0
- package/examples/aws/example.yaml +20 -0
- package/examples/cloudflare/example.yaml +19 -0
- package/examples/compliance/example.yaml +11 -0
- package/examples/conditions/README.md +12 -0
- package/examples/conditions/example.yaml +19 -0
- package/examples/conditions/tests/requests.json +13 -0
- package/examples/conditions/urlcode.yaml +24 -0
- package/examples/cookbook/README.md +8 -4
- package/examples/cookbook/example.yaml +17 -0
- package/examples/cookbook/functions/catalog.mjs +3 -0
- package/examples/cookbook/functions/fail.mjs +4 -0
- package/examples/cookbook/functions/items.mjs +3 -0
- package/examples/cookbook/functions/profile.mjs +3 -0
- package/examples/cookbook/functions/resource.mjs +3 -0
- package/examples/cookbook/functions/status.mjs +3 -0
- package/examples/cookbook/middleware/auth.mjs +48 -0
- package/examples/cookbook/middleware/body.mjs +15 -0
- package/examples/cookbook/middleware/bucket.mjs +29 -0
- package/examples/cookbook/middleware/cors.mjs +21 -0
- package/examples/cookbook/middleware/debug.mjs +13 -0
- package/examples/cookbook/middleware/envelope.mjs +11 -0
- package/examples/cookbook/middleware/errors.mjs +11 -0
- package/examples/cookbook/middleware/etag.mjs +18 -0
- package/examples/cookbook/middleware/locale.mjs +20 -0
- package/examples/cookbook/middleware/maintenance.mjs +10 -0
- package/examples/cookbook/middleware/methods.mjs +15 -0
- package/examples/cookbook/middleware/negotiate.mjs +20 -0
- package/examples/cookbook/middleware/referer.mjs +12 -0
- package/examples/cookbook/middleware/request-id.mjs +16 -0
- package/examples/cookbook/route-index.json +676 -0
- package/examples/cookbook/routes/middleware.yaml +126 -0
- package/examples/cookbook/tests/requests.json +526 -0
- package/examples/cookbook/urlcode.yaml +1 -0
- package/examples/egress/README.md +22 -0
- package/examples/egress/example.yaml +19 -0
- package/examples/egress/urlcode.yaml +19 -0
- package/examples/extensions/README.md +7 -0
- package/examples/extensions/example.yaml +21 -0
- package/examples/extensions/urlcode.yaml +25 -0
- package/examples/monitoring/example.yaml +8 -0
- package/examples/prerender/README.md +2 -2
- package/examples/prerender/example.yaml +16 -0
- package/examples/provider-conformance/README.md +12 -0
- package/examples/provider-conformance/example.yaml +14 -0
- package/examples/provider-conformance/urlcode.yaml +34 -0
- package/examples/tunnel/example.yaml +8 -0
- package/examples/vercel/example.yaml +19 -0
- package/llms-full.txt +3084 -0
- package/llms.txt +61 -21
- package/package.json +36 -7
- package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +122 -0
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +108 -0
- package/recipes/authenticated-json-api/README.md +51 -0
- package/recipes/authenticated-json-api/functions/profile.mjs +5 -0
- package/recipes/authenticated-json-api/recipe.yaml +34 -0
- package/recipes/authenticated-json-api/tests/requests.json +39 -0
- package/recipes/authenticated-json-api/urlcode.yaml +12 -0
- package/recipes/contact-form/README.md +25 -0
- package/recipes/contact-form/functions/contact.mjs +17 -0
- package/recipes/contact-form/recipe.yaml +33 -0
- package/recipes/contact-form/tests/requests.json +47 -0
- package/recipes/contact-form/urlcode.yaml +18 -0
- package/recipes/cors-api/README.md +16 -0
- package/recipes/cors-api/functions/items.mjs +3 -0
- package/recipes/cors-api/middleware/cors.mjs +21 -0
- package/recipes/cors-api/recipe.yaml +26 -0
- package/recipes/cors-api/tests/requests.json +65 -0
- package/recipes/cors-api/urlcode.yaml +12 -0
- package/recipes/health-page/README.md +13 -0
- package/recipes/health-page/recipe.yaml +23 -0
- package/recipes/health-page/tests/requests.json +36 -0
- package/recipes/health-page/urlcode.yaml +19 -0
- package/recipes/json-api/README.md +6 -0
- package/recipes/json-api/functions/echo.mjs +3 -0
- package/recipes/json-api/recipe.yaml +25 -0
- package/recipes/json-api/tests/requests.json +34 -0
- package/recipes/json-api/urlcode.yaml +12 -0
- package/recipes/middleware/README.md +34 -0
- package/recipes/middleware/functions/catalog.mjs +3 -0
- package/recipes/middleware/functions/fail.mjs +4 -0
- package/recipes/middleware/functions/items.mjs +3 -0
- package/recipes/middleware/functions/profile.mjs +3 -0
- package/recipes/middleware/functions/resource.mjs +3 -0
- package/recipes/middleware/functions/status.mjs +3 -0
- package/recipes/middleware/middleware/auth.mjs +48 -0
- package/recipes/middleware/middleware/body.mjs +15 -0
- package/recipes/middleware/middleware/bucket.mjs +29 -0
- package/recipes/middleware/middleware/cors.mjs +21 -0
- package/recipes/middleware/middleware/debug.mjs +13 -0
- package/recipes/middleware/middleware/envelope.mjs +11 -0
- package/recipes/middleware/middleware/errors.mjs +11 -0
- package/recipes/middleware/middleware/etag.mjs +18 -0
- package/recipes/middleware/middleware/locale.mjs +20 -0
- package/recipes/middleware/middleware/maintenance.mjs +10 -0
- package/recipes/middleware/middleware/methods.mjs +15 -0
- package/recipes/middleware/middleware/negotiate.mjs +20 -0
- package/recipes/middleware/middleware/referer.mjs +12 -0
- package/recipes/middleware/middleware/request-id.mjs +16 -0
- package/recipes/middleware/public/guide.txt +1 -0
- package/recipes/middleware/recipe.yaml +50 -0
- package/recipes/middleware/tests/requests.json +528 -0
- package/recipes/middleware/urlcode.yaml +127 -0
- package/recipes/protected-download/README.md +22 -0
- package/recipes/protected-download/files/report.txt +1 -0
- package/recipes/protected-download/recipe.yaml +31 -0
- package/recipes/protected-download/tests/requests.json +32 -0
- package/recipes/protected-download/urlcode.yaml +15 -0
- package/recipes/redirect/README.md +7 -0
- package/recipes/redirect/recipe.yaml +25 -0
- package/recipes/redirect/tests/requests.json +19 -0
- package/recipes/redirect/urlcode.yaml +9 -0
- package/recipes/static-plus-api/README.md +15 -0
- package/recipes/static-plus-api/functions/info.mjs +3 -0
- package/recipes/static-plus-api/public/assets/index.html +3 -0
- package/recipes/static-plus-api/public/assets/site.css +1 -0
- package/recipes/static-plus-api/public/index.html +8 -0
- package/recipes/static-plus-api/recipe.yaml +29 -0
- package/recipes/static-plus-api/tests/requests.json +56 -0
- package/recipes/static-plus-api/urlcode.yaml +23 -0
- package/recipes/typescript/README.md +8 -0
- package/recipes/typescript/functions/hello.ts +5 -0
- package/recipes/typescript/recipe.yaml +23 -0
- package/recipes/typescript/tests/requests.json +18 -0
- package/recipes/typescript/urlcode.yaml +5 -0
- package/recipes/webhook-receiver/README.md +20 -0
- package/recipes/webhook-receiver/functions/receive.mjs +16 -0
- package/recipes/webhook-receiver/recipe.yaml +27 -0
- package/recipes/webhook-receiver/tests/requests.json +59 -0
- package/recipes/webhook-receiver/urlcode.yaml +23 -0
- package/schemas/recipe.schema.json +139 -0
- package/schemas/urlcode.schema.json +659 -110
- package/skills/urlcode/SKILL.md +119 -0
- package/starters/default/.github/workflows/urlcode.yml +23 -0
- package/starters/default/.mcp.json +12 -0
- package/starters/default/AGENTS.md +79 -0
- package/starters/default/urlcode.yaml +0 -1
- package/dist/link-api.js +0 -136
- package/dist/link-cli.js +0 -141
- package/dist/link-events.js +0 -76
- package/dist/link-records.js +0 -31
- package/dist/link-store-worker.js +0 -150
- package/dist/link-store.js +0 -250
- package/dist/management-policy.js +0 -41
- package/dist/sqlite-version.js +0 -6
- package/dist/types/link-api.d.ts +0 -30
- package/dist/types/link-cli.d.ts +0 -36
- package/dist/types/link-events.d.ts +0 -27
- package/dist/types/link-records.d.ts +0 -11
- package/dist/types/link-store-worker.d.ts +0 -1
- package/dist/types/link-store.d.ts +0 -130
- package/dist/types/management-policy.d.ts +0 -9
- package/dist/types/sqlite-version.d.ts +0 -1
- package/docs/DYNAMIC-LINKS.md +0 -561
- package/docs/MANAGEMENT-SECURITY.md +0 -82
- package/examples/live-links/README.md +0 -11
- package/examples/live-links/tests/requests.json +0 -6
- package/examples/live-links/urlcode.yaml +0 -16
package/docs/RESILIENCE.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# DDoS, overload and recovery playbook
|
|
2
2
|
|
|
3
3
|
This is an operator plan for the current self-hosted release, not a claim of built-in DDoS
|
|
4
|
-
protection, managed failover or tested high availability. URLCode's
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
protection, managed failover or tested high availability. URLCode's resource
|
|
5
|
+
limits — the HTTP admission cap either way, plus the worker pool's own
|
|
6
|
+
deadline/queue-less ceiling for a `sandbox: true` route — reduce some failure
|
|
7
|
+
modes; they cannot protect a saturated network link. Keep the public origin
|
|
8
|
+
behind your existing protected ingress.
|
|
7
9
|
|
|
8
10
|
## Defense responsibilities
|
|
9
11
|
|
|
@@ -11,8 +13,8 @@ network link. Keep the public origin behind your existing protected ingress.
|
|
|
11
13
|
|---|---|---|
|
|
12
14
|
| Upstream network | Hosting/CDN DDoS mitigation and an escalation contact; protect bandwidth before it reaches the origin | No network-level mitigation service |
|
|
13
15
|
| Edge/proxy | TLS, per-client and aggregate request/connection budgets, header/body/time limits; restrict direct origin access | Private bind default; no automatic TLS/WAF. Optional per-instance [`throttle` and `agents` policies](POLICIES.md) as a second layer behind the edge, with `--trusted-proxies` naming the hops allowed to set `X-Forwarded-For` |
|
|
14
|
-
| Application | Validate inputs, bound expensive work, authenticate sensitive operations | Strict route/body validation; sandbox deadlines and no execution queue |
|
|
15
|
-
| Process/container | CPU/RAM/PID limits, restart backoff, least privilege, read-only reviewed app | Worker isolation, bounded worker replacement, health and request logs |
|
|
16
|
+
| Application | Validate inputs, bound expensive work, authenticate sensitive operations | Strict route/body validation; a `sandbox: true` route gets worker deadlines and no execution queue, a trusted (default) route shares the HTTP admission cap with no worker ceiling |
|
|
17
|
+
| Process/container | CPU/RAM/PID limits, restart backoff, least privilege, read-only reviewed app | Worker isolation for `sandbox: true` routes, bounded worker replacement, health and request logs |
|
|
16
18
|
| Release/recovery | Known-good artifacts, candidate verification, traffic switching, rollback drills | Local validation/tests/audit; explicit snapshot reload; no orchestration |
|
|
17
19
|
|
|
18
20
|
NGINX provides request-rate controls and connection controls keyed by values such
|
|
@@ -30,7 +32,8 @@ forwarded headers to construct its public URL; set `--origin` explicitly.
|
|
|
30
32
|
|
|
31
33
|
The optional [`throttle` policy](policies/throttle.md) adds a per-client budget
|
|
32
34
|
inside the runtime, and the [`agents` policy](policies/agents.md) refuses listed
|
|
33
|
-
User-Agents before a body is read or the
|
|
35
|
+
User-Agents before a body is read or the function/middleware call starts,
|
|
36
|
+
trusted or sandboxed. Both are a second
|
|
34
37
|
layer behind the edge, not a replacement for it: counters are per instance,
|
|
35
38
|
the socket and admission limits still apply first, and a flood still costs
|
|
36
39
|
connections. The client identity is the socket peer unless
|
|
@@ -50,8 +53,8 @@ is not implemented; adding a reverse proxy does not bypass runtime execution.
|
|
|
50
53
|
| Failure or traffic pattern | Current consequence | Mitigation / recovery |
|
|
51
54
|
|---|---|---|
|
|
52
55
|
| High-rate ordinary requests | Event-loop, logging, bandwidth or socket exhaustion | Filter/rate-limit upstream; scale only within measured resource/cost budgets |
|
|
53
|
-
| Flood of functions or middleware | Two default worker slots fill; further calls receive 503 | Bound programmable traffic before the origin; isolate heavy workloads |
|
|
54
|
-
| Infinite/slow application code | Shared invocation deadline returns 504; worker terminated/replaced | Identify bad release/route with protected diagnostics; roll back or block route at ingress |
|
|
56
|
+
| Flood of functions or middleware | Two default worker slots fill for `sandbox: true` routes; further calls receive 503. Trusted (default) routes shed load through the in-flight admission cap instead | Bound programmable traffic before the origin; isolate heavy workloads |
|
|
57
|
+
| Infinite/slow application code | Shared invocation deadline returns 504; a `sandbox: true` worker is terminated/replaced, while a trusted route blocking the event loop synchronously cannot be preempted ([capacity](CAPACITY.md)) | Identify bad release/route with protected diagnostics; roll back or block route at ingress |
|
|
55
58
|
| Guest invalid response or failure | Generic 502 | Compare with last deployment; run fixture on a private candidate |
|
|
56
59
|
| Repeated worker exits | Replacement backs off (250 ms doubling to 30 s) and keeps retrying; readiness stays 503 until every slot serves | Contain the cause; load is shed meanwhile. Replacement never stops, because a guest deadline is reachable from ordinary request input and must not disable functions until an operator restarts |
|
|
57
60
|
| Large/slow requests | 64 admitted application requests, body/header limits and receipt timeouts; copies still consume memory | Smaller proxy/body budgets and connection admission limits |
|
|
@@ -120,8 +123,8 @@ Choose RTO (acceptable recovery time) and RPO (acceptable data loss) per deploym
|
|
|
120
123
|
URLCode does not promise values. A stateless YAML deployment can be recreated
|
|
121
124
|
from retained immutable artifacts, subject to recovery of DNS/ingress and secret
|
|
122
125
|
access. Log loss is possible under pressure and has a separate retention target.
|
|
123
|
-
|
|
124
|
-
verification; Git route configuration does not back up runtime data.
|
|
126
|
+
Future app-owned or extension-owned durable state needs its own backups and
|
|
127
|
+
restore verification; Git route configuration does not back up runtime data.
|
|
125
128
|
|
|
126
129
|
A rollback needs the previous app/runtime and its matching policy and compatible
|
|
127
130
|
secret bindings. The health version combines configuration and asset digests;
|
|
@@ -153,8 +156,6 @@ admission/fairness, production metrics/exporters, dedicated slow-reader protecti
|
|
|
153
156
|
provider-level mitigation validation and sustained failure/soak testing. These are
|
|
154
157
|
free-runtime/operator requirements.
|
|
155
158
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
reloading/restarting. An uncertain mutation may have committed. See
|
|
160
|
-
[dynamic-link recovery](DYNAMIC-LINKS.md).
|
|
159
|
+
Core has no durable store of its own to recover; a future durable-state
|
|
160
|
+
extension (such as the planned `urlcode-dynamic-link`) is responsible for its
|
|
161
|
+
own management listener, backup and recovery procedure once it exists.
|
package/docs/ROUTING.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Route matching
|
|
1
|
+
# Route matching
|
|
2
2
|
|
|
3
3
|
## Supported path patterns
|
|
4
4
|
|
|
@@ -49,7 +49,7 @@ route returning 405, 404, 410 or 400 does not fall through to another route.
|
|
|
49
49
|
Likewise, a missing file in the longest selected static mount does not fall back
|
|
50
50
|
to a shorter mount. See [HTTP](HTTP.md) and [the contract](SPECIFICATION.md).
|
|
51
51
|
|
|
52
|
-
## Adding a configured
|
|
52
|
+
## Adding a configured redirect today
|
|
53
53
|
|
|
54
54
|
```sh
|
|
55
55
|
urlcode add https://example.com/new-page --alias new-link --project ./my-links
|
|
@@ -83,13 +83,11 @@ and needs no route rebuild or service restart. The same distinction applies to
|
|
|
83
83
|
any per-visitor session record. Git owns route behavior and code; user-created records have
|
|
84
84
|
their own persistence, backup and export lifecycle.
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
Core has no native handler for this today: the `link` handler that implemented
|
|
87
|
+
it was removed. Stored short links are moving to a future
|
|
88
|
+
`urlcode-dynamic-link` extension package (mount-based, like `auth`/`admin`,
|
|
89
|
+
not yet published); a project needing them declares an `extension` mount once
|
|
90
|
+
that package exists.
|
|
90
91
|
|
|
91
92
|
Functions still cannot access databases, the filesystem or network directly.
|
|
92
|
-
|
|
93
|
-
successful redirect. General application state and realtime sessions remain
|
|
94
|
-
future work. SQLite is optional and supports local same-host processes; a
|
|
95
|
-
multi-host deployment needs a different adapter. A cache is not the durable store.
|
|
93
|
+
General application state and realtime sessions remain future work.
|
package/docs/SANDBOX-REVIEW.md
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
# Independent sandbox review gate
|
|
2
2
|
|
|
3
|
+
Scope: this gate is about the `sandbox: true` execution path only —
|
|
4
|
+
`function`/`middleware` routes run trusted and unsandboxed by default
|
|
5
|
+
(docs/SPIKE-DEFAULT-TRUST-MODEL.md), and a trusted route's full Node access is
|
|
6
|
+
by design, not a gap this review closes. Nothing here claims to review
|
|
7
|
+
arbitrary trusted project code; that trust is the project's own call, made
|
|
8
|
+
per route.
|
|
9
|
+
|
|
3
10
|
Status: **external assessment not performed**. Internal source review, CI, CodeQL
|
|
4
11
|
and adversarial regressions are useful evidence, not an independent sign-off.
|
|
5
|
-
Do not host anonymous hostile multi-tenant code
|
|
6
|
-
|
|
12
|
+
Do not host anonymous hostile multi-tenant code in a `sandbox: true` route
|
|
13
|
+
before this gate is closed, and do not run untrusted/unreviewed code in a
|
|
14
|
+
trusted (non-`sandbox`) route at all — that path was never sandboxed and this
|
|
15
|
+
gate does not apply to it. No unrestricted Node execution fallback is
|
|
16
|
+
permitted *within a route that declared `sandbox: true`*.
|
|
7
17
|
|
|
8
18
|
## Review package
|
|
9
19
|
|
|
@@ -15,14 +25,17 @@ resource settings. Give a reviewer independent of the implementation access to:
|
|
|
15
25
|
module graph, import denial, export validation, binding grants and message bridge.
|
|
16
26
|
- `src/config.ts`, `src/config-worker.ts`, router and assets: parser/schema limits,
|
|
17
27
|
file containment, activation, memory amplification and host-side compilation.
|
|
18
|
-
- HTTP server
|
|
19
|
-
|
|
20
|
-
- `test/sandbox.test.ts`, middleware/config/links/logging/reload tests, Dockerfile,
|
|
28
|
+
- HTTP server and policy: request smuggling, admission, body/response framing.
|
|
29
|
+
- `test/sandbox.test.ts`, middleware/config/logging/reload tests, Dockerfile,
|
|
21
30
|
protected workflows and `docs/FUNCTION-SECURITY.md`.
|
|
31
|
+
- `src/runtime.ts`'s dispatch decision (`route.sandbox ? pool : trusted`) and
|
|
32
|
+
`src/trusted-functions.ts`: confirm a route that declares `sandbox: true`
|
|
33
|
+
can never be dispatched through the trusted, in-process path by any code
|
|
34
|
+
path, and that `sandbox: false`/absent never reaches `FunctionPool`.
|
|
22
35
|
|
|
23
36
|
Run `npm ci --ignore-scripts`, `npm run verify`, `npm run test:package`, and
|
|
24
37
|
`node scripts/operational-drills.ts`. Record the exact commands and result files.
|
|
25
|
-
CI adds constrained-container
|
|
38
|
+
CI adds a constrained-container test.
|
|
26
39
|
Use only disposable local/staging systems with synthetic data.
|
|
27
40
|
|
|
28
41
|
## Threat model and required probes
|
package/docs/SCAFFOLDING.md
CHANGED
|
@@ -68,5 +68,3 @@ Scaffolding does not recursively invent dependencies imported by existing code,
|
|
|
68
68
|
crawl HTML/CSS links, generate binary content, or implement your business logic.
|
|
69
69
|
See [readiness checks](READINESS.md) and [asset behavior](ASSETS.md).
|
|
70
70
|
|
|
71
|
-
Scaffolding enforces the entry-level `dynamicLinks` opt-in for `link` handlers
|
|
72
|
-
and reports the effective boolean. It never enables this capability for you.
|
package/docs/SECURITY-AUDIT.md
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
# Security review — 2026-09-18
|
|
2
|
+
|
|
3
|
+
Scope: trust-model change (docs/SPIKE-DEFAULT-TRUST-MODEL.md). `function`/
|
|
4
|
+
`middleware` routes now run trusted and unsandboxed by default, with
|
|
5
|
+
`sandbox: true` as an explicit per-route opt-in to the isolation this document's
|
|
6
|
+
earlier entries describe. This is a maintainer-decided policy reversal, not a
|
|
7
|
+
finding; it is recorded here because it changes what every earlier entry's
|
|
8
|
+
"guest"/"sandbox" language means going forward.
|
|
9
|
+
|
|
10
|
+
**What did not change:** the `sandbox: true` execution path — QuickJS/WASM
|
|
11
|
+
isolation, module-graph restriction, fresh heap per call, worker deadline —
|
|
12
|
+
is byte-for-byte the same as every earlier entry describes; nothing in this
|
|
13
|
+
change touched `src/functions.ts`, `src/function-worker.ts` or `src/guest-api.ts`.
|
|
14
|
+
Binding grants are unaffected either way: `env`/`secrets` still reach only a
|
|
15
|
+
route that explicitly declared them and an operator policy pinned to the
|
|
16
|
+
project revision explicitly granted, whether that route is trusted or
|
|
17
|
+
sandboxed.
|
|
18
|
+
|
|
19
|
+
**What did change, and the resulting residual risk:** a `function`/
|
|
20
|
+
`middleware` route with no `sandbox` field (the common case going forward, and
|
|
21
|
+
every existing project's routes after an upgrade with no YAML change) now runs
|
|
22
|
+
in the host process with full Node access — the isolation earlier entries'
|
|
23
|
+
"remaining gaps" language assumed for *all* guest code no longer applies to
|
|
24
|
+
it. The residual-risk framing in earlier entries ("before exposing hostile
|
|
25
|
+
multi-tenant workloads, obtain independent review of WASM/host boundaries")
|
|
26
|
+
is scoped to `sandbox: true` routes specifically; it was never a claim that
|
|
27
|
+
covered a route that opts out of the sandbox, and after this change most
|
|
28
|
+
routes do exactly that by default. Whether a given project's own function/
|
|
29
|
+
middleware code is safe to trust with full host access is now the project's
|
|
30
|
+
judgment call, not something this runtime's isolation reviews (past or
|
|
31
|
+
future) can speak to. New source review of the dispatch decision itself
|
|
32
|
+
(`src/runtime.ts`, `src/trusted-functions.ts`, `src/policy.ts`'s split
|
|
33
|
+
grant-hashing) accompanies the change; see the pull request that introduced
|
|
34
|
+
`sandbox` for its own description of what was and was not verified.
|
|
35
|
+
|
|
1
36
|
# Security review — 2026-09-17
|
|
2
37
|
|
|
3
38
|
Scope: follow-up source review of worker/connection replacement, probe admission,
|
|
@@ -5,6 +40,11 @@ request correlation, operational logging, dependency/release supply chain and th
|
|
|
5
40
|
live-link Node requirement. Regression tests accompany the fixes. Internal review,
|
|
6
41
|
not an independent penetration test.
|
|
7
42
|
|
|
43
|
+
This is a dated record, not current guidance. The `link` handler, its SQLite
|
|
44
|
+
store and the link-store/management findings below were removed from core in
|
|
45
|
+
a later change; they describe the runtime as it existed on this date, not the
|
|
46
|
+
current one.
|
|
47
|
+
|
|
8
48
|
## Findings fixed in this revision
|
|
9
49
|
|
|
10
50
|
| Finding | Impact and evidence | Fix / regression |
|
|
@@ -100,7 +140,7 @@ repository-governance follow-up pins them and enables dependency maintenance,
|
|
|
100
140
|
secret protection, CodeQL and private reporting; see [governance](../GOVERNANCE.md).
|
|
101
141
|
CI now also gates runtime advisories with `npm audit --omit=dev`. A manual main-only
|
|
102
142
|
signed candidate/SBOM workflow is now defined; see
|
|
103
|
-
[release security](RELEASE-SECURITY.md).
|
|
143
|
+
[release security](RELEASE-SECURITY.md). A tagged release publishes to npm with provenance. The 0.1.0 release is licensed under
|
|
104
144
|
Apache-2.0; the license does not close the independent-review gates.
|
|
105
145
|
|
|
106
146
|
**Application responsibility:** HTML/JS assets are active browser content; choose
|
package/docs/SPECIFICATION.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
# Implemented
|
|
1
|
+
# Implemented project contract
|
|
2
2
|
|
|
3
3
|
This document and [JSON Schema](../schemas/urlcode.schema.json) describe
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
the source contract, including unreleased additions after 0.3.0.
|
|
5
|
+
`version: "1"` remains the project-format contract. Unsupported fields
|
|
6
|
+
are rejected rather than interpreted as future behavior.
|
|
6
7
|
|
|
7
8
|
## Files and validation
|
|
8
9
|
|
|
@@ -29,12 +30,12 @@ deadline; individual synchronous operations are not preempted. At most 1,000 par
|
|
|
29
30
|
Keys are absolute case-sensitive paths. Trailing slashes are significant.
|
|
30
31
|
Parameters occupy whole segments, e.g. `/p/{id}`, with distinct identifier names.
|
|
31
32
|
Each parameter matches exactly one nonempty segment, never across `/`; it is not
|
|
32
|
-
greedy. No regex paths, host
|
|
33
|
+
greedy. No regex paths, client-controlled host dispatch or dot segments. Only static directory mounts
|
|
33
34
|
support a terminal `/*` wildcard with an otherwise literal path. Route keys cannot contain
|
|
34
35
|
percent encoding, spaces, backslashes or query strings. Path length is limited
|
|
35
36
|
to 2,048 characters and 32 segments. `/_urlcode` is reserved.
|
|
36
37
|
|
|
37
|
-
One handler per route: `function`, `redirect`, `page`, `static`, `download`, `respond` or `
|
|
38
|
+
One handler per route: `function`, `redirect`, `page`, `static`, `download`, `respond`, `conditional`, `proxy` or an `extension` mount.
|
|
38
39
|
See [asset configuration](ASSETS.md) for file handlers. Optional properties:
|
|
39
40
|
|
|
40
41
|
- `methods`: unique HTTP methods; default GET and HEAD. Explicit lists are exact;
|
|
@@ -55,8 +56,8 @@ Requests decode the path once; invalid UTF-8/percent encoding, encoded slashes o
|
|
|
55
56
|
backslashes, control characters and dot segments return 400. Query values decode
|
|
56
57
|
once. Incoming query data is not automatically forwarded.
|
|
57
58
|
|
|
58
|
-
See [route matching
|
|
59
|
-
limits
|
|
59
|
+
See [route matching](ROUTING.md) for examples, precedence, wildcard
|
|
60
|
+
limits and reload behavior.
|
|
60
61
|
|
|
61
62
|
The optional top-level `site` block (entry file only) generates native routes
|
|
62
63
|
for site conventions: `robots` → `/robots.txt`, `sitemap` → `/sitemap.xml`,
|
|
@@ -67,6 +68,37 @@ path wins and the generated one is logged as shadowed. Absolute URLs come from
|
|
|
67
68
|
the operator's `--origin`; `sitemap` refuses activation without one. See
|
|
68
69
|
[site conventions](SITE.md).
|
|
69
70
|
|
|
71
|
+
## Exact conditions and duplicate-path alternatives
|
|
72
|
+
|
|
73
|
+
Optional route `match` conjunctively compares exact query/header/cookie strings,
|
|
74
|
+
an uppercase method and the canonical authority of the operator-configured
|
|
75
|
+
public origin. Host/forwarded headers never select the trusted host. A guard
|
|
76
|
+
mismatch returns 404 without trying a less-specific path; route method admission
|
|
77
|
+
still applies after the guard. Conditions are not authentication or authorization.
|
|
78
|
+
|
|
79
|
+
The `conditional` handler puts alternatives under one existing route key:
|
|
80
|
+
`cases` contains 1–16 `{match, redirect}` or `{match, respond}` entries; optional
|
|
81
|
+
`fallback` contains exactly one redirect/respond handler. Duplicate YAML paths
|
|
82
|
+
remain invalid. Cases must be provably disjoint: each pair needs a shared
|
|
83
|
+
predicate with different required values. Cases run before fallback; no matching
|
|
84
|
+
case and no fallback returns 404. Nested cases and branch-local bindings,
|
|
85
|
+
middleware or policy are unsupported. Shared inputs, methods, headers,
|
|
86
|
+
middleware and policies stay at route level.
|
|
87
|
+
|
|
88
|
+
Each query/header/cookie map has 1–16 comparisons; names have at most 128
|
|
89
|
+
characters and values 1,024. Query comparisons use decoded raw strings without
|
|
90
|
+
parameter defaults/coercion. Cookies use unquoted wire values and an 8 KiB input
|
|
91
|
+
limit. Missing and empty are different. Duplicate examined scalar inputs return
|
|
92
|
+
400 when the transport exposes their counts. Header names normalize to lowercase;
|
|
93
|
+
authentication and transport headers cannot be predicates. No regex, geo/device
|
|
94
|
+
inference, wildcard or arbitrary-code conditions are supported.
|
|
95
|
+
|
|
96
|
+
Conditional routing requires cache disabled or no-store and forces downstream
|
|
97
|
+
no-store responses. Explicit fixtures are required for branch coverage.
|
|
98
|
+
Self-hosted, AWS and Vercel use the shared matcher; Cloudflare refuses conditions
|
|
99
|
+
until its artifact compiler supports them. See [conditions](CONDITIONS.md) and
|
|
100
|
+
the [executable example](../examples/conditions).
|
|
101
|
+
|
|
70
102
|
## HTTP request/response configuration
|
|
71
103
|
|
|
72
104
|
Routes accept `request.body` validation and `response.headers` overrides. The
|
|
@@ -125,15 +157,11 @@ keys preserve repeated values. Headers are forwarded only through explicit maps.
|
|
|
125
157
|
|
|
126
158
|
## Stored links
|
|
127
159
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
path input against an operator-bound store. GET/HEAD only. The logical collection
|
|
134
|
-
is portable; file paths and store credentials are external deployment bindings.
|
|
135
|
-
No general storage capability is exposed to guest code. See [dynamic links](DYNAMIC-LINKS.md)
|
|
136
|
-
for validation, persistence, mutation, expiry and read-after-write behavior.
|
|
160
|
+
Core has no native `link` handler or `dynamicLinks` project flag; both were
|
|
161
|
+
removed. Stored short links are moving to a future `urlcode-dynamic-link`
|
|
162
|
+
extension package (mount-based, like `auth`/`admin`), not yet published. A
|
|
163
|
+
project needing them declares an `extension` mount once that package exists;
|
|
164
|
+
there is no in-core replacement or deprecation shim for `link`/`dynamicLinks`.
|
|
137
165
|
|
|
138
166
|
## Functions
|
|
139
167
|
|
|
@@ -161,9 +189,52 @@ export default function hello(request, { args, env }) {
|
|
|
161
189
|
}
|
|
162
190
|
```
|
|
163
191
|
|
|
192
|
+
`function` also accepts a string: `function: functions/hello.mjs`. Document
|
|
193
|
+
validation normalizes it to the long form above before routing, auditing,
|
|
194
|
+
explaining or hashing the project: `source` is the string, `args` maps every
|
|
195
|
+
`{param}` segment of the path to `{from: path, name: param}`, and each such
|
|
196
|
+
parameter the route does not already declare under `parameters` (by name, with
|
|
197
|
+
`in: path`) is appended as `{in: path, required: true, schema: {type: string,
|
|
198
|
+
minLength: 1, maxLength: 128}}`. Declared parameters keep their own schema and
|
|
199
|
+
order. The string must be a project-relative `.mjs` or `.js` path without `..`
|
|
200
|
+
segments; anything else is refused with the route path named. A `middleware`
|
|
201
|
+
entry may likewise be a string, normalized to `{source: <string>}`. Only the
|
|
202
|
+
long form exists after loading, so `routes`, `audit`, `explain`, revision hashes
|
|
203
|
+
and the field reference describe the expansion.
|
|
204
|
+
|
|
164
205
|
ES modules only (`.mjs` or `.js`, independent of Node package settings).
|
|
165
|
-
TypeScript
|
|
166
|
-
|
|
206
|
+
[Build-time TypeScript authoring](TYPESCRIPT-AUTHORING.md) can produce these
|
|
207
|
+
JavaScript modules in a separate output project; serving does not transpile them.
|
|
208
|
+
The build never imports application code into Node, uses fixed compiler settings,
|
|
209
|
+
and does not perform semantic type checking. Grants must target the built
|
|
210
|
+
configuration/source revision. `export` defaults to `default`.
|
|
211
|
+
|
|
212
|
+
### Trust: unsandboxed by default, `sandbox: true` opt-in
|
|
213
|
+
|
|
214
|
+
A route's `function`/`middleware` chain runs one of two ways, chosen by the
|
|
215
|
+
route's `sandbox` field (false or absent — the default — versus `true`; see
|
|
216
|
+
[docs/SPIKE-DEFAULT-TRUST-MODEL.md](SPIKE-DEFAULT-TRUST-MODEL.md)):
|
|
217
|
+
|
|
218
|
+
- **`sandbox` false/absent (trusted, the default):** the module is imported
|
|
219
|
+
directly into the host process with ordinary Node module resolution — bare
|
|
220
|
+
specifiers, `node:` builtins, npm packages and dynamic `import()` all work,
|
|
221
|
+
none of the module-graph/source-size limits below apply, and there is no
|
|
222
|
+
fresh-heap-per-call reset (module-level state persists across requests like
|
|
223
|
+
any other Node server). The handler/middleware signature and `context`
|
|
224
|
+
shape are unchanged from the sandboxed contract below; a trusted function
|
|
225
|
+
additionally has the full Fetch API, Node built-ins and the filesystem
|
|
226
|
+
available to it, not just the guest text/JSON subset. `args`/`env`/
|
|
227
|
+
`secrets` are exactly what the route declares and an operator grants,
|
|
228
|
+
identically to the sandboxed path.
|
|
229
|
+
- **`sandbox: true`:** the rest of this section, unchanged from every earlier
|
|
230
|
+
release. A sandboxed route's functions and middleware execute inside
|
|
231
|
+
QuickJS/WASM, never through Node imports.
|
|
232
|
+
|
|
233
|
+
The remainder of this section (module restrictions, the guest API subset,
|
|
234
|
+
guest limits and deadlines) describes the `sandbox: true` path specifically,
|
|
235
|
+
unless stated otherwise.
|
|
236
|
+
|
|
237
|
+
Only relative `.js`/`.mjs`
|
|
167
238
|
project imports are supported, with a snapshotted dependency graph. No bare/npm,
|
|
168
239
|
Node built-in, remote, dynamic source imports or `import.meta`. Runtime-created
|
|
169
240
|
imports remain restricted to the route's middleware and handler dependency graphs; there is no fallback.
|
|
@@ -176,7 +247,8 @@ delete/get/has/entries/getSetCookie; Response constructor with string/null body,
|
|
|
176
247
|
Requests decode body bytes as UTF-8. Binary/streaming bodies, URL helpers,
|
|
177
248
|
fetch/WebSocket, crypto and filesystem are not exposed. Promise/async and
|
|
178
249
|
bounded timers (128 pending per invocation) work inside the guest. Unsupported
|
|
179
|
-
APIs fail; they never execute on the host. Do not claim full browser/Node API
|
|
250
|
+
APIs fail; they never execute on the host. Do not claim full browser/Node API
|
|
251
|
+
parity for a `sandbox: true` route; a trusted route has no such restriction.
|
|
180
252
|
|
|
181
253
|
Context contains `inputs.path/query/header`, `args`, `env`, `secrets`. Arguments
|
|
182
254
|
may be scalar literals, input references, `{env: alias}` or `{secret: alias}`.
|
|
@@ -192,12 +264,17 @@ Dotenv supports single-line NAME=value, paired single/double quotes, blank lines
|
|
|
192
264
|
and full-line comments, without expansion/escapes/shell execution. Loading a
|
|
193
265
|
value does not authorize exposing it to a function; the policy still applies.
|
|
194
266
|
|
|
195
|
-
|
|
196
|
-
counters, cached secrets or prototype mutation. QuickJS
|
|
197
|
-
stack limit 512 KiB; outer worker and deployment limits
|
|
198
|
-
not a claim that total process RSS is capped at 32
|
|
199
|
-
saturation returns 503. The independent 5-second
|
|
200
|
-
and returns 504. Generic failures return 502;
|
|
267
|
+
A `sandbox: true` invocation has a fresh guest heap and module state every
|
|
268
|
+
time. No cross-request counters, cached secrets or prototype mutation. QuickJS
|
|
269
|
+
heap limit is 32 MiB, stack limit 512 KiB; outer worker and deployment limits
|
|
270
|
+
are additional defenses, not a claim that total process RSS is capped at 32
|
|
271
|
+
MiB. Two workers, no queue; saturation returns 503. The independent 5-second
|
|
272
|
+
deadline terminates a worker and returns 504. Generic failures return 502;
|
|
273
|
+
worker replacement is bounded. A trusted route has none of this: no fresh
|
|
274
|
+
heap/module reset, no fixed worker-pool ceiling (bounded instead by ordinary
|
|
275
|
+
Node concurrency and the HTTP admission cap), and its deadline races the
|
|
276
|
+
call's promise rather than force-terminating a worker — see
|
|
277
|
+
[capacity](CAPACITY.md) for both models side by side.
|
|
201
278
|
|
|
202
279
|
HEAD invokes the handler as HEAD and suppresses body output. Code must guard
|
|
203
280
|
its own application side effects when future brokered integrations are enabled.
|
|
@@ -206,11 +283,18 @@ not arbitrary Host/forwarded headers. Request/response bodies default to 1 MiB;
|
|
|
206
283
|
response headers 16 KiB, maximum 256 pairs. Hop-by-hop headers are stripped;
|
|
207
284
|
cookies are preserved individually. Default response cache policy is `no-store`.
|
|
208
285
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
286
|
+
A trusted (non-`sandbox`) route already has unrestricted host execution by
|
|
287
|
+
design — that is the point of the default described above. For a `sandbox:
|
|
288
|
+
true` route, there is no unrestricted host-execution fallback: declarative
|
|
289
|
+
proxy and webhook signals use the separately granted host broker described in
|
|
290
|
+
[egress](EGRESS.md), and that route's guests still have no fetch API or
|
|
291
|
+
general persistent state capability. Approved secrets can be returned by code
|
|
292
|
+
that receives them, in either mode; isolation does not automatically enforce
|
|
212
293
|
information-flow rules on authorized inputs. Keep grants narrow and review the
|
|
213
|
-
exact pinned revision. The sandbox still needs independent
|
|
294
|
+
exact pinned revision. The `sandbox: true` path still needs independent
|
|
295
|
+
security review before hostile multi-tenant use of that specific mode; that
|
|
296
|
+
review's scope was never a claim about a route that opts out of the sandbox
|
|
297
|
+
(see [docs/SANDBOX-REVIEW.md](SANDBOX-REVIEW.md)).
|
|
214
298
|
|
|
215
299
|
## Reload and status
|
|
216
300
|
|
|
@@ -230,3 +314,40 @@ The health `version` combines route-definition and asset-representation digests,
|
|
|
230
314
|
not a full artifact digest
|
|
231
315
|
or secret fingerprint. Production release identity should be the Git commit and
|
|
232
316
|
container image digest. See [operations](OPERATIONS.md).
|
|
317
|
+
|
|
318
|
+
See [capabilities and normalized route representation](CAPABILITIES.md) for the target catalog,
|
|
319
|
+
programmatic compatibility analysis and provider verification limits.
|
|
320
|
+
|
|
321
|
+
## Authoring, conversion and verification tools
|
|
322
|
+
|
|
323
|
+
[Interchange](INTERCHANGE.md) imports and exports a strict literal redirect
|
|
324
|
+
subset with source diagnostics and dry-run reports. Provider conversions refuse
|
|
325
|
+
semantic differences by default; explicit acknowledgment retains warnings and
|
|
326
|
+
never reports lossless behavior. [Bulk import](BULK.md) shards CSV/JSON/YAML rows
|
|
327
|
+
into ordinary includes while retaining runtime resource limits. [Recipes](RECIPES.md)
|
|
328
|
+
are local Git-owned examples; they grant no capabilities. [Build-time TypeScript](TYPESCRIPT-AUTHORING.md)
|
|
329
|
+
is separate from runtime execution.
|
|
330
|
+
|
|
331
|
+
The [tooling SDK and optional local MCP](TOOLING.md) inspect and validate without
|
|
332
|
+
executing handlers or reading binding values. [Provider conformance](PROVIDER-VERIFICATION.md)
|
|
333
|
+
distinguishes local adapter replay from actual deployment observations; no real
|
|
334
|
+
provider deployment is implied by CI. [Proxy and signal egress](EGRESS.md) requires
|
|
335
|
+
external revision-pinned operator grants and bounded host-owned transport;
|
|
336
|
+
project declarations cannot grant network authority to themselves or guests.
|
|
337
|
+
|
|
338
|
+
## Bounded outbound behavior
|
|
339
|
+
|
|
340
|
+
The proxy handler and webhook signals require external revision-pinned origin
|
|
341
|
+
grants. [Egress](EGRESS.md) specifies request and response semantics, DNS pinning,
|
|
342
|
+
header filtering, size/time/concurrency limits, secret binding, signal guarantees
|
|
343
|
+
and shutdown. Project declarations cannot grant network authority to themselves.
|
|
344
|
+
All non-self-hosted targets refuse these capabilities.
|
|
345
|
+
|
|
346
|
+
## Operator-installed extension handlers
|
|
347
|
+
|
|
348
|
+
The optional `extensions` map declares version-1 extension configuration.
|
|
349
|
+
`extension: name` handlers require exclusive literal `/prefix/*` mounts and
|
|
350
|
+
explicit operator registration pinned to the project revision. Optional
|
|
351
|
+
`policies.extensions` requirements are validated by the named extension and
|
|
352
|
+
authorized before cache access. See [extension contracts](EXTENSIONS.md) for
|
|
353
|
+
configuration, trust boundaries, lifecycle and target restrictions.
|