Skip to content
File

Blob: src/workerd/server/workerd.capnp

45.2 KB
1# Copyright (c) 2017-2022 Cloudflare, Inc.
2# Licensed under the Apache 2.0 license found in the LICENSE file or at:
3# https://opensource.org/licenses/Apache-2.0
4 
5@0xe6afd26682091c01;
6# This file defines the schema for configuring the workerd runtime.
7#
8# A config file can be written as a `.capnp` file that imports this file and then defines a
9# constant of type `Config`. Alternatively, various higher-level tooling (e.g. wrangler) may
10# generate configs for you, outputting a binary Cap'n Proto file.
11#
12# To start a server with a config, do:
13#
14# workerd serve my-config.capnp constantName
15#
16# You can also build a new self-contained binary which combines the `workerd` binary with your
17# configuration and all your source code:
18#
19# workerd compile my-config.capnp constantName -o my-server-bin
20#
21# This binary can then be run stand-alone.
22#
23# A common theme in this configuration is capability-based design. We generally like to avoid
24# giving a Worker the ability to access external resources by name, since this makes it hard
25# to see and restrict what each Worker can access. Instead, the default is that a Worker has
26# access to no privileged resources at all, and you must explicitly declare "bindings" to give
27# it access to specific resources. A binding gives the Worker a JavaScript API object that points
28# to a specific resource. This means that by changing config alone, you can fully control which
29# resources an Worker connects to. (You can even disallow access to the public internet, although
30# public internet access is granted by default.)
31#
32# This config format is fairly powerful, allowing you to do things like define a TLS-terminating
33# reverse proxy server without using any actual JavaScript code. However, you should not be
34# afraid to fall back to code for anything the config cannot express, as Workers are very fast
35# to execute!
36 
37# Any capnp files imported here must be:
38# 1. embedded using wd_cc_embed
39# 2. added to `tryImportBulitin` in workerd.c++ (grep for '"/workerd/workerd.capnp"').
40using Cxx = import "/capnp/c++.capnp";
41$Cxx.namespace("workerd::server::config");
42$Cxx.allowCancellation;
43 
44struct Config {
45 # Top-level configuration for a workerd instance.
46 
47 services @0 :List(Service);
48 # List of named services defined by this server. These names are private; they are only used
49 # to refer to the services from elsewhere in this config file, as well as for logging and the
50 # like. Services are not reachable until you configure some way to make them reachable, such
51 # as via a Socket.
52 #
53 # If you do not define any service called "internet", one is defined implicitly, representing
54 # the ability to access public internet servers. An explicit definition would look like:
55 #
56 # ( name = "internet",
57 # network = (
58 # allow = ["public"], # Allows connections to publicly-routable addresses only.
59 # tlsOptions = (trustBrowserCas = true)
60 # )
61 # )
62 #
63 # The "internet" service backs the global `fetch()` function in a Worker, unless that Worker's
64 # configuration specifies some other service using the `globalOutbound` setting.
65 
66 sockets @1 :List(Socket);
67 # List of sockets on which this server will listen, and the services that will be exposed
68 # through them.
69 
70 v8Flags @2 :List(Text);
71 # List of "command-line" flags to pass to V8, like "--expose-gc". We put these in the config
72 # rather than on the actual command line because for most use cases, managing these via the
73 # config file is probably cleaner and easier than passing on the actual CLI.
74 #
75 # WARNING: Use at your own risk. V8 flags can have all sorts of wild effects including completely
76 # breaking everything. V8 flags also generally do not come with any guarantee of stability
77 # between V8 versions. Most users should not set any V8 flags.
78 
79 extensions @3 :List(Extension);
80 # Extensions provide capabilities to all workers. Extensions are usually prepared separately
81 # and are late-linked with the app using this config field.
82 
83 autogates @4 :List(Text);
84 # A list of gates which are enabled.
85 # These are used to gate features/changes in workerd and in our internal repo. See the equivalent
86 # config definition in our internal repo for more details.
87 
88 structuredLogging @5 :Bool = false;
89 # If true, logs will be emitted as JSON for structured logging.
90 # When false, logs use the traditional human-readable format.
91 # This affects the format of logs from KJ_LOG and exception reporting as well as js logs.
92 # This won't work for logs coming from service worker syntax workers with the old module registry.
93 # Note: This field is obsolete and deprecated. Use the logging struct instead.
94 
95 logging @6 : LoggingOptions;
96 # Console and Stdio logging configuration options.
97}
98 
99struct LoggingOptions {
100 structuredLogging @0 :Bool = false;
101 # Override of top-level structured logging (only when true).
102 # If true, logs will be emitted as JSON for structured logging.
103 # When false, logs use the traditional human-readable format.
104 # This affects the format of logs from KJ_LOG and exception reporting as well as js logs.
105 # This won't work for logs coming from service worker syntax workers with the old module registry.
106 
107 stdoutPrefix @1 :Text;
108 # Set a custom prefix for process.stdout. Defaults to "stdout: ".
109 
110 stderrPrefix @2 :Text;
111 # Set a custom prefix for process.stderr. Defaults to "stderr: ".
112}
113 
114# ========================================================================================
115# Sockets
116 
117struct Socket {
118 name @0 :Text;
119 # Each socket has a unique name which can be used on the command line to override the socket's
120 # address with `--socket-addr <name>=<addr>` or `--socket-fd <name>=<fd>`.
121 
122 address @1 :Text;
123 # Address/port on which this socket will listen. Optional; if not specified, then you will be
124 # required to specify the socket on the command line with with `--socket-addr <name>=<addr>` or
125 # `--socket-fd <name>=<fd>`.
126 #
127 # Examples:
128 # - "*:80": Listen on port 80 on all local IPv4 and IPv6 interfaces.
129 # - "1.2.3.4": Listen on the specific IPv4 address on the default port for the protocol.
130 # - "1.2.3.4:80": Listen on the specific IPv4 address and port.
131 # - "1234:5678::abcd": Listen on the specific IPv6 address on the default port for the protocol.
132 # - "[1234:5678::abcd]:80": Listen on the specific IPv6 address and port.
133 # - "unix:/path/to/socket": Listen on a Unix socket.
134 # - "unix-abstract:name": On Linux, listen on the given "abstract" Unix socket name.
135 # - "example.com:80": Perform a DNS lookup to determine the address, and then listen on it. If
136 # this resolves to multiple addresses, listen on all of them.
137 #
138 # (These are the formats supported by KJ's parseAddress().)
139 
140 union {
141 http @2 :HttpOptions;
142 https :group {
143 options @3 :HttpOptions;
144 tlsOptions @4 :TlsOptions;
145 }
146 tcp :group {
147 tlsOptions @6 :TlsOptions;
148 }
149 
150 # TODO(someday): TCP proxy, SMTP, Cap'n Proto, ...
151 }
152 
153 service @5 :ServiceDesignator;
154 # Service name which should handle requests on this socket.
155 
156 # TODO(someday): Support mapping different hostnames to different services? Or should that be
157 # done strictly via JavaScript?
158}
159 
160# ========================================================================================
161# Services
162 
163struct Service {
164 # Defines a named service. Each server has a list of named services. The names are private,
165 # used to refer to the services within this same config file.
166 
167 name @0 :Text;
168 # Name of the service. Used only to refer to the service from elsewhere in the config file.
169 # Services are not accessible unless you explicitly configure them to be, such as through a
170 # `Socket` or through a binding from another Worker.
171 
172 union {
173 unspecified @1 :Void;
174 # (This catches when someone forgets to specify one of the union members. Do not set this.)
175 
176 worker @2 :Worker;
177 # A Worker!
178 
179 network @3 :Network;
180 # A service that implements access to a network. fetch() requests are routed according to
181 # the URL hostname.
182 
183 external @4 :ExternalServer;
184 # A service that forwards all requests to a specific remote server. Typically used to
185 # connect to a back-end server on your internal network.
186 
187 disk @5 :DiskDirectory;
188 # An HTTP service backed by a directory on disk, supporting a basic HTTP GET/PUT. Generally
189 # not intended to be exposed directly to the internet; typically you want to bind this into
190 # a Worker that adds logic for setting Content-Type and the like.
191 }
192 
193 # TODO(someday): Allow defining a list of middlewares to stack on top of the service. This would
194 # be a list of Worker names, where each Worker must have a binding called `next`. This
195 # implicitly creates an inherited worker that wraps this service, with the `next` binding
196 # pointing to the service itself (or to the next middleware in the stack).
197}
198 
199struct ServiceDesignator {
200 # A reference to a service from elsewhere in the config file, e.g. from a service binding in a
201 # Worker.
202 #
203 # In the case that only `name` needs to be specified, then you can provide a raw string wherever
204 # `ServiceDesignator` is needed. Cap'n proto automatically assumes the string is intended to be
205 # the value for `name`, since that is the first field. In other words, if you would otherwise
206 # write something like:
207 #
208 # bindings = [(service = (name = "foo"))]
209 #
210 # You can write this instead, which is equivalent:
211 #
212 # bindings = [(service = "foo")]
213 
214 name @0 :Text;
215 # Name of the service in the Config.services list.
216 
217 entrypoint @1 :Text;
218 # A modules-syntax Worker can export multiple named entrypoints. `export default {` specifies
219 # the default entrypoint, whereas `export let foo = {` defines an entrypoint named `foo`. If
220 # `entrypoint` is specified here, it names an alternate entrypoint to use on the target worker,
221 # otherwise the default is used.
222 
223 props :union {
224 # Value to provide in `ctx.props` in the target worker.
225 
226 empty @2 :Void;
227 # Empty object. (This is the default.)
228 
229 json @3 :Text;
230 # A JSON-encoded value.
231 }
232 
233 # TODO(someday): Options to specify which event types are allowed.
234 # TODO(someday): Allow adding an outgoing middleware stack here (see TODO in Service, above).
235}
236 
237struct Worker {
238 union {
239 modules @0 :List(Module);
240 # The Worker is composed of ES modules that may import each other. The first module in the list
241 # is the main module, which exports event handlers.
242 
243 serviceWorkerScript @1 :Text;
244 # The Worker is composed of one big script that uses global `addEventListener()` to register
245 # event handlers.
246 #
247 # The value of this field is the raw source code. When using Cap'n Proto text format, use the
248 # `embed` directive to read the code from an external file:
249 #
250 # serviceWorkerScript = embed "worker.js"
251 
252 inherit @2 :Text;
253 # Inherit the configuration of some other Worker by its service name. This Worker is a clone
254 # of the other worker, but various settings can be modified:
255 # * `bindings`, if specified, overrides specific named bindings. (Each binding listed in the
256 # derived worker must match the name and type of some binding in the inherited worker.)
257 # * `globalOutbound`, if non-null, overrides the one specified in the inherited worker.
258 # * `compatibilityDate` and `compatibilityFlags` CANNOT be modified; they must be null.
259 # * If the inherited worker defines durable object namespaces, then the derived worker must
260 # specify `durableObjectStorage` to specify where its instances should be stored. Each
261 # devived worker receives its own namespace of objects. `durableObjectUniqueKeyModifier`
262 # must also be specified by derived workers.
263 #
264 # This can be useful when you want to run the same Worker in multiple configurations or hooked
265 # up to different back-ends. Note that all derived workers run in the same isolate as the
266 # base worker; they differ in the content of the `env` object passed to them, which contains
267 # the bindings. (When using service workers syntax, the global scope contains the bindings;
268 # in this case each derived worker runs in its own global scope, though still in the same
269 # isolate.)
270 }
271 
272 struct Module {
273 name @0 :Text;
274 # Name (or path) used to import the module.
275 
276 union {
277 esModule @1 :Text;
278 # An ES module file with imports and exports.
279 #
280 # As with `serviceWorkerScript`, above, the value is the raw source code.
281 
282 commonJsModule @2 :Text;
283 # A common JS module, using require().
284 
285 text @3 :Text;
286 # A raw text blob. Importing this will produce a string with the value.
287 
288 data @4 :Data;
289 # A raw data blob. Importing this will produce an ArrayBuffer with the value.
290 
291 wasm @5 :Data;
292 # A Wasm module. The value is a compiled binary Wasm module file. Importing this will produce
293 # a `WebAssembly.Module` object, which you can then instantiate.
294 
295 json @6 :Text;
296 # Importing this will produce the result of parsing the given text as JSON.
297 
298 obsolete @7 :Text;
299 # This position used to be the nodeJsCompatModule type that has now been
300 # obsoleted.
301 
302 pythonModule @8 :Text;
303 # A Python module. All bundles containing this value type are converted into a JS/WASM Worker
304 # Bundle prior to execution.
305 
306 pythonRequirement @9 :Text;
307 # A Python package that is required by this bundle. The package must be supported by
308 # Pyodide (https://pyodide.org/en/stable/usage/packages-in-pyodide.html). All packages listed
309 # will be installed prior to the execution of the worker.
310 #
311 # The value of this field is ignored and should always be an empty string. Only the module
312 # name matters. The field should have been declared `Void`, but it's difficult to change now.
313 }
314 
315 namedExports @10 :List(Text);
316 # For commonJsModule modules, this is a list of named exports that the
317 # module expects to be exported once the evaluation is complete.
318 #
319 # (`commonJsModule` should have been a group containing the body and `namedExports`, but it's
320 # too late to change now.)
321 }
322 
323 compatibilityDate @3 :Text;
324 compatibilityFlags @4 :List(Text);
325 # See: https://developers.cloudflare.com/workers/platform/compatibility-dates/
326 #
327 # `compatibilityDate` must be specified, unless the Worker inhits from another worker, in which
328 # case it must not be specified. `compatibilityFlags` can optionally be specified when
329 # `compatibilityDate` is specified.
330 
331 bindings @5 :List(Binding);
332 # List of bindings, which give the Worker access to external resources and configuration
333 # settings.
334 #
335 # For Workers using ES modules syntax, the bindings are delivered via the `env` object. For
336 # service workers syntax, each binding shows up as a global variable.
337 
338 struct Binding {
339 name @0 :Text;
340 
341 union {
342 unspecified @1 :Void;
343 # (This catches when someone forgets to specify one of the union members. Do not set this.)
344 
345 parameter :group {
346 # Indicates that the Worker requires a binding of the given type, but it won't be specified
347 # here. Another Worker can inherit this Worker and fill in this binding.
348 
349 type @2 :Type;
350 # Expected type of this parameter.
351 
352 optional @3 :Bool;
353 # If true, this binding is optional. Derived workers need not specify it, in which case
354 # the binding won't be present in the environment object passed to the worker.
355 #
356 # When a Worker has any non-optional parameters that haven't been filled in, then it can
357 # only be used for inheritance; it cannot be invoked directly.
358 }
359 
360 text @4 :Text;
361 # A string.
362 
363 data @5 :Data;
364 # An ArrayBuffer.
365 
366 json @6 :Text;
367 # A value parsed from JSON.
368 
369 wasmModule @7 :Data;
370 # A WebAssembly module. The binding will be an instance of `WebAssembly.Module`. Only
371 # supported when using Service Workers syntax.
372 #
373 # DEPRECATED: Please switch to ES modules syntax instead, and embed Wasm modules as modules.
374 
375 cryptoKey @8 :CryptoKey;
376 # A CryptoKey instance, for use with the WebCrypto API.
377 #
378 # Note that by setting `extractable = false`, you can prevent the Worker code from accessing
379 # or leaking the raw key material; it will only be able to use the key to perform WebCrypto
380 # operations.
381 
382 service @9 :ServiceDesignator;
383 # Binding to a named service (possibly, a worker).
384 
385 durableObjectClass @26 :ServiceDesignator;
386 # A Durable Object class binding, without an actual storage namespace. This can be used to
387 # implement a facet.
388 
389 durableObjectNamespace @10 :DurableObjectNamespaceDesignator;
390 # Binding to the durable object namespace implemented by the given class.
391 #
392 # In the common case that this refers to a class in the same Worker, you can specify just
393 # a string, like:
394 #
395 # durableObjectNamespace = "MyClass"
396 
397 kvNamespace @11 :ServiceDesignator;
398 # A KV namespace, implemented by the named service. The Worker sees a KvNamespace-typed
399 # binding. Requests to the namespace will be converted into HTTP requests targeting the
400 # given service name.
401 
402 r2Bucket @12 :ServiceDesignator;
403 # R2 bucket binding. Similar to KV namespaces, this turns operations into HTTP requests aimed
404 # at the named service.
405 
406 obsolete0 @13 :ServiceDesignator;
407 
408 wrapped @14 :WrappedBinding;
409 # Wraps a collection of inner bindings in a common api functionality.
410 
411 queue @15 :ServiceDesignator;
412 # A Queue binding, implemented by the named service. Requests to the
413 # namespace will be converted into HTTP requests targeting the given
414 # service name.
415 
416 fromEnvironment @16 :Text;
417 # Takes the value of an environment variable from the system. The value specified here is
418 # the name of a system environment variable. The value of the binding is obtained by invoking
419 # `getenv()` with that name. If the environment variable isn't set, the binding value is
420 # `null`.
421 
422 analyticsEngine @17 :ServiceDesignator;
423 # A binding for Analytics Engine. Allows workers to store information through Analytics Engine Events.
424 # workerd will forward AnalyticsEngineEvents to designated service in the body of HTTP requests
425 # This binding is subject to change and requires the `--experimental` flag
426 
427 hyperdrive :group {
428 designator @18 :ServiceDesignator;
429 database @19 :Text;
430 user @20 :Text;
431 password @21 :Text;
432 scheme @22 :Text;
433 }
434 # A binding for Hyperdrive. Allows workers to use Hyperdrive caching & pooling for Postgres
435 # databases.
436 
437 unsafeEval @23 :Void;
438 # A simple binding that enables access to the UnsafeEval API.
439 
440 memoryCache :group {
441 # A binding representing access to an in-memory cache.
442 
443 id @24 :Text;
444 # The identifier associated with this cache. Any number of isolates
445 # can access the same in-memory cache (within the same process), and
446 # each worker may use any number of in-memory caches.
447 
448 limits @25 :MemoryCacheLimits;
449 }
450 
451 workerLoader :group {
452 # A binding representing the ability to dynamically load Workers from code presented at
453 # runtime.
454 #
455 # A Worker loader is not just a function that loads a Worker, but also serves as a
456 # cache of Workers, automatically unloading Workers that are not in use. To that end, each
457 # Worker must have a name, and if a Worker with that name already exists, it'll be reused.
458 
459 id @27 :Text;
460 # Optional: The identifier associated with this Worker loader. Multiple Workers can bind to
461 # the same ID in order to access the same loader, so that if they request the same name
462 # from it, they'll end up sharing the same loaded Worker.
463 #
464 # (If omitted, the binding will not share a cache with any other binding.)
465 }
466 
467 workerdDebugPort @28 :Void;
468 # A binding that provides a connect() method to dynamically connect to any workerd
469 # instance's debug port. This allows dynamic access to worker entrypoints via the
470 # WorkerdDebugPort RPC interface.
471 #
472 # Usage: const client = await env.DEBUG_PORT.connect("localhost:1234");
473 # const fetcher = await client.getEntrypoint("service", "entrypoint");
474 #
475 # This is a workerd-only API intended for local development and testing.
476 
477 # TODO(someday): dispatch, other new features
478 }
479 
480 struct Type {
481 # Specifies the type of a parameter binding.
482 
483 union {
484 unspecified @0 :Void;
485 # (This catches when someone forgets to specify one of the union members. Do not set this.)
486 
487 text @1 :Void;
488 data @2 :Void;
489 json @3 :Void;
490 wasm @4 :Void;
491 cryptoKey @5 :List(CryptoKey.Usage);
492 service @6 :Void;
493 durableObjectNamespace @7 :Void;
494 kvNamespace @8 :Void;
495 r2Bucket @9 :Void;
496 obsolete0 @10 :Void;
497 queue @11 :Void;
498 analyticsEngine @12 : Void;
499 hyperdrive @13: Void;
500 durableObjectClass @14: Void;
501 workerdDebugPort @15: Void;
502 }
503 }
504 
505 struct DurableObjectNamespaceDesignator {
506 # The type of a Durable Object namespace binding.
507 
508 className @0 :Text;
509 # Exported class name that implements the Durable Object.
510 
511 serviceName @1 :Text;
512 # The service name of the worker that defines this class. If omitted, the current worker
513 # is assumed.
514 #
515 # Use of this field is discouraged. Instead, when accessing a different Worker's Durable
516 # Objects, specify a `service` binding to that worker, and have the worker implement an
517 # appropriate API.
518 #
519 # (This is intentionally not a ServiceDesignator because you cannot choose an alternate
520 # entrypoint here; the class name IS the entrypoint.)
521 }
522 
523 struct CryptoKey {
524 # Parameters to crypto.subtle.importKey().
525 
526 union {
527 raw @0 :Data;
528 hex @1 :Text;
529 base64 @2 :Text;
530 # Raw key material, possibly hex or base64-encoded. Use this for symmetric keys.
531 #
532 # Hint: `raw` would typically be used with Cap'n Proto's `embed` syntax to embed an
533 # external binary key file. `hex` or `base64` could do that too but can also be specified
534 # inline.
535 
536 pkcs8 @3 :Text;
537 # Private key in PEM-encoded PKCS#8 format.
538 
539 spki @4 :Text;
540 # Public key in PEM-encoded SPKI format.
541 
542 jwk @5 :Text;
543 # Key in JSON format.
544 }
545 
546 algorithm :union {
547 # Value for the `algorithm` parameter.
548 
549 name @6 :Text;
550 # Just a name, like `AES-GCM`.
551 
552 json @7 :Text;
553 # An object, encoded here as JSON.
554 }
555 
556 extractable @8 :Bool = false;
557 # Is the Worker allowed to export this key to obtain the underlying key material? Setting
558 # this false ensures that the key cannot be leaked by errant JavaScript code; the key can
559 # only be used in WebCrypto operations.
560 
561 usages @9 :List(Usage);
562 # What operations is this key permitted to be used for?
563 
564 enum Usage {
565 encrypt @0;
566 decrypt @1;
567 sign @2;
568 verify @3;
569 deriveKey @4;
570 deriveBits @5;
571 wrapKey @6;
572 unwrapKey @7;
573 }
574 }
575 
576 struct MemoryCacheLimits {
577 maxKeys @0 :UInt32;
578 maxValueSize @1 :UInt32;
579 maxTotalValueSize @2 :UInt64;
580 }
581 
582 struct WrappedBinding {
583 # A binding that wraps a group of (lower-level) bindings in a common API.
584 
585 moduleName @0 :Text;
586 # Wrapper module name.
587 # The module must be an internal one (provided by extension or registered in the c++ code).
588 # Module will be instantitated during binding initialization phase.
589 
590 entrypoint @1 :Text = "default";
591 # Module needs to export a function with a given name (default export gets "default" name).
592 # The function needs to accept a single `env` argument - a dictionary with inner bindings.
593 # Function will be invoked during initialization phase and its return value will be used as
594 # resulting binding value.
595 
596 innerBindings @2 :List(Binding);
597 # Inner bindings that will be created and passed in the env dictionary.
598 # These bindings shall be used to implement end-user api, and are not available to the
599 # binding consumers unless "re-exported" in wrapBindings function.
600 }
601 }
602 
603 globalOutbound @6 :ServiceDesignator = "internet";
604 # Where should the global "fetch" go to? The default is the service called "internet", which
605 # should usually be configured to talk to the public internet.
606 
607 cacheApiOutbound @11 :ServiceDesignator;
608 # Where should cache API (i.e. caches.default and caches.open(...)) requests go?
609 
610 durableObjectNamespaces @7 :List(DurableObjectNamespace);
611 # List of durable object namespaces in this Worker.
612 
613 struct DurableObjectNamespace {
614 className @0 :Text;
615 # Exported class name that implements the Durable Object.
616 #
617 # Changing the class name will not break compatibility with existing storage, so long as
618 # `uniqueKey` stays the same.
619 
620 union {
621 uniqueKey @1 :Text;
622 # A unique, stable ID associated with this namespace. This could be a GUID, or any other
623 # string which does not appear anywhere else in the world.
624 #
625 # This string is used to ensure that objects of this class have unique identifiers distinct
626 # from objects of any other class. Object IDs are cryptographically derived from `uniqueKey`
627 # and validated against it. It is impossible to guess or forge a valid object ID without
628 # knowing the `uniqueKey`. Hence, if you keep the key secret, you can prevent anyone from
629 # forging IDs. However, if you don't care if users can forge valid IDs, then it's not a big
630 # deal if the key leaks.
631 #
632 # DO NOT LOSE this key, otherwise it may be difficult or impossible to recover stored data.
633 
634 ephemeralLocal @2 :Void;
635 # Instances of this class are ephemeral -- they have no durable storage at all. The
636 # `state.storage` API will not be present. Additionally, this namespace will allow arbitrary
637 # strings as IDs. There are no `idFromName()` nor `newUniqueId()` methods; `get()` takes any
638 # string as a parameter.
639 #
640 # Ephemeral objects are NOT globally unique, only "locally" unique, for some definition of
641 # "local". For example, on Cloudflare's network, these objects are unique per-colo.
642 #
643 # WARNING: Cloudflare Workers currently limits this feature to Cloudflare-internal users
644 # only, because using them correctly requires deep understanding of Cloudflare network
645 # topology. We're working on something better for public consuption. Until then for
646 # "ephemeral" use cases we recommend using regular durable objects and just not storing
647 # anything. An object that hasn't stored anything will not consume any storage space on
648 # disk.
649 }
650 
651 preventEviction @3 :Bool;
652 # By default, Durable Objects are evicted after 10 seconds of inactivity, and expire 70 seconds
653 # after all clients have disconnected. Some applications may want to keep their Durable Objects
654 # pinned to memory forever, so we provide this flag to change the default behavior.
655 #
656 # Note that this is only supported in Workerd; production Durable Objects cannot toggle eviction.
657 
658 enableSql @4 :Bool;
659 # Whether or not Durable Objects in this namespace can use the `storage.sql` API to execute SQL
660 # queries.
661 #
662 # workerd uses SQLite to back all Durable Objects, but the SQL API is hidden by default to
663 # emulate behavior of traditional DO namespaces on Cloudflare that aren't SQLite-backed. This
664 # flag should be enabled when testing code that will run on a SQLite-backed namespace.
665 
666 container @5 :ContainerOptions;
667 # If present, Durable Objects in this namespace have attached containers.
668 # workerd will talk to the configured container engine to start containers for each
669 # Durable Object based on the given image. The Durable Object can access the container via the
670 # ctx.container API. TODO(CloudChamber): add link to docs.
671 
672 struct ContainerOptions {
673 imageName @0 :Text;
674 # Image name to be used to create the container using supported provider.
675 # By default, we pull the "latest" tag of this image.
676 }
677 }
678 
679 durableObjectUniqueKeyModifier @8 :Text;
680 # Additional text which is hashed together with `DurableObjectNamespace.uniqueKey`. When using
681 # worker inheritance, each derived worker must specify a unique modifier to ensure that its
682 # Durable Object instances have unique IDs from all other workers inheriting the same parent.
683 #
684 # DO NOT LOSE this value, otherwise it may be difficult or impossible to recover stored data.
685 
686 durableObjectStorage :union {
687 # Specifies where this worker's Durable Objects are stored.
688 
689 none @9 :Void;
690 # Default. The worker has no Durable Objects. `durableObjectNamespaces` must be empty, or
691 # define all namespaces as `ephemeralLocal`, or this must be an abstract worker (meant to be
692 # inherited by other workers, who will specify `durableObjectStorage`).
693 
694 inMemory @10 :Void;
695 # The `state.storage` API stores in-memory only. All stored data will persist for the
696 # lifetime of the process, but will be lost upon process exit.
697 #
698 # Individual objects will still shut down when idle as normal -- only data stored with the
699 # `state.storage` interface is persistent for the lifetime of the process.
700 #
701 # This mode is intended for local testing purposes.
702 
703 localDisk @12 :Text;
704 # ** EXPERIMENTAL; SUBJECT TO BACKWARDS-INCOMPATIBLE CHANGE **
705 #
706 # Durable Object data will be stored in a directory on local disk. This field is the name of
707 # a service, which must be a DiskDirectory service. For each Durable Object class, a
708 # subdirectory will be created using `uniqueKey` as the name. Within the directory, one or
709 # more files are created for each object, with names `<id>.<ext>`, where `.<ext>` may be any of
710 # a number of different extensions depending on the storage mode. (Currently, the main storage
711 # is a file with the extension `.sqlite`, and in certain situations extra files with the
712 # extensions `.sqlite-wal`, and `.sqlite-shm` may also be present.)
713 }
714 
715 # TODO(someday): Support distributing objects across a cluster. At present, objects are always
716 # local to one instance of the runtime.
717 
718 moduleFallback @13 :Text;
719 
720 tails @14 :List(ServiceDesignator);
721 # List of tail worker services that should receive tail events for this worker.
722 # See: https://developers.cloudflare.com/workers/observability/logs/tail-workers/
723 
724 streamingTails @15 :List(ServiceDesignator);
725 # List of streaming tail worker services that should receive tail events for this worker.
726 # NOTE: This will be deleted in a future refactor, do not depend on this.
727 
728 containerEngine :union {
729 none @16 :Void;
730 # No container engine configured. Container operations will not be available.
731 
732 localDocker @17 :DockerConfiguration;
733 # Use local Docker daemon for container operations.
734 # Only used for local development and testing purposes.
735 }
736 
737 struct DockerConfiguration {
738 socketPath @0 :Text;
739 # Path to the Docker socket.
740 
741 containerEgressInterceptorImage @1 :Text;
742 # Docker image name for the container egress interceptor sidecar.
743 # This sidecar intercepts outbound traffic from containers and routes it
744 # through workerd for egress mappings (setEgressHttp bindings).
745 # You can find this image in repositories like DockerHub: https://hub.docker.com/r/cloudflare/proxy-everything
746 }
747}
748 
749struct ExternalServer {
750 # Describes the ability to talk to a specific server, typically a back-end server available
751 # on the internal network.
752 #
753 # When a Worker contains a service binding that points to an ExternalServer, *all* fetch()
754 # calls on that binding will be delivered to that server, regardless of whether the hostname
755 # or protocol specified in the URL actually match the hostname or protocol used by the actual
756 # server. Typically, a Worker implementing a reverse proxy would use this to forward a request
757 # to a back-end application server. Such a back-end typically does not have a real public
758 # hostname, since it is only reachable through the proxy, but the requests forwarded to it will
759 # keep the hostname that was on the original request.
760 #
761 # Note that this also implies that regardless of whether the original URL was http: or https:,
762 # the request will be delivered to the target server using the protocol specified below. A
763 # header like `X-Forwarded-Proto` can be used to pass along the original protocol; see
764 # `HttpOptions`.
765 
766 address @0 :Text;
767 # Address/port of the server. Optional; if not specified, then you will be required to specify
768 # the address on the command line with with `--external-addr <name>=<addr>`.
769 #
770 # Examples:
771 # - "1.2.3.4": Connect to the given IPv4 address on the protocol's default port.
772 # - "1.2.3.4:80": Connect to the given IPv4 address and port.
773 # - "1234:5678::abcd": Connect to the given IPv6 address on the protocol's default port.
774 # - "[1234:5678::abcd]:80": Connect to the given IPv6 address and port.
775 # - "unix:/path/to/socket": Connect to the given Unix Domain socket by path.
776 # - "unix-abstract:name": On Linux, connect to the given "abstract" Unix socket name.
777 # - "example.com:80": Perform a DNS lookup to determine the address, and then connect to it.
778 #
779 # (These are the formats supported by KJ's parseAddress().)
780 
781 union {
782 http @1 :HttpOptions;
783 # Talk to the server over unencrypted HTTP.
784 
785 https :group {
786 # Talk to the server over encrypted HTTPS.
787 
788 options @2 :HttpOptions;
789 tlsOptions @3 :TlsOptions;
790 
791 certificateHost @4 :Text;
792 # If present, expect the host to present a certificate authenticating it as this hostname.
793 # If `certificateHost` is not provided, then the certificate is checked against `address`.
794 }
795 
796 tcp :group {
797 # Connect to the server over raw TCP. Bindings to this service will only support the
798 # `connect()` method; `fetch()` will throw an exception.
799 tlsOptions @5 :TlsOptions;
800 certificateHost @6 :Text;
801 }
802 
803 # TODO(someday): Cap'n Proto RPC
804 }
805}
806 
807struct Network {
808 # Describes the ability to talk to a network.
809 #
810 # This is commonly used to define the "internet" service which is the default `globalOutbound`
811 # for all Workers. To prevent SSRF, by default Workers will not be permitted to reach internal
812 # network addresses using global fetch(). It's recommended that you create ExternalServer
813 # bindings instead to grant access to specific servers. However, if you really want to, you
814 # can configure a service that grants arbitrary internal network access, like:
815 #
816 # ( name = "internalNetwork",
817 # network = (
818 # allow = ["public", "private"],
819 # )
820 # )
821 
822 allow @0 :List(Text) = ["public"];
823 deny @1 :List(Text);
824 # Specifies which network addresses the Worker will be allowed to connect to, e.g. using fetch().
825 # The default allows publicly-routable IP addresses only, in order to prevent SSRF attacks.
826 #
827 # The allow and deny lists specify network blocks in CIDR notation (IPv4 and IPv6), such as
828 # "192.0.2.0/24" or "2001:db8::/32". Traffic will be permitted as long as the address
829 # matches at least one entry in the allow list and none in the deny list.
830 #
831 # In addition to IPv4 and IPv6 CIDR notation, several special strings may be specified:
832 # - "private": Matches network addresses that are reserved by standards for private networks,
833 # such as "10.0.0.0/8" or "192.168.0.0/16". This is a superset of "local".
834 # - "public": Opposite of "private".
835 # - "local": Matches network addresses that are defined by standards to only be accessible from
836 # the local machine, such as "127.0.0.0/8" or Unix domain addresses.
837 # - "network": Opposite of "local".
838 # - "unix": Matches all Unix domain socket addresses. (In the future, we may support specifying a
839 # glob to narrow this to specific paths.)
840 # - "unix-abstract": Matches Linux's "abstract unix domain" addresses. (In the future, we may
841 # support specifying a glob.)
842 #
843 # In the case that the Worker specifies a DNS hostname rather than a raw address, these rules are
844 # used to filter the addresses returned by the lookup. If none of the returned addresses turn
845 # out to be permitted, then the system will behave as if the DNS entry did not exist.
846 #
847 # (The above is exactly the format supported by kj::Network::restrictPeers().)
848 
849 tlsOptions @2 :TlsOptions;
850}
851 
852struct DiskDirectory {
853 # Configures access to a directory on disk. This is a type of service which will expose an HTTP
854 # interface to the directory content.
855 #
856 # This is very bare-bones, generally not suitable for serving a web site on its own. In
857 # particular, no attempt is made to guess the `Content-Type` header. You normally would wrap
858 # this in a Worker that fills in the metadata in the way you want.
859 #
860 # A GET request targeting a directory (rather than a file) will return a basic JSAN directory
861 # listing like:
862 #
863 # [{"name":"foo","type":"file"},{"name":"bar","type":"directory"}]
864 #
865 # Possible "type" values are "file", "directory", "symlink", "blockDevice", "characterDevice",
866 # "namedPipe", "socket", "other".
867 #
868 # `Content-Type` will be `application/octet-stream` for files or `application/json` for a
869 # directory listing. Files will have a `Content-Length` header, directories will not. Symlinks
870 # will be followed (but there is intentionally no way to create one, even if `writable` is
871 # `true`), and treated according to the type of file they point to. The other inode types cannot
872 # be opened; trying to do so will produce a "406 Not Acceptable" error (on the theory that there
873 # is no acceptable format for these, regardless of what the client says it accepts).
874 #
875 # `HEAD` requests are properly optimized to perform a stat() without actually opening the file.
876 
877 path @0 :Text;
878 # The filesystem path of the directory. If not specified, then it must be specified on the
879 # command line with `--directory-path <service-name>=<path>`.
880 #
881 # Relative paths are interpreted relative to the current directory where the server is executed,
882 # NOT relative to the config file. So, you should usually use absolute paths in the config file.
883 
884 writable @1 :Bool = false;
885 # Whether to support PUT requests for writing. A PUT will write to a temporary file which
886 # is atomically moved into place upon successful completion of the upload. Parent directories are
887 # created as needed.
888 
889 allowDotfiles @2 :Bool = false;
890 # Whether to allow access to files and directories whose name starts with '.'. These are made
891 # inaccessible by default since they very often store metadata that is not meant to be served,
892 # e.g. a git repository or an `.htaccess` file.
893 #
894 # Note that the special links "." and ".." will never be accessible regardless of this setting.
895}
896 
897# ========================================================================================
898# Protocol options
899 
900struct HttpOptions {
901 # Options for using HTTP (as a client or server). In particular, this specifies behavior that is
902 # important in the presence of proxy servers, whether forward or reverse.
903 
904 style @0 :Style = host;
905 
906 enum Style {
907 host @0;
908 # Normal HTTP. The request line contains only the path, and the separate `Host` header
909 # specifies the hostname.
910 
911 proxy @1;
912 # HTTP proxy protocol. The request line contains a full URL instead of a path. No `Host`
913 # header is required. This is the protocol used by HTTP forward proxies. This allows you to
914 # implement such a proxy as a Worker.
915 }
916 
917 forwardedProtoHeader @1 :Text;
918 # If specified, then when the given header is present on a request, it specifies the protocol
919 # ("http" or "https") that was used by the original client. The request URL reported to the
920 # Worker will reflect this protocol. Otherwise, the URL will reflect the actual physical protocol
921 # used by the server in receiving the request.
922 #
923 # This option is useful when this server sits behind a reverse proxy that performs TLS
924 # termination. Typically such proxies forward the original protocol in a header named something
925 # like "X-Forwarded-Proto".
926 #
927 # This setting is ignored when `style` is `proxy`.
928 
929 cfBlobHeader @2 :Text;
930 # If set, then the `request.cf` object will be encoded (as JSON) into / parsed from the header
931 # with this name. Otherwise, it will be discarded on send / `undefined` on receipt.
932 
933 injectRequestHeaders @3 :List(Header);
934 # List of headers which will be automatically injected into all requests. This can be used
935 # e.g. to add an authorization token to all requests when using `ExternalServer`. It can also
936 # apply to incoming requests received on a `Socket` to modify the headers that will be delivered
937 # to the app. Any existing header with the same name is removed.
938 
939 injectResponseHeaders @4 :List(Header);
940 # Same as `injectRequestHeaders` but for responses.
941 
942 struct Header {
943 name @0 :Text;
944 # Case-insensitive.
945 
946 value @1 :Text;
947 # If null, the header will be removed.
948 }
949 
950 capnpConnectHost @5 :Text;
951 # A CONNECT request for this host+port will be treated as a request to form a Cap'n Proto RPC
952 # connection. The server will expose a WorkerdBootstrap as the bootstrap interface, allowing
953 # events to be delivered to the target worker via capnp. Clients will use capnp for non-HTTP
954 # event types (especially JSRPC).
955 
956 # TODO(someday): When we support TCP, include an option to deliver CONNECT requests to the
957 # TCP handler.
958}
959 
960struct TlsOptions {
961 # Options that apply when using TLS. Can apply on either the client or the server side, depending
962 # on the context.
963 #
964 # This is based on KJ's TlsContext::Options.
965 
966 keypair @0 :Keypair;
967 # The default private key and certificate to use. Optional when acting as a client.
968 
969 struct Keypair {
970 privateKey @0 :Text;
971 # Private key in PEM format. Supports PKCS8 keys as well as "traditional format" RSA and DSA
972 # keys.
973 #
974 # Remember that you can use Cap'n Proto's `embed` syntax to reference an external file.
975 
976 certificateChain @1 :Text;
977 # Certificate chain in PEM format. A chain can be constructed by concatenating multiple
978 # PEM-encoded certificates, starting with the leaf certificate.
979 }
980 
981 # TODO(someday): Support SNI-based keypair selection? Is a hostname -> keypair map good enough?
982 # Does it need to support wildcards? Maybe we should just let you provide a pile of certs and
983 # we can figure out which hosts each one matches?
984 
985 requireClientCerts @1 :Bool = false;
986 # If true, then when acting as a server, incoming connections will be rejected unless they bear
987 # a certificate signed by one of the trusted CAs.
988 #
989 # Typically, when using this, you'd set `trustBrowserCas = false` and list a specific private CA
990 # in `trustedCertificates`.
991 
992 trustBrowserCas @2 :Bool = false;
993 # If true, trust certificates which are signed by one of the CAs that browsers normally trust.
994 # You should typically set this true when talking to the public internet, but you may want to
995 # set it false when talking to servers on your internal network.
996 
997 trustedCertificates @3 :List(Text);
998 # Additional CA certificates to trust, in PEM format. Remember that you can use Cap'n Proto's
999 # `embed` syntax to read the certificates from other files.
1000 
1001 minVersion @4 :Version = goodDefault;
1002 # Minimum TLS version that will be allowed. Generally you should not override this unless you
1003 # have unusual backwards-compatibility needs.
1004 
1005 enum Version {
1006 goodDefault @0;
1007 # A good default chosen by the code maintainers. May change over time.
1008 
1009 ssl3 @1;
1010 tls1Dot0 @2;
1011 tls1Dot1 @3;
1012 tls1Dot2 @4;
1013 tls1Dot3 @5;
1014 }
1015 
1016 cipherList @5 :Text;
1017 # OpenSSL cipher list string. The default is a curated list designed to be compatible with
1018 # almost all software in current use (specifically, based on Mozilla's "intermediate"
1019 # recommendations). The defaults will change in future versions of this software to account
1020 # for the latest cryptanalysis.
1021 #
1022 # Generally you should only specify your own `cipherList` if:
1023 # - You have extreme backwards-compatibility needs and wish to enable obsolete and/or broken
1024 # algorithms.
1025 # - You need quickly to disable an algorithm recently discovered to be broken.
1026}
1027 
1028# ========================================================================================
1029# Extensions
1030 
1031struct Extension {
1032 # Additional capabilities for workers.
1033 
1034 modules @0 :List(Module);
1035 # List of javascript modules provided by the extension.
1036 # These modules can either be imported directly as user-level api (if not marked internal)
1037 # or used to define more complicated workerd constructs such as wrapped bindings and events.
1038 
1039 struct Module {
1040 # A module extending workerd functionality.
1041 
1042 name @0 :Text;
1043 # Full js module name.
1044 
1045 internal @1 :Bool = false;
1046 # Internal modules can be imported by other extension modules only and not the user code.
1047 
1048 esModule @2 :Text;
1049 # Raw source code of ES module.
1050 }
1051}
1052 
1053# ========================================================================================
1054# Fallback Service Request
1055# Used only to define the JSON structure of a request to the fallback service.
1056 
1057struct FallbackServiceRequest {
1058 type @0 :Text;
1059 specifier @1 :Text;
1060 rawSpecifier @2 :Text;
1061 referrer @3 :Text;
1062 
1063 struct Attribute {
1064 name @0: Text;
1065 value @1: Text;
1066 }
1067 attributes @4 :List(Attribute);
1068}