Home
Softono
No data found
Vyshyvanka

Vyshyvanka

Open source C#
21
Stars
1
Forks
0
Issues
0
Watchers
1 week
Last Commit

About Vyshyvanka

Visual workflow automation platform built on .NET 10 with a Blazor WebAssembly designer, REST API, plugin system, and support for Keycloak/Authentik/LDAP auth and Vault/OpenBao credential storage.

Platforms

Web Self-hosted Windows

Languages

C#

Links

Vyshyvanka

A workflow automation platform built on .NET 10. Users create automated workflows through a visual node-based designer, connect nodes to define data flow, and execute workflows triggered by webhooks, schedules, or manual actions.

[!WARNING] This project is under heavy development and is not suitable for production use. APIs, data formats, and features may change without notice.

Why "Vyshyvanka"?

Vyshyvanka (Вишиванка) is a traditional Ukrainian embroidered shirt. Each pattern is crafted by weaving threads through fabric — every stitch deliberate, every connection meaningful. The same idea drives this project: workflows are patterns woven from nodes and connections, each one carrying data from one point to the next. The name reflects both the craft of building something intricate from simple elements and the Ukrainian roots of the team behind it.

Screenshots

Light Theme

Designer Home
Designer Light Home Light

Dark Theme (Vyshyvanka Red)

Designer Settings
Designer Dark Settings Dark

Architecture

graph TD
    Designer["Designer\n(Blazor WASM)"] -->|HTTP| API["API\n(ASP.NET Core)"]
    API --> Engine["Engine\n(Execution, Persistence, Plugins)"]
    Engine --> Core["Core\n(Domain Models, Interfaces)"]

Dependencies flow downward only. The Designer communicates with the API exclusively over HTTP.

Tech Stack

Component Technology
Runtime .NET 10 / C# 14
API ASP.NET Core
UI Blazor WebAssembly
Database SQLite (dev) / PostgreSQL (prod)
ORM Entity Framework Core (code-first)
Orchestration .NET Aspire
Auth Built-in JWT, Keycloak, Authentik, or LDAP
Credential Storage Built-in AES-256, HashiCorp Vault, or OpenBao
Serialization System.Text.Json
Testing xUnit, CsCheck, NSubstitute, bUnit

Prerequisites

Getting Started

Clone the repo and restore dependencies:

git clone <repository-url>
cd Vyshyvanka
dotnet restore Vyshyvanka.slnx

Run with Aspire (recommended)

Starts both the API and Designer with service discovery:

dotnet run --project src/Vyshyvanka.AppHost

This uses SQLite by default. To use PostgreSQL instead (requires Docker):

USE_POSTGRES=true dotnet run --project src/Vyshyvanka.AppHost

Run individual projects

# API only
dotnet run --project src/Vyshyvanka.Api

# Designer only
dotnet run --project src/Vyshyvanka.Designer

Build & Test

dotnet build
dotnet test

Project Structure

Project Location Description
Vyshyvanka.Core src/ Domain models, interfaces, enums, exceptions. No external dependencies.
Vyshyvanka.Engine src/ Workflow execution engine, EF Core persistence, plugin system, node registry.
Vyshyvanka.Api src/ REST API controllers, middleware, authentication, DTOs.
Vyshyvanka.Designer src/ Blazor WebAssembly visual workflow editor.
Vyshyvanka.AppHost src/ .NET Aspire host for orchestrating services.
Vyshyvanka.ServiceDefaults src/ Shared Aspire service configuration (OpenTelemetry, resilience).
Vyshyvanka.Plugin.AdvancedHttp plugins/ HTTP retry, polling, batch, and GraphQL nodes.
Vyshyvanka.Plugin.GitLab plugins/ GitLab issues, merge requests, pipelines, files, tags, releases.
Vyshyvanka.Plugin.Jira plugins/ Jira issues, comments, users, and JQL search.
Vyshyvanka.Plugin.Tmplt plugins/ Starter template for building new plugins.
Vyshyvanka.Tests tests/ Unit, integration, property-based, and E2E tests.

Key Concepts

Workflows

A workflow is a directed graph of nodes connected through typed ports. Every workflow must have exactly one trigger node as its entry point.

Nodes

Nodes are the building blocks of workflows. Three categories:

Category Base Class Description
Trigger BaseTriggerNode Entry point — webhooks, schedules, manual triggers
Action BaseActionNode Operations — HTTP requests, database queries, email, custom code
Logic BaseLogicNode Flow control — conditionals, switches, loops, merges

Executions

When a trigger fires, an execution is created and moves through: PendingRunningCompleted / Failed / Cancelled. Node outputs are stored during execution for use in expressions.

Expressions

Reference data from previous nodes using double-brace syntax. Nodes are referenced by their ID (GUID):

{{ nodes.<nodeId>.propertyName }}
{{ nodes.<nodeId>.response.body.users[0].email }}
{{ variables.executionId }}
{{ variables.workflowId }}

The Designer's autocomplete shows node names but inserts their IDs automatically.

Plugins

Extend Vyshyvanka by creating plugin projects that reference Vyshyvanka.Core and implement custom nodes.

Plugin Description
AdvancedHttp HTTP retry, polling, batch requests, and GraphQL
GitLab GitLab issues, merge requests, pipelines, files, tags, releases, and webhook triggers
Jira Jira issues, comments, users, and JQL search
Template Starter template for building your own plugins

Authentication

Vyshyvanka supports four authentication providers, configured via Authentication:Provider in appsettings.json:

Provider Value Description
Built-in BuiltIn Local email/password with self-issued JWT tokens (default)
Keycloak Keycloak OpenID Connect via Keycloak
Authentik Authentik OpenID Connect via Authentik
LDAP Ldap LDAP directory with locally-issued JWT tokens

API key authentication (X-API-Key header) is always available for webhooks and external integrations, regardless of the active provider.

Built-in (default)

Works out of the box. Users register and log in with email/password. Development seeds three users automatically ([email protected], [email protected], [email protected]).

Keycloak / Authentik

Configure the OIDC authority and role mappings. The API validates tokens issued by the external provider and auto-provisions local users on first login.

{
  "Authentication": {
    "Provider": "Keycloak",
    "Authority": "https://keycloak.example.com/realms/vyshyvanka",
    "ClientId": "vyshyvanka-api",
    "Audience": "vyshyvanka-api",
    "RoleClaimType": "realm_access",
    "RoleMappings": {
      "vyshyvanka-admin": "Admin",
      "vyshyvanka-editor": "Editor"
    }
  }
}

See appsettings.Keycloak.json and appsettings.Authentik.json for full examples.

LDAP

Credentials are verified against the LDAP directory. Sessions use locally-issued JWT tokens. Users are provisioned on first login with roles mapped from LDAP group memberships.

{
  "Authentication": {
    "Provider": "Ldap",
    "Ldap": {
      "Host": "ldap.example.com",
      "Port": 389,
      "UseStartTls": true,
      "BindDn": "cn=readonly,dc=example,dc=com",
      "BindPassword": "...",
      "SearchBase": "ou=users,dc=example,dc=com",
      "UserSearchFilter": "(mail={0})",
      "RoleMappings": {
        "Vyshyvanka-Admins": "Admin",
        "Vyshyvanka-Editors": "Editor"
      }
    }
  }
}

See appsettings.Ldap.json for the full example.

Auth Discovery

The GET /api/auth/config endpoint (anonymous) returns the active provider and OIDC settings so the Designer can configure its auth flow at runtime.

Credential Storage

Vyshyvanka supports three credential storage backends, configured via CredentialStorage:Provider in appsettings.json:

Provider Value Description
Built-in BuiltIn AES-256 encrypted in the local database (default)
HashiCorp Vault HashiCorpVault KV v2 secrets engine
OpenBao OpenBao KV v2 secrets engine (Vault-compatible)

Built-in (default)

Credential values are encrypted with AES-256 and stored alongside metadata in the database. Configure the encryption key via Vyshyvanka:EncryptionKey.

HashiCorp Vault / OpenBao

Metadata (name, type, owner) stays in the local database. Secret values are stored in Vault/OpenBao via the KV v2 API.

{
  "CredentialStorage": {
    "Provider": "HashiCorpVault",
    "Url": "https://vault.example.com:8200",
    "MountPath": "secret",
    "PathPrefix": "vyshyvanka/credentials"
  }
}

The Vault token can be set via CredentialStorage:Token or the VAULT_TOKEN environment variable.

See appsettings.Vault.json and appsettings.OpenBao.json for full examples.

Documentation

Detailed design docs and architectural decisions live in the docs/ folder.

License

MIT