elsa-workflows / elsa-workflows/elsa-core
XS / Hyperbee.XS-based expression provider as an alternative to Roslyn C# expressions
- Dominant language
- C#
- Stars
- 7.9k
- Forks
- 1.5k
- Avg merge
- 15h 22m
- Merged PRs (30d)
- 114
Description
**Summary**
Add a new expression provider that uses [Hyperbee.XS](https://github.com/Stillpoint-Software/hyperbee.xs) as its backing engine, offering a C#‑like syntax implemented on top of expression trees instead of Roslyn scripting.
**Motivation**
* The existing C# expression feature uses Roslyn as the expression evaluator. Roslyn is a full C# compiler and does not attempt to provide a sandbox for untrusted code; the recommended approach is to run untrusted scripts in a separate, restricted process or container rather than in the main application process.
* In multi‑tenant, cloud‑hosted scenarios where Elsa Server is exposed to arbitrary tenant-authored expressions, it’s hard to safely expose the Roslyn-based C# expressions directly without additional isolation.
* Hyperbee.XS is a lightweight, C#‑like scripting language that generates expression trees and is designed for embedded scripting, rule engines, and DSLs, without pulling in the full Roslyn compiler pipeline. This seems like a good fit for workflow expressions and may be easier to constrain to a limited, auditable surface.
**Proposal**
* Introduce a new module, e.g. `Elsa.Expressions.Xs` (or similar), that registers an *XS* expression provider.
* The provider would:
* Parse expressions using Hyperbee.XS and compile them to delegates.
* Expose the same globals that the current C# provider does (`WorkflowInstanceId`, `CorrelationId`, `Variable`, `Output`, `Input`, etc.).
* Integrate with Elsa’s existing expression infrastructure so XS can be selected as an expression type from Studio and JSON definitions.
* Add a configuration hook similar to `UseCSharp(...)`, e.g.:
```csharp
services.AddElsa(elsa =>
{
elsa.UseXs(options =>
{
// Configure allowed types/namespaces, register helper functions, etc.
});
});
```
so hosts can:
* Control which assemblies/types are visible to XS.
* Register reusable helper functions/DSL constructs exposed to expressions.
* Potentially restrict XS usage further in multi-tenant scenarios.
**Naming**
Some options for the expression syntax / UI label:
* `XS`
* `XS Script`
* `Hyperbee XS`
To avoid confusion with the existing Roslyn-based `C#` expressions, I’d suggest:
* **Expression type key:** `XS`
* **Display name:** `XS Script`
**Notes**
* This is intended as an additional option, not a replacement for the current Roslyn-based C# expressions.
* Security-wise, XS would still need to be treated as untrusted code in multi-tenant environments (and combined with process/container isolation where strong tenant isolation is required), but its expression-tree focus and smaller surface area could make it easier to lock down than full C# via Roslyn.
- https://github.com/dotnet/roslyn/issues/10830?utm_source=chatgpt.com "Securely Sandboxing Roslyn Code Execution · Issue #10830"
- https://feed.nuget.org/packages/Hyperbee.XS?utm_source=chatgpt.com "Hyperbee.XS 1.3.3"
- https://docs.elsaworkflows.io/expressions/c "C# | Elsa 3"
- https://github.com/Stillpoint-Software/hyperbee.xs "GitHub - Stillpoint-Software/hyperbee.xs: A Lightweight, Extensible Scripting Language for Expression Trees"
Contributor guide
Assessment
This issue has not been assessed yet.