What AutoFlow is
AutoFlow is Automation plus Workflow. Users encode workflows of interactions between DevSecOps objects and external systems as small Starlark programs, called workflow definitions. AutoFlow runs each definition on autocore, its event-sourced workflow engine. One durable run of a definition is a workflow: it survives restarts, instance failures and network outages, and it can wait for as long as the process it automates needs.
What you get
Durable
Every action call, timer and channel value is recorded in the workflow’s history, and after a restart the workflow replays that history and resumes where it stopped. A sleeping workflow holds no CPU or memory, so a two-week wait costs nothing beyond its rows in the database.
Sandboxed Starlark
A workflow has no I/O, no wall clock and no randomness: time.now() reads workflow time from the history, and the only way to reach the outside world is an action provided by a module. Tokens and passwords travel as sensitive values that a workflow can pass along but never read, print or compare.
Governed
A workflow asks the policy module for a verdict before it acts and enforces it: proceed, stop, or hand the decision to a person and wait for the answer, for days if it has to.
Extensible
Modules add actions over gRPC and protobuf, so they can be written in any language; a Go SDK is provided. Built in today: gitlab, policy, event and gitlab-function.
A workflow definition
load("module:gitlab", "call_api")
def main(w, project_id, issue_iid, token):
sleep(14 * 24 * time.hour)
headers = {
"Authorization": "Bearer " + token,
"Content-Type": "application/json",
}
status, _, _, err = gather(call_api(
"POST",
"/api/v4/projects/%d/issues/%d/notes" % (project_id, issue_iid),
headers = headers,
body = json.encode({"body": "Still relevant?"}),
))
if err != None or status != 201:
fail("could not comment on the issue")main is the entry point. Whoever starts the workflow supplies project_id, issue_iid and token, the token as a sensitive value that "Bearer " + token keeps sensitive. sleep is a durable timer: the workflow is suspended and picked up two weeks later by whichever AutoFlow instance owns it then. call_api is an action: it runs outside the interpreter, its result is recorded, and on replay the recorded result is returned instead of a new HTTP request. A non-2xx status is data, not an error, and a transport failure arrives as err. Starlark has no exception handling, so fail ends the workflow as failed.
What it is not
AutoFlow is a primitive: it runs a program durably and lets it act through modules. The systems below are things that can be built on it, not things it is.
- Not CI, but a CI-like system could be built on it. A workflow runs no containers, no binaries and no heavy compute; GitLab CI/CD does that. A system that starts pipelines, waits for their results and decides what happens next, across projects and over days, is what a workflow definition expresses.
- Not an interactive agent, but agentic orchestration can be built on it. A workflow runs unattended and holds no conversation. Long-running coordination of agent steps and human approvals, durable across days and restarts, is a workflow definition whose actions run the steps and whose channels carry the approvals.
- Not only a scheduler. A workflow can sleep and wake on a durable timer, but the timer is one statement in a program that also calls APIs, waits for people and branches on results. A workflow starts when a caller submits its definition.
Where it runs
AutoFlow keeps workflow state in PostgreSQL and coordinates its instances through Redis. Today a workflow starts only through the AutoFlow gRPC API, called by GitLab features and by the autoflow command line tool. See Status and roadmap for what is in design.