Flowable external workers in Node.js and TypeScript: what the integration does
Many teams keep their service logic in Node.js or TypeScript while their BPMN models run on the Flowable Java engine. For that split, the supported method is the @flowable-oss/external-worker-client npm library, which acquires, locks and completes external jobs over the Flowable REST API. The worker never holds process state of its own. It asks the engine for work on a topic, receives a locked job with its variables, runs the code, and reports the result back as a completion or a failure. Confirm with your team which Node.js runtime versions and TypeScript settings your organization supports before you choose this path, since the library's published requirements are in its repository.
The Flowable engine stays the system of record. The database holds the process instance, the variables, the job lock owner and the lock expiration time, and history is written there as well. The worker only pulls, executes and reports back. This matters for audit and recovery: if a Node.js process crashes while holding a job, the lock eventually expires and the engine makes the job available again, so another worker can pick it up. Your design has to tolerate the same step running more than once, so side effects in the external service need idempotency keys or equivalent checks. Ask your platform team how lock expiration is configured for your deployment before you set expectations for recovery time.
Two decisions shape the integration early. The first is authentication: the client supports basic authentication with a username and password, or a token. Basic credentials are simpler to start with but place a long-lived secret in every worker, so you should decide where those values are stored and rotated. The second is where the worker runs relative to the Flowable REST application, since network paths, TLS and the REST endpoint's reachability all determine whether workers can run in a separate cluster or must sit beside the engine. Document both choices with your security and operations owners before writing the first topic handler.
What a Node.js external worker needs before the build starts
A Node.js external worker depends on four things being in place before any code is written: a Flowable engine or REST application to call, a Node.js runtime with access to the published client, a service account allowed to work with jobs, and a network path between the worker and the REST endpoint. Each item below is a decision your team should confirm in its own environment.
A running Flowable engine or REST application
The worker does not run process logic itself. It polls and completes external jobs held by a Flowable engine, so you need an engine that exposes the REST API and has the external worker job tasks in your process models. Confirm which Flowable release your organization runs, since the client's compatibility must match it. Check the release notes for the major version you use, because Flowable 8.0.0 changed the Spring Boot and JSON baseline and the engine side of the stack must match your planned upgrade path.
Node.js runtime and the published package
Install the client from npm as @flowable-oss/external-worker-client. Confirm the supported Node.js version and the matching client version against the client repository before you pick a runtime image, since this page does not specify a version. Your build pipeline should pin both the Node.js version and the package version in a lockfile so that workers deployed later behave the same way as the ones you tested.
A dedicated service account with job rights
Create a service account for the worker rather than reusing a personal or administrator login. It needs permission to acquire external jobs for the topics it handles and to complete or fail them. Decide who owns the credential, how it is rotated, and where it is stored. The client supports basic authentication or a token, so the choice you make here determines how the secret reaches the worker process.
Network path from worker to REST endpoint
The worker must reach the Flowable REST endpoint over HTTP or HTTPS, and the engine must accept connections from the worker's network segment. List the hosts, ports and any proxies or load balancers between them. If workers run in a different cluster or cloud account from the engine, confirm firewall rules, DNS names and TLS certificates early, because a blocked path shows up as jobs that are never acquired.
Process models that use external worker tasks
The worker only receives jobs for topics that a process model defines. Agree the topic names, the variables each task reads and writes, and the expected retry behavior with the team that owns the BPMN models. Mismatched topic names are a common reason a worker runs without ever receiving work, so record the list in the design document before development starts.
A test environment with matching versions
Set up a non-production Flowable instance that runs the same release as production and a worker built from the pinned client version. Use it to confirm job acquisition, locking and completion before you connect real workers. Ask your vendor or internal platform team to confirm whether the test instance can be seeded with the same process definitions, so that tests reflect production behavior.
How to configure a TypeScript external worker step by step
This sequence takes a Node.js or TypeScript service from an empty project to a worker that acquires, locks, completes and fails Flowable external jobs over REST. Each step closes with a check against a test process instance in the engine. Confirm exact option names and endpoints in the flowable-external-client-js repository before you start.
Install the client package from npm
In your Node.js or TypeScript service, run
npm install @flowable-oss/external-worker-clientand confirm the package appears inpackage.json. The library is published on npm and handles acquiring, locking and completing external jobs over the Flowable REST API. Check the package README for the TypeScript types it provides, then build the project to confirm the import resolves. The step is done when the project compiles with the client imported and no errors.Confirm the Flowable REST endpoint is reachable
The client calls the engine over REST, so the Flowable REST application or your Spring Boot REST setup must be running and reachable from the worker host. Ask the platform team for the base URL in each environment, and confirm network routes, proxies and TLS settings from the worker's network. Send one authenticated request with curl to a read-only endpoint from the worker host. The step is done when the engine returns a successful response.
Set the base URL and credentials
Configure the REST base URL and choose basic authentication (username and password) or a token, since the client supports both. Load these values from environment variables or a secrets manager at startup, and keep them out of source control. Use a dedicated engine user that holds only the rights the worker needs, and check the client README for the exact option names. The step is done when a request with a wrong credential is rejected and the correct one is accepted.
Register a handler for each topic
Map each external worker topic in your BPMN models to a handler function in the worker. The topic string must match the model exactly, including letter case, so confirm it against the deployed process definition. Keep each handler small: it reads the job's input variables, performs the work and returns the output values for completion. The step is done when a test process with one external worker task on a known topic is deployed and the worker log shows the handler registered for that topic.
Start the acquire and lock loop
Start the client's polling loop so it acquires available jobs for the registered topics and locks them under a lock owner. The engine stores the lock owner and lock expiry in the database, so if a worker stops, the lock expires and another worker can pick up the job. Set the lock time the client requests to be longer than your slowest handler, and confirm the setting in the client documentation. The step is done when a test instance creates a job and the engine shows it locked by your worker.
Complete jobs with output variables
When a handler finishes, the client signals completion over REST and sends any output variables back to the process. The engine then moves the execution past the external worker task. Make your handler idempotent, so a retry after a timeout does not repeat side effects in downstream systems. The step is done when the test instance moves past the task and the job no longer appears as locked or pending in the engine.
Fail jobs that cannot complete
When a handler hits an error it cannot recover from, report a failure for the job over REST so it does not stay locked until expiry. Include a clear error message so operators can see the cause in the engine. Agree with your operations team how failed jobs are retried and who reviews them, using the failed job handling available in the engine. The step is done when a test handler that throws produces a failed job that operators can see.
Verify end to end and stop the worker cleanly
Run the full sequence with a test instance: start the process, watch the worker acquire and complete the job, then confirm the process reaches the next activity. Stop the worker and confirm it leaves no jobs locked, or that any remaining locks expire and a second worker picks the job up. Record the topic, lock owner and test results in your runbook. The step is done when the test passes twice in a row and shutdown leaves no orphaned locks.
How job acquisition, locking and completion work in the client
An external worker job starts when a BPMN service task configured as an external worker reaches its turn in the engine. The engine creates a job on the task's topic and leaves it waiting for a worker. The @flowable-oss/external-worker-client library then acquires that job over the REST API, and the engine records a lock owner and a lock expiration time against it. While the handler runs, the job is locked to that worker. The handler finishes by completing the job with output variables, or by reporting a failure. Before you build on this, confirm in the client repository which lock duration the client requests by default, whether it renews locks during long handlers, and how it exposes the complete and fail calls.
Locks are what keep two workers from running the same job at the same time, and they are also what recovers work when a worker disappears. The Flowable advanced documentation describes the async executor coordinating nodes through lock owners and lock expiration times stored in the database. External job locks sit in the same shared store, so an expired lock lets another worker acquire the job. The practical consequence is that the lock duration must comfortably exceed the longest normal run of your handler. A handler that outlives its lock can finish after another worker has taken the job, which produces duplicate side effects. Plan for this by making handlers idempotent, by keeping individual handlers short, and by testing a slow dependency on purpose to see what the engine does.
Retry and failure behavior depends on how the handler reports an error, not only on whether the handler threw an exception. A transient problem, such as a timeout to a downstream API, should be reported as a failure that the engine can retry, with the retry count and any backoff set on the job or the process definition. A business outcome, such as a rejected application, is better modeled as a value in process variables or as a BPMN error caught by a boundary event, so the model shows the path. Decide these categories with the process owner before development starts, and document them next to the topic names. Then test each category against a running engine, and check the failed job list afterward, because the engine keeps retry state in the database where your operations team will look.
Basic auth or a token: which should the worker use
On a developer workstation the priority is speed and isolation. A dedicated local engine with throwaway credentials lets each developer experiment without touching shared data. Basic authentication with a username and password is the simplest option to configure in the client, and it keeps the first run of a worker easy to reproduce. The main risk is that local habits carry into shared environments, so the local setup should be kept deliberately separate from anything else.
- Use a local-only account: Create an engine user that exists only on the developer's engine and is never copied into shared configuration.
- Keep secrets out of source control: Read the username and password from environment variables or a local, git-ignored file rather than hard-coding them in TypeScript.
- Reset data freely: Local engines can be recreated, so a leaked development password has limited impact.
- Match the auth method to later stages: If the team plans to use tokens in production, test the token path at least once before the shared environment is built.
- Avoid production hostnames: Point the worker at a local REST endpoint so that a misconfigured run cannot acquire jobs from a real process instance.
Before leaving this tab, confirm that no development credential appears in a committed file or a shared chat history.
A shared test environment has several people and pipelines using the same engine, so credentials become shared assets. Basic authentication is still workable here, but each worker should have its own account so that job acquisition can be traced to a specific service. Using one account for every worker makes it hard to tell which worker locked or completed a job when something goes wrong.
- One account per worker: Give each worker deployment its own engine user so logs and audit records identify the caller.
- Store credentials in the pipeline's secret store: Inject them at runtime from the CI/CD or orchestration secret mechanism, not from files baked into images.
- Rotate on a schedule agreed with the test owners: Ask the test team how often shared passwords change and who is notified when they do.
- Restrict the account's permissions: Limit the account to the topics the worker handles, using the engine's authorization model.
- Plan for test data cleanup: Stale locked jobs from a stopped worker should be understood before a new worker reuses the same topic.
Before relying on this environment, confirm which account each worker uses and who can read the secret store that holds it.
In production, the credential choice is a security control. The worker holds the ability to acquire and complete work that moves real business processes forward, so its identity needs a clear owner, a rotation procedure and an audit trail. The client supports token authentication alongside basic authentication, and the token path is the one to plan for production unless the security team has a reason to prefer basic credentials. Token issuance, lifetime and refresh behavior depend on the identity system in use, so confirm those details with the team that operates it rather than assuming them.
- Assign a named service owner: One team should own each worker identity, approve changes and answer for its permissions.
- Prefer tokens where the identity system supports them: Confirm how tokens are obtained, refreshed and revoked in your environment before the worker is deployed.
- Use a secret manager for any remaining passwords: Keep basic credentials in a vault with access logging and automated rotation where possible.
- Limit scope to the worker's topics: Grant only the permissions needed to acquire and complete jobs for its topics.
- Test revocation: Confirm that disabling the account or token stops the worker without corrupting in-flight jobs.
Before go-live, confirm the owner, the rotation procedure and the revocation test have been signed off by the security and operations teams.
Whatever method is chosen, the credential needs a defined lifecycle: who creates it, where it is stored, how it is rotated and how it is removed when a worker is retired. Basic authentication places a long-lived password in the worker's configuration, so its storage and rotation matter most. Tokens move part of that burden to the issuer, but they still need storage, renewal and revocation procedures. The organization should decide these responsibilities before the first worker is deployed, not after an incident.
- Record the owner: Keep a register of worker identities that names the owning team and the business process served.
- Define rotation steps: Document how a new password or token is issued, deployed to workers and the old one retired, including the order of steps.
- Plan for retirement: Disable the account when a worker or topic is decommissioned so orphaned credentials do not remain active.
- Separate duties: The person who requests a credential should not be the only person who approves it.
- Log access: Confirm that secret reads and identity changes are recorded in a system the security team reviews.
Before approving a design, ask who performs rotation, how long a rotation takes in your pipeline and what happens if a worker cannot pick up the new credential.
Many organizations later connect Flowable to a central identity provider so that users and services are managed in one place. The external worker client's authentication setting is a configuration concern, so the worker code may need little change, but the identities behind the credentials will move. Designing for that move early avoids a rebuild of service accounts, topic permissions and rotation runbooks. The Flowable identity model also has its own user and group handling, so the team should confirm how engine users map to central identities before cutover.
- Name accounts by service, not by person: Service identities are easier to map to a central directory than individual developer accounts.
- Keep the worker configuration generic: Read the authentication method and credentials from configuration so the switch does not require a code change.
- Plan the mapping of permissions: Decide how central roles or groups correspond to the engine's privileges and topic access.
- Schedule a parallel run: Test the worker against the new identity source in a non-production environment before retiring the old credentials.
- Confirm the integration path: Ask the engine team how REST authentication will be configured with the central provider, since that work sits outside the Node.js client.
Before planning the move, confirm which identity provider will be used and whether the team has documented how its tokens are issued to services.
How topics, variables and job fields map to handler code
This table maps each Flowable external job element to the code that receives it, along with who must agree on the value before coding starts. Read it as a checklist for the modeling and engineering handoff, since a mismatch in topic names, variable types or result keys fails at runtime rather than at deployment.
| Element | What the handler code sees | Agree with BPMN modelers first |
|---|---|---|
| External job topic | String used to select the handler function, such as a registry key per topic | Exact topic names, casing and whether one topic serves several service tasks |
| Process variables in | Typed TypeScript input object built from the job variables, with explicit parsing of dates and numbers | Variable names, types and which are required versus optional on each task |
| Handler result | Object returned by the handler, mapped to variables on the completion request | Output variable names, types and whether results overwrite or append to process state |
| Job identifier | Passed into logs and included in retry or failure messages so one job traces to one process instance | Which correlation fields (process instance, business key) the logs must carry |
| Retries and failure | Handler errors mapped to a failure call with a message and retry count | Which errors are retryable, retry counts and whether a failed job should route to a boundary event |
| Timeouts and lock expiry | Work must finish within the lock period or another node can reacquire the job | Expected duration per topic so lock settings and worker concurrency can be sized |
| Authentication settings | Credentials or token loaded from environment configuration, never from the model | Which service account the workers use and who owns its rotation |
| Unknown or extra variables | Handler should ignore or reject fields it does not declare, depending on the contract | Whether modelers may add variables without a coordinated code change |
Securing credentials, transport and worker permissions
A Node.js or TypeScript external worker holds credentials to the Flowable REST API and acts on process work, so its security depends on how those credentials are stored, how traffic reaches the engine, and what the account is allowed to do. The cards below cover each of these layers, plus input handling inside the worker itself. Review them together with the Flowable security guidance for the engine and its REST API before the worker reaches a shared environment.
Keep credentials out of code and images
Basic authentication uses a username and password, and the client also accepts a token, so either secret can end up in a repository or a container layer if it is hardcoded. Load both from environment variables or a secrets manager at runtime, and keep them out of .env files committed to source control. Check that container images, build logs and error output never print the configuration object. Rotate the credential on a set schedule and after any staff change that touched the pipeline.
Use HTTPS to the REST endpoint
The worker sends credentials and process variables to the Flowable REST API on every acquire and complete call. Over plain HTTP, basic credentials are readable by anyone on the network path, and variables may contain personal or financial data. Point the client at an HTTPS URL, terminate TLS at a gateway or the engine, and make the worker reject certificates it cannot verify rather than disabling verification to get past a test error. Confirm the certificate chain includes any internal certificate authority your environment uses.
Scope the service account to its topics
A worker that handles one topic should not hold rights to start processes, change definitions or read unrelated instances. Create a dedicated Flowable user for each worker group and grant only the privileges its topics need, through your identity setup and the authorization checks your application enforces. Ask whether the account can be limited to specific topics and whether acquiring jobs for one topic can reach jobs for another. Review these grants when a topic is added or retired.
Validate variables before business logic
Variables that a process passes to a worker arrive as data that may have been set by a user, an upstream service or a model in an earlier step. Before the worker calls a payment, email or record update, check types, required fields, ranges and allowed values in code, and reject anything malformed by failing the job with a clear message. Do not pass variable values into shell commands, dynamic queries or eval-style code. Log the rejection without echoing sensitive field contents.
Limit what a compromised worker can do
Assume a worker process could be taken over through a dependency flaw or a leaked secret, and design so the damage stays small. Run the worker under a non-root user with a read-only filesystem where possible, restrict its outbound network to the engine and the services it needs, and give it only the downstream credentials that its topic requires. Keep npm dependencies pinned and scanned, since the worker's supply chain is part of its attack surface. Test what the account can reach by trying operations it should not have.
How to scale Node.js workers without duplicate work
The key rule for scaling is that several Node.js worker instances can poll the same topic safely because the Flowable engine, not the worker, decides who owns a job. When a worker acquires external jobs, the engine records a lock owner and a lock expiration time in the database. A second worker asking for the same topic receives only jobs that are unlocked or whose lock has expired, so two instances should not complete the same job under normal operation. Your job is to make sure the lock lasts long enough for your slowest handler, and that a crashed worker's lock expires quickly enough for another instance to pick the job up.
The lock duration is the setting that most often causes trouble. If a handler takes longer than the lock lasts, the job becomes eligible for another worker while the first handler is still running, and both may perform the side effect before one of them signals completion. Set the lock duration from measured handler times at peak load, with headroom for retries against downstream systems, rather than from average times. Polling frequency and the number of jobs requested per acquisition control how quickly work is picked up and how much load the REST API receives. Confirm the exact acquisition parameters, lock time and retry options in the client's README in the flowable-external-client-js repository before you fix any values.
Node.js runs handlers concurrently on one event loop, so a single process can hold several locked jobs at once. Concurrency inside one process multiplies the work each lock covers: if a process acquires ten jobs and processes them in parallel, all ten locks start their clock at acquisition, and a slow downstream call can push several of them past expiry together. Limit how many jobs a process acquires relative to how many it can finish within the lock window, and treat idempotency as a requirement for every handler that calls an external system, because the engine guarantees single ownership of the job, not exactly-once effects in systems outside Flowable. Load testing against a realistic queue depth, with injected slow responses, is the only reliable way to choose these settings for your environment.
Why external jobs stall, fail or complete twice
This table lists the failures teams most often hit when a Node.js or TypeScript worker polls Flowable external jobs, with the likely cause and the check to run first. Read each row against the symptom you see, then run the check before changing worker code. The main takeaway is that most stalls come from topic names, credentials, network paths and lock timing rather than from the handler logic itself.
| Symptom | Likely cause | Check to run |
|---|---|---|
| Authentication rejected | Wrong username or password for basic auth, an expired or invalid token, or the client sending credentials to a different base URL than the REST application | Call the REST API with the same credentials from a shell, confirm the base URL and context path, and compare the auth mode configured in the client with the one the server expects |
| Jobs never acquired | The topic in the worker does not match the topic set on the service task in the BPMN model, or the job is not yet due or is suspended | Compare the topic string character by character with the model, then query open external jobs for the process instance to confirm they exist and are not suspended |
| Locks expire during long handlers | The handler runs longer than the lock duration, so another worker or the async executor can reacquire the job | Measure handler duration under realistic input, confirm the lock time configured in the client, and split long work into shorter steps or extend the lock where the client supports it |
| Completion rejected with a stale lock owner | The lock expired or was taken by another worker, so the worker's lock owner no longer matches the job when it calls complete | Log the lock owner returned at acquisition and at completion, check whether the handler exceeded the lock time, and make completion idempotent so a retry does not change outcome |
| Unreachable REST endpoint behind a proxy | Ingress or reverse proxy strips or rewrites the path, enforces a short timeout, blocks the REST path, or terminates TLS in a way the Node.js runtime does not trust | Request the REST root from the worker host, compare the path through the proxy with the direct service address, check proxy timeouts and the CA bundle used by Node.js |
| Variable type mismatch | Process variables arrive as typed values (for example, numbers, dates or JSON) that the worker reads as strings, or the worker returns a value type the model does not expect | Inspect the variable types in the job's process instance, parse inputs explicitly in the handler, and write outputs with the types the downstream gateways and expressions evaluate |
| Job completed twice | A retry after a timeout re-sends completion for a job that already finished, or two worker replicas process the same job | Check worker logs for duplicate completion calls, confirm the lock logic for each replica, and make handlers safe to repeat before adding retries |
Questions buyers ask before building Node.js external workers
What drives the cost of building Flowable external workers in Node.js?
The cost follows the number of external topics, how many distinct services the workers call, and how much error handling and observability each one needs. A topic that makes a single well-documented REST call is far smaller than one that coordinates several systems with compensating logic. Ask any quote to itemize the topics, the target services, the authentication method for each, the test environment, and the handover. Engineering time is the main recurring cost once the workers are in production, because worker code, dependencies and the Node.js runtime all need upkeep.
How long does it take to get a first working Node.js external worker?
The timeline depends less on the client library than on the engine access, the process model and the target service. The @flowable-oss/external-worker-client package is published on npm and covers acquiring, locking and completing jobs over REST, so the worker code for one topic is usually the smaller part of the work. Confirm the duration in the written scope, and ask what has to be ready first: a reachable Flowable REST endpoint, a test deployment of the process definition, and a service account the worker can use.
What does the client team need to provide before the work starts?
Plan to provide network access from the worker runtime to the Flowable REST API, a non-production engine with a representative process definition, and a dedicated service account or token for each worker group. You also need the target system owners who can confirm API contracts, timeouts and error codes, and a decision on where worker logs and metrics go. Ask the partner to list these prerequisites in the written scope so that gaps are visible before development starts.
Can our platform team build Node.js external workers in-house?
Yes, a team that already runs Node.js services and operates Flowable can build simple external workers without a partner. The harder parts are the ones around the worker: safe locking behavior when several instances run, retry and failure semantics that the process model depends on, credential handling, and testing against the engine. Teams that want an outside check on those points often scope a fixed engagement for the first topics and then take over. Whichever path you choose, agree who owns the worker code after handover.
Which Basic authentication or token approach should we use for workers?
The client supports basic authentication with a username and password, and it also supports authentication with a token. Basic authentication is simpler to configure but puts a long-lived credential in the worker configuration, so it needs strict secret storage and rotation. Tokens suit workers that run in orchestrated environments if your identity provider issues them. Confirm with your security team which method your policy allows, how credentials reach the container, and how revocation works. Do not store either credential in source control.
How does the work change when we upgrade Flowable?
Worker code depends on the REST API that the engine exposes, so each Flowable major release needs a check of the endpoints and payloads your workers use. Flowable 8.0.0, released on February 27, 2026, moved to Spring Framework 7 and Spring Boot 4 and dropped support for Spring Boot 3, while Flowable 7.0.0 moved the platform to Java 17, Spring Boot 3 and Jakarta EE. Those changes affect the engine and the REST application more than a Node.js client, but your regression tests should cover external job flows after every upgrade. Ask the partner which versions the client has been tested against.
When is a Java delegate or HTTP task a better choice than an external worker?
Use a Java delegate when the logic is short, already lives in the Java codebase, and benefits from the engine's transaction handling. Use an HTTP task when the process only needs one REST call with simple mapping and error handling. External workers fit when the logic must run in a Node.js or TypeScript service, when it needs its own scaling and deployment cycle, or when a separate team owns it. Each option adds operational surface, so compare the cost of running an additional service against the cost of extending the Java codebase.
How DeployOpen scopes and delivers Flowable worker integrations
DeployOpen plans, implements, tests, documents and supports Flowable external worker integrations inside your own infrastructure. We start from a written scope that names the topics, the Flowable environment, the Node.js or TypeScript runtime and the systems each worker reaches, so the delivery stays aligned with how your team operates.
How we scope
- Inventory the external worker topics, the process and case models that raise them, and the owning team for each.
- Confirm the Flowable version, deployment target and whether jobs are acquired over the Java API or the REST API.
- Agree how workers authenticate, using basic authentication or tokens, and who issues and rotates those credentials.
- Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
How we build
- Build the Node.js or TypeScript worker with the @flowable-oss/external-worker-client library, including lock and completion handling for each topic.
- Define failure paths for jobs that cannot complete, covering retries and the failure signal sent back to the engine.
- Test workers against a non-production Flowable instance, including duplicate workers competing for the same topic and expired locks.
- Configure worker concurrency and deployment units so capacity can be added per topic as load grows.
How we hand over
- Document each topic, its input and output variables, authentication settings and the expected job lifecycle for your engineers.
- Provide runbooks for starting, stopping and scaling workers, along with the logs and metrics your operations team should watch.
- Walk your engineers through the codebase and the test suite so they can extend workers without DeployOpen involvement.
- Record configuration, versions and open decisions in the handover pack so later changes start from a known baseline.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers for worker code and the Flowable versions it depends on.
- Review the client library and Flowable release notes when versions change, and plan upgrades against your test suite.
- Confirm with your team which support channel, response expectations and change process apply before the retainer starts.
- Revisit authentication and scaling choices as your process volume and security requirements change over time.

