diff --git a/README.md b/README.md
index 9502ade1..bbab84db 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,10 @@
-[![contributions welcome](https://img.shields.io/badge/contributions-welcome-green.svg?style=flat)](https://github.com/serverlessworkflow/specification/issues)
-[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/serverlessworkflow/specification/blob/master/LICENSE)
-[](https://cloud-native.slack.com/messages/serverless-workflow)
-[](https://serverlessworkflow.io/)
+[![contributions Welcome](https://img.shields.io/badge/Contributions-Welcome-green.svg?style=flat)](https://github.com/serverlessworkflow/specification/issues)
+[![license](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/serverlessworkflow/specification/blob/master/LICENSE)
+[](https://github.com/serverlessworkflow/specification/releases/latest)
+
+[](https://serverlessworkflow.io/)
+[](https://cloud-native.slack.com/messages/serverless-workflow)
+[](https://www.linkedin.com/company/serverless-workflow/)
[](https://twitter.com/CNCFWorkflow)
## Table of Contents
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..1c341b87
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,25 @@
+# Security Policy
+
+## Reporting a Vulnerability
+
+The Serverless Workflow team and community take security bugs very seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
+
+To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/serverlessworkflow/specification/security/advisories/new) tab.
+
+The Serverless Workflow team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
+
+## Security Best Practices
+
+To help ensure the security of your workflows, we recommend the following best practices:
+
+- **Keep Up to Date**: Always use the latest version of the Serverless Workflow DSL.
+- **Review Code**: Regularly review your workflows and code for potential security issues.
+- **Access Control**: Implement proper access controls to restrict who can create, modify, or execute workflows.
+- **Monitor and Audit**: Continuously monitor and audit workflows to detect and respond to any suspicious activities.
+- **Secure External Resources**: Ensure that any resources external to a workflow definition are always secured using modern authentication policies as defined in the DSL.
+- **Use Trusted Containers and Scripts**: When relying on [run tasks](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#run), only use trusted container images, scripts, commands and workflows.
+- **Custom Functions**: Only use custom functions from the [Serverless Workflow Catalog](https://github.com/serverlessworkflow/catalog) or from trusted sources to avoid introducing vulnerabilities.
+
+---
+
+Thank you for helping to keep the Serverless Workflow DSL secure!
diff --git a/ctk/features/set.feature b/ctk/features/set.feature
index c0772f88..c5fd4395 100644
--- a/ctk/features/set.feature
+++ b/ctk/features/set.feature
@@ -3,7 +3,7 @@ Feature: Set Task
I want to ensure that set tasks can be executed within the workflow
So that my implementation conforms to the expected behavior
- # Tests emit tasks
+ # Tests set tasks
Scenario: Set Task
Given a workflow with definition:
"""yaml
diff --git a/dsl-reference.md b/dsl-reference.md
index a8b37b35..d36fded5 100644
--- a/dsl-reference.md
+++ b/dsl-reference.md
@@ -25,8 +25,8 @@
+ [Shell](#shell-process)
+ [Script](#script-process)
+ [Workflow](#workflow-process)
- - [Switch](#switch)
- [Set](#set)
+ - [Switch](#switch)
- [Try](#try)
- [Wait](#wait)
+ [Flow Directive](#flow-directive)
@@ -42,6 +42,7 @@
- [Standard Error Types](#standard-error-types)
+ [Event Consumption Strategy](#event-consumption-strategy)
+ [Event Filter](#event-filter)
+ + [Event Properties](#event-properties)
+ [Retry](#retry)
+ [Input](#input)
+ [Output](#output)
@@ -50,6 +51,7 @@
+ [Duration](#duration)
+ [HTTP Response](#http-response)
+ [HTTP Request](#http-request)
+ + [URI Template](#uri-template)
## Abstract
@@ -83,7 +85,7 @@ Documents the workflow definition.
| dsl | `string` | `yes` | The version of the DSL used to define the workflow. |
| namespace | `string` | `yes` | The workflow's namespace.
|
| name | `string` | `yes` | The workflow's name.
|
-| version | `string` | `yes` | The workflow's [semantic version]
+| version | `string` | `yes` | The workflow's [semantic version](https://semver.org/) |
| title | `string` | `no` | The workflow's title. |
| summary | `string` | `no` | The workflow's Markdown summary. |
| tags | `map[string, string]` | `no` | A key/value mapping of the workflow's tags, if any. |
@@ -229,9 +231,9 @@ The Serverless Workflow DSL defines a list of [tasks](#task) that **must be** su
- [Call](#call), used to call services and/or functions.
- [Do](#do), used to define one or more subtasks to perform in sequence.
- [Fork](#fork), used to define one or more subtasks to perform concurrently.
-- [Emit](#emit), used to emit [events](#event).
+- [Emit](#emit), used to emit [events](#event-properties).
- [For](#for), used to iterate over a collection of items, and conditionally perform a task for each of them.
-- [Listen](#listen), used to listen for an [event](#event) or more.
+- [Listen](#listen), used to listen for an [event](#event-properties) or more.
- [Raise](#raise), used to raise an [error](#error) and potentially fault the [workflow](#workflow).
- [Run](#run), used to run a [container](#container-process), a [script](#script-process) , a [shell](#shell-process) command or even another [workflow](#workflow-process).
- [Switch](#switch), used to dynamically select and execute one of multiple alternative paths based on specified conditions
@@ -279,7 +281,7 @@ do:
Serverless Workflow defines several default functions that **MUST** be supported by all implementations and runtimes:
-- [AsyncAPI](#asyncapi)
+- [AsyncAPI](#asyncapi-call)
- [gRPC](#grpc-call)
- [HTTP](#http-call)
- [OpenAPI](#openapi-call)
@@ -368,9 +370,10 @@ The [HTTP Call](#http-call) enables workflows to interact with external services
| Name | Type | Required | Description|
|:--|:---:|:---:|:---|
| method | `string` | `yes` | The HTTP request method. |
-| endpoint | [`endpoint`](#endpoint) | `yes` | An URI or an object that describes the HTTP endpoint to call. |
+| endpoint | `string`\|[`endpoint`](#endpoint) | `yes` | An URI or an object that describes the HTTP endpoint to call. |
| headers | `map` | `no` | A name/value mapping of the HTTP headers to use, if any. |
| body | `any` | `no` | The HTTP request body, if any. |
+| query | `map[string, any]` | `no` | A name/value mapping of the query parameters to use, if any. |
| output | `string` | `no` | The http call's output format.
*Supported values are:*
*- `raw`, which output's the base-64 encoded [http response](#http-response) content, if any.*
*- `content`, which outputs the content of [http response](#http-response), possibly deserialized.*
*- `response`, which outputs the [http response](#http-response).*
*Defaults to `content`.* |
###### Examples
@@ -494,7 +497,7 @@ Allows workflows to publish events to event brokers or messaging systems, facili
| Name | Type | Required | Description |
|:--|:---:|:---:|:---|
-| emit.event | [`event`](#event) | `yes` | Defines the event to emit. |
+| emit.event | [`eventProperties`](#event-properties) | `yes` | Defines the event to emit. |
##### Examples
@@ -508,15 +511,16 @@ do:
- emitEvent:
emit:
event:
- source: https://petstore.com
- type: com.petstore.order.placed.v1
- data:
- client:
- firstName: Cruella
- lastName: de Vil
- items:
- - breed: dalmatian
- quantity: 101
+ with:
+ source: https://petstore.com
+ type: com.petstore.order.placed.v1
+ data:
+ client:
+ firstName: Cruella
+ lastName: de Vil
+ items:
+ - breed: dalmatian
+ quantity: 101
```
#### For
@@ -528,9 +532,9 @@ Allows workflows to iterate over a collection of items, executing a defined set
| Name | Type | Required | Description|
|:--|:---:|:---:|:---|
| for.each | `string` | `no` | The name of the variable used to store the current item being enumerated.
Defaults to `item`. |
-| for.in | `string` | `yes` | A [runtime expression](#runtime-expressions) used to get the collection to enumerate. |
+| for.in | `string` | `yes` | A [runtime expression](dsl.md#runtime-expressions) used to get the collection to enumerate. |
| for.at | `string` | `no` | The name of the variable used to store the index of the current item being enumerated.
Defaults to `index`. |
-| while | `string` | `no` | A [runtime expression](#runtime-expressions) that represents the condition, if any, that must be met for the iteration to continue. |
+| while | `string` | `no` | A [runtime expression](dsl.md#runtime-expressions) that represents the condition, if any, that must be met for the iteration to continue. |
| do | [`task`](#task) | `yes` | The task to perform for each item in the collection. |
##### Examples
@@ -555,8 +559,8 @@ do:
one:
with:
type: com.fake.petclinic.pets.checkup.completed.v2
- output:
- as: '.pets + [{ "id": $pet.id }]'
+ output:
+ as: '.pets + [{ "id": $pet.id }]'
```
#### Fork
@@ -601,7 +605,6 @@ do:
room: ${ .room.number }
```
-
#### Listen
Provides a mechanism for workflows to await and react to external events, enabling event-driven behavior within workflow systems.
@@ -964,7 +967,7 @@ do:
##### Switch Case
-Defines a switch case, encompassing of a condition for matching and an associated action to execute upon a match.
+Defines a switch case, encompassing a condition for matching and an associated action to execute upon a match.
| Name | Type | Required | Description |
|:--|:---:|:---:|:---|
@@ -1073,7 +1076,7 @@ Defines an external resource.
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
| name | `string` | `no` | The name, if any, of the defined resource. |
-| uri | `string` | `yes` | The URI at which to get the defined resource. |
+| uri | [`uri-template`](#uri-template) | `yes` | The URI at which to get the defined resource. |
| authentication | [`authentication`](#authentication) | `no` | The authentication policy, or the name of the authentication policy, to use when fecthing the resource. |
##### Examples
@@ -1113,7 +1116,7 @@ document:
use:
secrets:
- usernamePasswordSecret
- authentication:
+ authentications:
sampleBasicFromSecret:
basic:
use: usernamePasswordSecret
@@ -1208,8 +1211,8 @@ Defines the fundamentals of an 'oauth2' authentication
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
-| authority | `string` | `yes` | The URI that references the OAuth2 authority to use. |
-| grant | `string` | `yes` | The grant type to use.
+| authority | [`uri-template`](#uri-template) | `yes` | The URI that references the OAuth2 authority to use. |
+| grant | `string` | `yes` | The grant type to use. |
| client.id | `string` | `yes` | The client id to use. |
| client.secret | `string` | `no` | The client secret to use, if any. |
| scopes | `string[]` | `no` | The scopes, if any, to request the token for. |
@@ -1346,7 +1349,7 @@ Defines the [Problem Details RFC](https://datatracker.ietf.org/doc/html/rfc7807)
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
-| type | `string` | `yes` | A URI reference that identifies the [`error`](#error) type.
For cross-compatibility concerns, it is strongly recommended to use [Standard Error Types](#standard-error-types) whenever possible.
Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error). |
+| type | [`uri-template`](#uri-template) | `yes` | A URI reference that identifies the [`error`](#error) type.
For cross-compatibility concerns, it is strongly recommended to use [Standard Error Types](#standard-error-types) whenever possible.
Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error). |
| status | `integer` | `yes` | The status code generated by the origin for this occurrence of the [`error`](#error).
For cross-compatibility concerns, it is strongly recommended to use [HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231#section-6) whenever possible.
Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error). |
| instance | `string` | `yes` | A [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) used to reference the component the [`error`](#error) originates from.
Runtimes **MUST** set the property when raising or escalating the [`error`](#error). Otherwise ignore. |
| title | `string` | `no` | A short, human-readable summary of the [`error`](#error). |
@@ -1355,7 +1358,7 @@ Defines the [Problem Details RFC](https://datatracker.ietf.org/doc/html/rfc7807)
#### Examples
```yaml
-type: https://https://serverlessworkflow.io/spec/1.0.0/errors/communication
+type: https://serverlessworkflow.io/spec/1.0.0/errors/communication
title: Service Not Available
status: 503
```
@@ -1366,14 +1369,14 @@ Standard error types serve the purpose of categorizing errors consistently acros
| Type | Status¹ | Description |
|------|:-------:|-------------|
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/configuration](#) | `400` | Errors resulting from incorrect or invalid configuration settings, such as missing or misconfigured environment variables, incorrect parameter values, or configuration file errors. |
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/validation](#) | `400` | Errors arising from validation processes, such as validation of input data, schema validation failures, or validation constraints not being met. These errors indicate that the provided data or configuration does not adhere to the expected format or requirements specified by the workflow. |
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/expression](#) | `400` | Errors occurring during the evaluation of runtime expressions, such as invalid syntax or unsupported operations. |
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/authentication](#) | `401` | Errors related to authentication failures. |
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/authorization](#) | `403` | Errors related to unauthorized access attempts or insufficient permissions to perform certain actions within the workflow. |
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/timeout](#) | `408` | Errors caused by timeouts during the execution of tasks or during interactions with external services. |
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/communication](#) | `500` | Errors encountered while communicating with external services, including network errors, service unavailable, or invalid responses. |
-| [https://https://serverlessworkflow.io/spec/1.0.0/errors/runtime](#) | `500` | Errors occurring during the runtime execution of a workflow, including unexpected exceptions, errors related to resource allocation, or failures in handling workflow tasks. These errors typically occur during the actual execution of workflow components and may require runtime-specific handling and resolution strategies. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/configuration](#) | `400` | Errors resulting from incorrect or invalid configuration settings, such as missing or misconfigured environment variables, incorrect parameter values, or configuration file errors. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/validation](#) | `400` | Errors arising from validation processes, such as validation of input data, schema validation failures, or validation constraints not being met. These errors indicate that the provided data or configuration does not adhere to the expected format or requirements specified by the workflow. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/expression](#) | `400` | Errors occurring during the evaluation of runtime expressions, such as invalid syntax or unsupported operations. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/authentication](#) | `401` | Errors related to authentication failures. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/authorization](#) | `403` | Errors related to unauthorized access attempts or insufficient permissions to perform certain actions within the workflow. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/timeout](#) | `408` | Errors caused by timeouts during the execution of tasks or during interactions with external services. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/communication](#) | `500` | Errors encountered while communicating with external services, including network errors, service unavailable, or invalid responses. |
+| [https://serverlessworkflow.io/spec/1.0.0/errors/runtime](#) | `500` | Errors occurring during the runtime execution of a workflow, including unexpected exceptions, errors related to resource allocation, or failures in handling workflow tasks. These errors typically occur during the actual execution of workflow components and may require runtime-specific handling and resolution strategies. |
¹ *Default value. The `status code` that best describe the error should always be used.*
@@ -1389,6 +1392,28 @@ Represents the configuration of an event consumption strategy.
| any | [`eventFilter[]`](#event-filter) | `no` | Configures the workflow to wait for any of the defined events before resuming execution.
*Required if `all` and `one` have not been set.* |
| one | [`eventFilter`](#event-filter) | `no` | Configures the workflow to wait for the defined event before resuming execution.
*Required if `all` and `any` have not been set.* |
+### Event Properties
+
+An event object typically includes details such as the event type, source, timestamp, and unique identifier along with any relevant data payload. The [Cloud Events specification](https://cloudevents.io/), favored by Serverless Workflow, standardizes this structure to ensure interoperability across different systems and services.
+
+#### Properties
+
+| Property | Type | Required | Description |
+|----------|:----:|:--------:|-------------|
+| id | `string` | `no` | Identifies the event. `source` + `id` is unique for each distinct event.
*Required when emitting an event using `emit.event.with`.* |
+| source | `string` | `no` | An URI formatted string, or [runtime expression](dsl.md#runtime-expressions), that identifies the context in which an event happened. `source` + `id` is unique for each distinct event.
*Required when emitting an event using `emit.event.with`.* |
+| type | `string` | `no` | Describes the type of event related to the originating occurrence.
*Required when emitting an event using `emit.event.with`.* |
+| time | `string` | `no` | A string, or [runtime expression](dsl.md#runtime-expressions), representing the timestamp of when the occurrence happened. |
+| subject | `string` | `no` | Describes the subject of the event in the context of the event producer. |
+| datacontenttype | `string` | `no` | Content type of `data` value. If omitted, it implies the `data` is a JSON value conforming to the "application/json" media type. |
+| dataschema | `string` | `no` | An URI formatted string, or [runtime expression](dsl.md#runtime-expressions), that identifies the schema that `data` adheres to. |
+| data | `object` | `no` | The event payload. |
+
+*Additional properties can be supplied, see the Cloud Events specification [documentation](https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#extension-context-attributes) for more info.*
+
+*When used in an [`eventFilter`](#event-filter), at least one property must be supplied.*
+
+
### Event Filter
An event filter is a mechanism used to selectively process or handle events based on predefined criteria, such as event type, source, or specific attributes.
@@ -1397,7 +1422,7 @@ An event filter is a mechanism used to selectively process or handle events base
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
-| with | `object` | `yes` | A name/value mapping of the attributes filtered events must define. Supports both regular expressions and runtime expressions. |
+| with | [`eventProperties`](#event-properties) | `yes` | A name/value mapping of the attributes filtered events must define. Supports both regular expressions and runtime expressions. |
| correlate | [`map[string, correlation]`](#correlation) | `no` | A name/definition mapping of the correlations to attempt when filtering events. |
### Correlation
@@ -1473,7 +1498,7 @@ When set, runtimes must validate input data against the defined schema, unless d
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
| schema | [`schema`](#schema) | `no` | The [`schema`](#schema) used to describe and validate input data.
*Even though the schema is not required, it is strongly encouraged to document it, whenever feasible.* |
-| from | `string`
`object` | `no` | A [runtime expression](#runtime-expressions), if any, used to filter and/or mutate the workflow/task input. |
+| from | `string`
`object` | `no` | A [runtime expression](dsl.md#runtime-expressions), if any, used to filter and/or mutate the workflow/task input. |
#### Examples
@@ -1502,7 +1527,7 @@ When set, runtimes must validate output data against the defined schema, unless
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
| schema | [`schema`](#schema) | `no` | The [`schema`](#schema) used to describe and validate output data.
*Even though the schema is not required, it is strongly encouraged to document it, whenever feasible.* |
-| as | `string`
`object` | `no` | A [runtime expression](#runtime-expressions), if any, used to filter and/or mutate the workflow/task output. |
+| as | `string`
`object` | `no` | A [runtime expression](dsl.md#runtime-expressions), if any, used to filter and/or mutate the workflow/task output. |
#### Examples
@@ -1636,6 +1661,17 @@ minutes: 15
seconds: 30
```
+### Endpoint
+
+Describes an enpoint.
+
+#### Properties
+
+| Property | Type | Required | Description |
+|----------|:----:|:--------:|-------------|
+| uri | `string` | `yes` | The endpoint's URI. |
+| authentication | `[authentication](#authentication)` | `no` | The authentication policy to use. |
+
### HTTP Response
Describes an HTTP response.
@@ -1685,4 +1721,22 @@ method: get
uri: https://petstore.swagger.io/v2/pet/1
headers:
Content-Type: application/json
-```
\ No newline at end of file
+```
+
+### URI Template
+
+The DSL has limited support for URI template syntax as defined by [RFC 6570](https://datatracker.ietf.org/doc/html/rfc6570). Specifically, only the [Simple String Expansion](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.2) is supported, which allows authors to embed variables in a URI.
+
+To substitute a variable within a URI, use the `{}` syntax. The identifier inside the curly braces will be replaced with its value during runtime evaluation. If no value is found for the identifier, an empty string will be used.
+
+This has the following limitations compared to runtime expressions:
+
+- Only top-level properties can be interpolated within strings, thus identifiers are treated verbatim. This means that `{pet.id}` will be replaced with the value of the `"pet.id"` property, not the value of the `id` property of the `pet` property.
+- The referenced variable must be of type `string`, `number`, `boolean`, or `null`. If the variable is of a different type an error with type `https://https://serverlessworkflow.io/spec/1.0.0/errors/expression` and status `400` will be raised.
+- [Runtime expression arguments](./dsl.md#runtime-expression-arguments) are not available for string substitution.
+
+#### Examples
+
+```yaml
+uri: https://petstore.swagger.io/v2/pet/{petId}
+```
diff --git a/dsl.md b/dsl.md
index f69bdcc1..3339d767 100644
--- a/dsl.md
+++ b/dsl.md
@@ -81,7 +81,7 @@ Workflows in the Serverless Workflow DSL can exist in several phases, each indic
Additionally, the flow of execution within a workflow can be controlled using [directives*](dsl-reference.md#flow-directive), which provide instructions to the workflow engine on how to manage and handle specific aspects of workflow execution.
-**To learn more about flow directives and how they can be utilized to control the execution and behavior of workflows, please refer to [Flow Directives](dsl-reference.md#flow-directive).*
+\**To learn more about flow directives and how they can be utilized to control the execution and behavior of workflows, please refer to [Flow Directives](dsl-reference.md#flow-directive).*
#### Components
@@ -102,14 +102,14 @@ The Serverless Workflow DSL defines several default [task](dsl-reference.md#task
- [Call](dsl-reference.md#call), used to call services and/or functions.
- [Do](dsl-reference.md#do), used to define one or more subtasks to perform in sequence.
-- [Fork](dsl-reference.md#fork), used to define one or more two subtasks to perform in parallel.
- [Emit](dsl-reference.md#emit), used to emit [events](dsl-reference.md#event).
- [For](dsl-reference.md#for), used to iterate over a collection of items, and conditionally perform a task for each of them.
+- [Fork](dsl-reference.md#fork), used to define one or more two subtasks to perform in parallel.
- [Listen](dsl-reference.md#listen), used to listen for an [event](dsl-reference.md#event) or more.
- [Raise](dsl-reference.md#raise), used to raise an [error](dsl-reference.md#error) and potentially fault the [workflow](dsl-reference.md#workflow).
- [Run](dsl-reference.md#run), used to run a [container](dsl-reference.md#container-process), a [script](dsl-reference.md#script-process), a [shell](dsl-reference.md#shell-process) command or even another [workflow](dsl-reference.md#workflow-process).
-- [Switch](dsl-reference.md#switch), used to dynamically select and execute one of multiple alternative paths based on specified conditions
- [Set](dsl-reference.md#set), used to dynamically set or update the [workflow](dsl-reference.md#workflow)'s data during the its execution.
+- [Switch](dsl-reference.md#switch), used to dynamically select and execute one of multiple alternative paths based on specified conditions
- [Try](dsl-reference.md#try), used to attempt executing a specified [task](dsl-reference.md#task), and to handle any resulting [errors](dsl-reference.md#error) gracefully, allowing the [workflow](dsl-reference.md#workflow) to continue without interruption.
- [Wait](dsl-reference.md#wait), used to pause or wait for a specified duration before proceeding to the next task.
@@ -138,7 +138,7 @@ A workflow begins with the first task defined.
Once the task has been executed, different things can happen:
-- `continue`: the task ran to completion, and the next task, if any, should be executed. The task to run next is implictly the next in declaration order, or explicitly defined by the `then` property of the executed task. If the executed task is the last task, then the workflow's execution gracefully ends.
+- `continue`: the task ran to completion, and the next task, if any, should be executed. The task to run next is implicitly the next in declaration order, or explicitly defined by the `then` property of the executed task. If the executed task is the last task, then the workflow's execution gracefully ends.
- `fault`: the task raised an uncaught error, which abruptly halts the workflow's execution and makes it transition to `faulted` [status phase](#status-phases).
- `end`: the task explicitly and gracefully ends the workflow's execution.
@@ -196,17 +196,50 @@ Runtimes **may** optionally support other runtime expression languages, which au
CloudFlows defines [several arguments](#runtime-expression-arguments) that runtimes **must** provide during the evaluation of runtime expressions.
-When the evaluation of an expression fails, runtimes **must** raise an error with type `https://https://serverlessworkflow.io/spec/1.0.0/errors/expression` and status `400`.
+When the evaluation of an expression fails, runtimes **must** raise an error with type `https://serverlessworkflow.io/spec/1.0.0/errors/expression` and status `400`.
#### Runtime expression arguments
| Name | Type | Description |
|:-----|:----:|:------------|
-| context | `map` | The task's context data. |
+| context | `any` | The task's context data. |
| input | `any` | The task's filtered input. |
| secrets | `map` | A key/value map of the workflow secrets.
To avoid unintentional bleeding, secrets can only be used in the `input.from` runtime expression. |
| task | [`taskDescriptor`](#task-descriptor) | Describes the current task. |
-| workflow | [`workflowDescritor`](#workflow-descriptor) | Describes the current workflow. |
+| workflow | [`workflowDescriptor`](#workflow-descriptor) | Describes the current workflow. |
+| runtime | [`runtimeDescriptor`](#runtime-descriptor) | Describes the runtime. |
+
+##### Runtime Descriptor
+
+This argument contains information about the runtime executing the workflow.
+
+| Name | Type | Description | Example |
+|:-----|:----:|:------------| ------- |
+| name | `string` | A human friendly name for the runtime. | `Synapse`, `Sonata` |
+| version | `string` | The version of the runtime. This can be an arbitrary string | a incrementing positive integer (`362`), semantic version (`1.4.78`), commit hash (`04cd3be6da98fc35422c8caa821e0aa1ef6b2c02`) or container image label (`v0.7.43-alpine`) |
+| metadata | `map` | An object/map of implementation specific key-value pairs. This can be chosen by runtime implementors and usage of this argument signals that a given workflow definition might not be runtime agnostic | A Software as a Service (SaaS) provider might choose to expose information about the tenant the workflow is executed for e.g. `{ "organization": { "id": "org-ff51cff2-fc83-4d70-9af1-8dacdbbce0be", "name": "example-corp" }, "featureFlags": ["fastZip", "arm64"] }`. |
+
+##### Task Descriptor
+
+| Name | Type | Description | Example |
+|:-----|:----:|:------------|:--------|
+| name | `string` | The task's name. | `getPet` |
+| definition | `map` | The tasks definition (specified under the name) as a parsed object | `{ "call": "http", "with": { ... } }` |
+| input | `any` | The task's input *BEFORE* the `input.from` expression. For the result of `input.from` expression use the context of the runtime expression (for jq `.`) | - |
+| startedAt.iso8601 | `string` | The start time of the task as a ISO 8601 date time string. It uses `T` as the date-time delimiter, either UTC (`Z`) or a time zone offset (`+01:00`). The precision can be either seconds, milliseconds or nanoseconds | `2022-01-01T12:00:00Z`, `2022-01-01T12:00:00.123456Z`, `2022-01-01T12:00:00.123+01:00` |
+| startedAt.epochMillis | `integer` | The start time of the task as a integer value of milliseconds since midnight of 1970-01-01 UTC | `1641024000123` (="2022-01-01T08:00:00.123Z") |
+| startedAt.epochNanos | `integer` | The start time of the task as a integer value of nanoseconds since midnight of 1970-01-01 UTC | `1641024000123456` (="2022-01-01T08:00:00.123456Z") |
+
+##### Workflow Descriptor
+
+| Name | Type | Description | Example |
+|:-----|:----:|:------------|:--------|
+| id | `string` | A unique id of the workflow execution. Now specific format is imposed | UUIDv4: `4a5c8422-5868-4e12-8dd9-220810d2b9ee`, ULID: `0000004JFGDSW1H037G7J7SFB9` |
+| definition | `map` | The workflow's definition as a parsed object | `{ "document": { ... }, "do": [...] }` |
+| input | `any` | The workflow's input *BEFORE* the `input.from` expression. For the result of `input.from` expression use the `$input` argument | - |
+| startedAt.iso8601 | `string` | The start time of the execution as a ISO 8601 date time string. It uses `T` as the date-time delimiter, either UTC (`Z`) or a time zone offset (`+01:00`). The precision can be either seconds, milliseconds or nanoseconds | `2022-01-01T12:00:00Z`, `2022-01-01T12:00:00.123456Z`, `2022-01-01T12:00:00.123+01:00` |
+| startedAt.epochMillis | `integer` | The start time of the execution as a integer value of milliseconds since midnight of 1970-01-01 UTC | `1641024000123` (="2022-01-01T08:00:00.123Z") |
+| startedAt.epochNanos | `integer` | The start time of the execution as a integer value of nanoseconds since midnight of 1970-01-01 UTC | `1641024000123456` (="2022-01-01T08:00:00.123456Z") |
### Fault Tolerance
@@ -220,7 +253,7 @@ Errors in Serverless Workflow are described using the [Problem Details RFC](http
*Example error:*
```yaml
-type: https://https://serverlessworkflow.io/spec/1.0.0/errors/communication
+type: https://serverlessworkflow.io/spec/1.0.0/errors/communication
title: Service Unavailable
status: 503
detail: The service is currently unavailable. Please try again later.
@@ -263,7 +296,7 @@ Workflows and tasks alike can be configured to timeout after a defined amount of
When a timeout occur, runtimes **must** abruptly interrupt the execution of the workflow/task, and **must** raise an error that, if uncaught, force the workflow/task to transition to the [`faulted` status phase](#status-phases).
-A timeout error **must** have its `type` set to `https://https://serverlessworkflow.io/spec/1.0.0/errors/timeout` and **should** have its `status` set to `408`.
+A timeout error **must** have its `type` set to `https://serverlessworkflow.io/spec/1.0.0/errors/timeout` and **should** have its `status` set to `408`.
### Interoperability
@@ -275,7 +308,7 @@ Serverless Workflow DSL is designed to seamlessly interact with a variety of ser
- [**AsyncAPI**](dsl-reference.md#asyncapi-call): Facilitates interaction with asynchronous messaging protocols. AsyncAPI is designed for event-driven architectures, allowing workflows to publish and subscribe to events.
- [**OpenAPI**](dsl-reference.md#openapi-call): Enables communication with services that provide OpenAPI specifications, which is useful for defining and consuming RESTful APIs.
-Runtimes **must** raise an error with type `https://https://serverlessworkflow.io/spec/1.0.0/errors/communication` if and when a problem occurs during a call.
+Runtimes **must** raise an error with type `https://serverlessworkflow.io/spec/1.0.0/errors/communication` if and when a problem occurs during a call.
#### Custom and Non-Standard Interactions
diff --git a/examples/accumulate-room-readings.yaml b/examples/accumulate-room-readings.yaml
index 09bdf4d3..3b51d0f2 100644
--- a/examples/accumulate-room-readings.yaml
+++ b/examples/accumulate-room-readings.yaml
@@ -14,16 +14,14 @@ do:
correlate:
roomId:
from: .roomid
- output:
- as: .data.reading
- with:
source: https://my.home.com/sensor
type: my.home.sensors.humidity
correlate:
roomId:
from: .roomid
- output:
- as: .data.reading
+ output:
+ as: .data.reading
- logReading:
for:
each: reading
diff --git a/examples/http-query-params.yaml b/examples/http-query-params.yaml
new file mode 100644
index 00000000..6f34c67e
--- /dev/null
+++ b/examples/http-query-params.yaml
@@ -0,0 +1,25 @@
+# yaml-language-server: $schema=https://serverlessworkflow.io/schemas/1.0.0-alpha2/workflow.yaml
+document:
+ dsl: 1.0.0-alpha2
+ namespace: examples
+ name: http-query-params
+ version: 1.0.0-alpha2
+input:
+ schema:
+ format: json
+ document:
+ type: object
+ required:
+ - searchQuery
+ properties:
+ searchQuery:
+ type: string
+do:
+ - searchStarWarsCharacters:
+ call: http
+ with:
+ method: get
+ endpoint: https://swapi.dev/api/people/
+ query:
+ search: ${.searchQuery}
+
diff --git a/schema/workflow.yaml b/schema/workflow.yaml
index b6990d79..9783dc2b 100644
--- a/schema/workflow.yaml
+++ b/schema/workflow.yaml
@@ -1,3 +1,4 @@
+
$id: https://serverlessworkflow.io/schemas/1.0.0-alpha1/workflow.yaml
$schema: https://json-schema.org/draft/2020-12/schema
description: Serverless Workflow DSL - Workflow Schema
@@ -6,6 +7,7 @@ required: [ document, do ]
properties:
document:
type: object
+ unevaluatedProperties: false
properties:
dsl:
type: string
@@ -40,6 +42,7 @@ properties:
description: Configures the workflow's input.
use:
type: object
+ unevaluatedProperties: false
properties:
authentications:
type: object
@@ -88,6 +91,7 @@ properties:
description: Configures the workflow's output.
schedule:
type: object
+ unevaluatedProperties: false
properties:
every:
$ref: '#/$defs/duration'
@@ -186,7 +190,7 @@ $defs:
$ref: '#/$defs/referenceableAuthenticationPolicy'
description: The authentication policy, if any, to use when calling the AsyncAPI operation.
required: [ document, operationRef ]
- additionalProperties: false
+ unevaluatedProperties: false
description: Defines the AsyncAPI call to perform.
- title: CallGRPC
$ref: '#/$defs/taskBase'
@@ -206,6 +210,7 @@ $defs:
description: The proto resource that describes the GRPC service to call.
service:
type: object
+ unevaluatedProperties: false
properties:
name:
type: string
@@ -231,7 +236,7 @@ $defs:
additionalProperties: true
description: The arguments, if any, to call the method with.
required: [ proto, service, method ]
- additionalProperties: false
+ unevaluatedProperties: false
description: Defines the GRPC call to perform.
- title: CallHTTP
$ref: '#/$defs/taskBase'
@@ -262,12 +267,16 @@ $defs:
description: A name/value mapping of the headers, if any, of the HTTP request to perform.
body:
description: The body, if any, of the HTTP request to perform.
+ query:
+ type: object
+ additionalProperties: true
+ description: A name/value mapping of the query parameters, if any, of the HTTP request to perform.
output:
type: string
enum: [ raw, content, response ]
description: The http call output format. Defaults to 'content'.
required: [ method, endpoint ]
- additionalProperties: false
+ unevaluatedProperties: false
description: Defines the HTTP call to perform.
- title: CallOpenAPI
$ref: '#/$defs/taskBase'
@@ -300,7 +309,7 @@ $defs:
enum: [ raw, content, response ]
description: The http call output format. Defaults to 'content'.
required: [ document, operationId ]
- additionalProperties: false
+ unevaluatedProperties: false
description: Defines the OpenAPI call to perform.
- title: CallFunction
$ref: '#/$defs/taskBase'
@@ -327,6 +336,7 @@ $defs:
properties:
fork:
type: object
+ unevaluatedProperties: false
required: [ branches ]
properties:
branches:
@@ -355,41 +365,14 @@ $defs:
properties:
emit:
type: object
+ unevaluatedProperties: false
properties:
event:
type: object
properties:
- id:
- type: string
- description: The event's unique identifier
- source:
- description: Identifies the context in which an event happened
- oneOf:
- - title: LiteralSource
- type: string
- format: uri-template
- - $ref: '#/$defs/runtimeExpression'
- type:
- type: string
- description: This attribute contains a value describing the type of event related to the originating occurrence.
- time:
- oneOf:
- - title: LiteralTime
- type: string
- format: date-time
- - $ref: '#/$defs/runtimeExpression'
- subject:
- type: string
- datacontenttype:
- type: string
- description: Content type of data value. This attribute enables data to carry any type of content, whereby format and encoding might differ from that of the chosen event format.
- dataschema:
- oneOf:
- - title: LiteralDataSchema
- type: string
- format: uri-template
- - $ref: '#/$defs/runtimeExpression'
- required: [ source, type ]
+ with:
+ $ref: '#/$defs/eventProperties'
+ required: [ source, type ]
additionalProperties: true
required: [ event ]
forTask:
@@ -402,6 +385,7 @@ $defs:
properties:
for:
type: object
+ unevaluatedProperties: false
properties:
each:
type: string
@@ -430,6 +414,7 @@ $defs:
properties:
listen:
type: object
+ unevaluatedProperties: false
properties:
to:
$ref: '#/$defs/eventConsumptionStrategy'
@@ -445,6 +430,7 @@ $defs:
properties:
raise:
type: object
+ unevaluatedProperties: false
properties:
error:
$ref: '#/$defs/error'
@@ -465,6 +451,7 @@ $defs:
properties:
container:
type: object
+ unevaluatedProperties: false
properties:
image:
type: string
@@ -489,6 +476,7 @@ $defs:
properties:
script:
type: object
+ unevaluatedProperties: false
properties:
language:
type: string
@@ -518,6 +506,7 @@ $defs:
properties:
shell:
type: object
+ unevaluatedProperties: false
properties:
command:
type: string
@@ -540,6 +529,7 @@ $defs:
workflow:
title: RunWorkflowDescriptor
type: object
+ unevaluatedProperties: false
properties:
namespace:
type: string
@@ -591,8 +581,8 @@ $defs:
additionalProperties:
type: object
title: SwitchCase
- required:
- - then
+ unevaluatedProperties: false
+ required: [ then ]
properties:
when:
type: string
@@ -613,6 +603,7 @@ $defs:
$ref: '#/$defs/taskList'
catch:
type: object
+ unevaluatedProperties: false
properties:
errors:
title: CatchErrors
@@ -651,6 +642,7 @@ $defs:
- type: string
referenceableAuthenticationPolicy:
type: object
+ unevaluatedProperties: false
oneOf:
- title: AuthenticationPolicyReference
properties:
@@ -662,6 +654,7 @@ $defs:
- $ref: '#/$defs/authenticationPolicy'
secretBasedAuthenticationPolicy:
type: object
+ unevaluatedProperties: false
properties:
use:
type: string
@@ -675,8 +668,10 @@ $defs:
properties:
basic:
type: object
+ unevaluatedProperties: false
oneOf:
- - properties:
+ - title: BasicAuthenticationData
+ properties:
username:
type: string
description: The username to use.
@@ -691,8 +686,10 @@ $defs:
properties:
bearer:
type: object
+ unevaluatedProperties: false
oneOf:
- - properties:
+ - title: BearerAuthenticationData
+ properties:
token:
type: string
description: The bearer token to use.
@@ -704,17 +701,20 @@ $defs:
properties:
oauth2:
type: object
+ unevaluatedProperties: false
oneOf:
- - properties:
+ - title: OAuth2AutenthicationData
+ properties:
authority:
type: string
- format: uri
+ format: uri-template
description: The URI that references the OAuth2 authority to use.
grant:
type: string
description: The grant type to use.
client:
type: object
+ unevaluatedProperties: false
properties:
id:
type: string
@@ -752,6 +752,7 @@ $defs:
description: Defines an authentication policy.
oauth2Token:
type: object
+ unevaluatedProperties: false
properties:
token:
type: string
@@ -763,6 +764,7 @@ $defs:
duration:
type: object
minProperties: 1
+ unevaluatedProperties: false
properties:
days:
type: integer
@@ -782,6 +784,7 @@ $defs:
description: The definition of a duration.
error:
type: object
+ unevaluatedProperties: false
properties:
type:
description: A URI reference that identifies the error type.
@@ -809,6 +812,7 @@ $defs:
required: [ type, status, instance ]
endpoint:
type: object
+ unevaluatedProperties: false
properties:
uri:
description: The endpoint's URI.
@@ -821,8 +825,43 @@ $defs:
$ref: '#/$defs/referenceableAuthenticationPolicy'
description: The authentication policy to use.
required: [ uri ]
+ eventProperties:
+ type: object
+ properties:
+ id:
+ type: string
+ description: The event's unique identifier
+ source:
+ description: Identifies the context in which an event happened
+ oneOf:
+ - title: LiteralSource
+ type: string
+ format: uri-template
+ - $ref: '#/$defs/runtimeExpression'
+ type:
+ type: string
+ description: This attribute contains a value describing the type of event related to the originating occurrence.
+ time:
+ oneOf:
+ - title: LiteralTime
+ type: string
+ format: date-time
+ - $ref: '#/$defs/runtimeExpression'
+ subject:
+ type: string
+ datacontenttype:
+ type: string
+ description: Content type of data value. This attribute enables data to carry any type of content, whereby format and encoding might differ from that of the chosen event format.
+ dataschema:
+ oneOf:
+ - title: LiteralDataSchema
+ type: string
+ format: uri-template
+ - $ref: '#/$defs/runtimeExpression'
+ additionalProperties: true
eventConsumptionStrategy:
type: object
+ unevaluatedProperties: false
oneOf:
- title: AllEventConsumptionStrategy
properties:
@@ -848,31 +887,12 @@ $defs:
required: [ one ]
eventFilter:
type: object
+ unevaluatedProperties: false
properties:
with:
title: WithEvent
- type: object
+ $ref: '#/$defs/eventProperties'
minProperties: 1
- properties:
- id:
- type: string
- description: The event's unique identifier
- source:
- type: string
- description: Identifies the context in which an event happened
- type:
- type: string
- description: This attribute contains a value describing the type of event related to the originating occurrence.
- time:
- type: string
- subject:
- type: string
- datacontenttype:
- type: string
- description: Content type of data value. This attribute enables data to carry any type of content, whereby format and encoding might differ from that of the chosen event format.
- dataschema:
- type: string
- additionalProperties: true
description: An event filter is a mechanism used to selectively process or handle events based on predefined criteria, such as event type, source, or specific attributes.
correlate:
type: object
@@ -891,6 +911,7 @@ $defs:
description: An event filter is a mechanism used to selectively process or handle events based on predefined criteria, such as event type, source, or specific attributes.
extension:
type: object
+ unevaluatedProperties: false
properties:
extend:
type: string
@@ -910,13 +931,14 @@ $defs:
externalResource:
oneOf:
- type: string
- format: uri
+ format: uri-template
- title: ExternalResourceURI
type: object
+ unevaluatedProperties: false
properties:
uri:
type: string
- format: uri
+ format: uri-template
description: The endpoint's URI.
authentication:
$ref: '#/$defs/referenceableAuthenticationPolicy'
@@ -927,6 +949,7 @@ $defs:
required: [ uri ]
input:
type: object
+ unevaluatedProperties: false
properties:
schema:
$ref: '#/$defs/schema'
@@ -939,6 +962,7 @@ $defs:
description: Configures the input of a workflow or task.
output:
type: object
+ unevaluatedProperties: false
properties:
schema:
$ref: '#/$defs/schema'
@@ -951,6 +975,7 @@ $defs:
description: Configures the output of a workflow or task.
export:
type: object
+ unevaluatedProperties: false
properties:
schema:
$ref: '#/$defs/schema'
@@ -963,6 +988,7 @@ $defs:
description: Set the content of the context.
retryPolicy:
type: object
+ unevaluatedProperties: false
properties:
when:
type: string
@@ -975,6 +1001,7 @@ $defs:
description: The duration to wait between retry attempts.
backoff:
type: object
+ unevaluatedProperties: false
oneOf:
- title: ConstantBackoff
properties:
@@ -997,9 +1024,11 @@ $defs:
description: The retry duration backoff.
limit:
type: object
+ unevaluatedProperties: false
properties:
attempt:
type: object
+ unevaluatedProperties: false
properties:
count:
type: integer
@@ -1013,6 +1042,7 @@ $defs:
description: The retry limit, if any
jitter:
type: object
+ unevaluatedProperties: false
properties:
from:
$ref: '#/$defs/duration'
@@ -1025,6 +1055,7 @@ $defs:
description: Defines a retry policy.
schema:
type: object
+ unevaluatedProperties: false
properties:
format:
type: string
@@ -1045,6 +1076,7 @@ $defs:
description: Represents the definition of a schema.
timeout:
type: object
+ unevaluatedProperties: false
properties:
after:
$ref: '#/$defs/duration'