File
Blob: src/workerd/server/workerd.capnp
| 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"'). |
| 40 | using Cxx = import "/capnp/c++.capnp"; |
| 41 | $Cxx.namespace("workerd::server::config"); |
| 42 | $Cxx.allowCancellation; |
| 43 | |
| 44 | struct 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 | |
| 99 | struct 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 | |
| 117 | struct 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 | |
| 163 | struct 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 | |
| 199 | struct 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 | |
| 237 | struct 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 | |
| 749 | struct 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 | |
| 807 | struct 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 | |
| 852 | struct 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 | |
| 900 | struct 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 | |
| 960 | struct 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 | |
| 1031 | struct 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 | |
| 1057 | struct 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 | } |