{"id":50734281,"url":"https://github.com/elsa-workflows/elsa-platform","last_synced_at":"2026-06-10T12:02:04.464Z","repository":{"id":358876939,"uuid":"1243475536","full_name":"elsa-workflows/elsa-platform","owner":"elsa-workflows","description":"Deployment platform for Elsa-based systems: manifests, artifacts, reconciliation, CLI, GitOps, and operator tooling.","archived":false,"fork":false,"pushed_at":"2026-06-03T20:18:13.000Z","size":2616,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T22:09:18.670Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.elsaplatform.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elsa-workflows.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-19T11:28:10.000Z","updated_at":"2026-06-03T20:18:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/elsa-workflows/elsa-platform","commit_stats":null,"previous_names":["elsa-workflows/elsa-platform"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/elsa-workflows/elsa-platform","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsa-workflows%2Felsa-platform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsa-workflows%2Felsa-platform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsa-workflows%2Felsa-platform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsa-workflows%2Felsa-platform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elsa-workflows","download_url":"https://codeload.github.com/elsa-workflows/elsa-platform/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsa-workflows%2Felsa-platform/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34151276,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-10T12:02:03.829Z","updated_at":"2026-06-10T12:02:04.453Z","avatar_url":"https://github.com/elsa-workflows.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Elsa Platform\n\nElsa Platform is the control plane for building, packaging, cataloging, and deploying Elsa-based systems. It brings together the pieces needed to govern professional Elsa solutions: manifest contracts, safe package inspection, catalog ingestion, runtime bundle planning, immutable deployment artifacts, workspace-scoped APIs, and an operator console.\n\nThe repository is organized as a set of bounded subsystems rather than one large application. Package Catalog owns package governance and workspace-owned catalog data. Runtime Builder turns catalog selections into deployable runtime bundles. Deployment owns artifact, environment, promotion, deployment-run, and runtime-command contracts. The React console provides a shared admin and workspace shell for those capabilities.\n\n## What Is Here\n\n- **Package manifests**: stable JSON contracts that describe deploy-time features, settings, infrastructure requirements, and extension metadata for Elsa packages.\n- **Manifest generator**: an MSBuild-integrated generator that inspects package assemblies with metadata-only reflection and emits `elsa-package.json` during build or pack.\n- **Platform API**: an ASP.NET Core API for public catalog reads, source synchronization, approvals, compatibility checks, workspace custom feeds, Runtime Builder access, and operator administration.\n- **Runtime Builder**: services and contracts for runtime images, saved runtime configurations, server bundle generation, and deployment template rendering.\n- **Deployment**: manifest parsing, artifact construction, path and checksum safety, deployment contracts, planning, execution, and history abstractions.\n- **Platform Console**: a Vite/React admin UI served from `/admin` by the API container in production.\n- **Aspire AppHost**: local orchestration and Azure-oriented publish wiring for the API host and catalog database.\n\n## Repository Layout\n\n```text\nsrc/\n  Elsa.Platform.AppHost                         .NET Aspire orchestration\n  Elsa.Platform.Console                         React admin/workspace console\n  Elsa.Platform.PackageManifests                Manifest wire contract\n  Elsa.Platform.PackageManifest.Generator*      Generator, MSBuild task, and core logic\n  Elsa.Platform.PackageCatalog.*                API, core services, EF Core persistence, sources\n  Elsa.Platform.RuntimeBuilder.*                Runtime plans, bundles, deployment templates\n  Elsa.Platform.Deployment.*                    Deployment manifests, artifacts, engine contracts\n  Elsa.Platform.ServiceDefaults                 Shared host defaults\n\ntests/\n  Elsa.Platform.*.Tests                         Unit and integration-style test projects\n  Elsa.Platform.Console.E2E                     Playwright console smoke tests\n\nspecs/\n  001-...025-*                                  Spec Kit feature history and active plans\n```\n\nSubsystem boundaries matter. Deployment may consume catalog abstractions or client contracts, but it should not depend on catalog API, persistence, or source-provider internals. Package Catalog and Runtime Builder are sibling subsystems. The console is a platform-level shell, not a catalog-only frontend. Artifact-specific behavior belongs in producer and consumer integrations, not in the platform core.\n\n## Platform Model\n\nThe current platform model is centered on accounts and workspaces. Workspace is the tenant boundary for customer-owned catalog and builder data. Public catalog endpoints remain anonymous where appropriate, while workspace-scoped endpoints derive account and workspace context from configured platform identity. Operator administration is separate and still supports an admin-key-backed local fallback.\n\nElsa Platform is the source of truth for immutable deployable artifacts and versioned desired-state revisions. Elsa Studio remains the authoring and single-engine inspection surface. Elsa runtimes remain responsible for executing deployed artifacts and owning runtime state such as workflow instances, bookmarks, queues, locks, and execution logs.\n\nFor platform-integrated Studio installations, the handoff command is **Submit to Platform**. It creates an immutable artifact in Elsa Platform. It does not release, promote, deploy, or make the workflow immediately executable. Direct runtime **Publish** remains direct-runtime terminology for non-integrated Studio installations or explicitly separated fallback behavior.\n\nThe platform is artifact-driven rather than workflow-only:\n\n```text\nproducer integration -\u003e artifact registry -\u003e desired-state revision -\u003e deployment run -\u003e runtime/provider integration\n```\n\nThe first-class product path is Elsa workflow artifacts, but the architecture is intentionally extensible. Workflow definitions, runtime configurations, container image references, Helm charts, or other application artifacts can all share the same control-plane envelope when they have an artifact type, metadata, digest, reference, target capability requirements, and a deployment adapter.\n\nThe active identity and tenancy work is documented in [specs/021-identity-tenancy/plan.md](specs/021-identity-tenancy/plan.md). The current execution plan for the artifact-driven deployment model is documented in [docs/platform-artifact-deployment-execution-plan.md](docs/platform-artifact-deployment-execution-plan.md).\n\n## Technology\n\n- C# on .NET 10 (`net10.0`)\n- ASP.NET Core authentication, authorization, OpenAPI, cookies, and JWT bearer validation\n- Entity Framework Core persistence with SQLite for local development and SQL Server for production-oriented publish\n- .NET Aspire AppHost for local orchestration and Azure infrastructure defaults\n- React 18, TypeScript, Vite, React Query, React Router, Vitest, and Playwright for the console\n- xUnit and FluentAssertions across the .NET test suite\n\nThe SDK is pinned by [global.json](global.json) to .NET SDK `10.0.300` with latest-feature roll-forward.\n\n## Getting Started\n\nRestore and build the solution:\n\n```bash\ndotnet restore Elsa.Platform.sln\ndotnet build Elsa.Platform.sln\n```\n\nRun the API directly:\n\n```bash\ndotnet run --project src/Elsa.Platform.Api\n```\n\nThe API exposes `/health`, OpenAPI metadata, public catalog endpoints, workspace endpoints, and the admin console route under `/admin`. In development it uses SQLite by default with the connection string from `appsettings.Development.json`.\n\nLocal development uses `GenericOidc`-style JWT bearer validation for workspace APIs. Generate a local token that matches `appsettings.Development.json`:\n\n```bash\nchmod +x scripts/create-local-platform-jwt.sh\nTOKEN=\"$(scripts/create-local-platform-jwt.sh)\"\ncurl -H \"Authorization: Bearer $TOKEN\" http://localhost:5220/api/me/workspaces\n```\n\nThe local token defaults to issuer `https://local.elsa-platform.test`, audience `elsa-platform-dev`, subject `user-123`, and a one-hour lifetime. Pass a different subject/name/email when you need another user:\n\n```bash\nTOKEN=\"$(scripts/create-local-platform-jwt.sh user-456 'Grace Hopper' grace@example.test)\"\n```\n\nFor a browser sign-in flow, start the local Keycloak realm, API, and console dev server in separate terminals:\n\n```bash\ndocker compose -f docker-compose.identity.yml up\ndotnet dev-certs https --trust\nASPNETCORE_ENVIRONMENT=Keycloak dotnet run --project src/Elsa.Platform.Api --launch-profile https\ncd src/Elsa.Platform.Console \u0026\u0026 npm install \u0026\u0026 npm run dev\n```\n\nThen open the console and use a workspace-only view such as Runtime Builder:\n\n```text\nhttps://localhost:7094/admin/runtime-builder\n```\n\nWhen the view needs workspace identity it links to `/api/auth/login`, which starts the OIDC authorization-code flow against Keycloak and returns to the console with an HttpOnly customer session cookie. The imported local user is:\n\n```text\nusername: ada\npassword: password\n```\n\nLocal Keycloak authorities use `127.0.0.1` instead of `localhost` so browser cookies from the console/API host are not sent to Keycloak on a different port.\n\nThe local Keycloak admin console is available at `http://127.0.0.1:8080` with `admin` / `admin`.\n\nRun the Aspire host:\n\n```bash\ndotnet run --project src/Elsa.Platform.AppHost\n```\n\nIn local Aspire runs, the dashboard starts Keycloak, the API, and the Vite-based\nconsole. The Aspire-managed Keycloak instance imports\n`dev/keycloak/elsa-platform-realm.json`, listens on `https://127.0.0.1:8080`, and\nuses `admin` / `admin` for the local admin console. Keycloak data is persisted in\nthe `elsa-platform-keycloak-data` Aspire volume, so locally registered users\nsurvive AppHost restarts. The imported console user is `ada` / `password`. Local\nself-registration is enabled in the imported realm, so the Keycloak sign-in page\nshows a registration link. If the Keycloak data volume already exists, either\nenable **User registration** in the Keycloak admin console under realm login\nsettings or remove the local Keycloak data volume so the realm import is applied\nagain. When built console assets are absent, Aspire injects the actual Vite\nconsole endpoint into the API so `/admin/*` is proxied to the console while the\nOIDC callback returns to the same browser origin. Production publish still\nserves the built console assets from the API container under `/admin`.\n\nRun the console during frontend development:\n\n```bash\ncd src/Elsa.Platform.Console\nnpm install\nnpm run dev\n```\n\nThe console dev server proxies relative `/api` requests to `http://localhost:5220` by default. Override `CATALOG_API_PROXY_TARGET` in `src/Elsa.Platform.Console/.env` when the API is running elsewhere.\n\n## Verification\n\nRun the full .NET test suite:\n\n```bash\ndotnet test Elsa.Platform.sln\n```\n\nRun console checks:\n\n```bash\ncd src/Elsa.Platform.Console\nnpm test\nnpm run typecheck\nnpm run build\n```\n\nRun console end-to-end smoke tests:\n\n```bash\ncd tests/Elsa.Platform.Console.E2E\nnpm install\nnpm run e2e\n```\n\n## Manifest Workflow\n\nRuntime package authors add the manifest generator as a private build dependency:\n\n```xml\n\u003cPackageReference Include=\"Elsa.Platform.PackageManifest.Generator\" Version=\"x.y.z\" PrivateAssets=\"all\" /\u003e\n```\n\nDuring build or pack, the generator discovers public CShells feature classes, extracts deploy-time settings, applies XML documentation and optional source-only hints, validates the manifest contract, and includes one root `elsa-package.json` in the produced NuGet package. It intentionally ignores application-code hooks and unsupported CLR-only configuration shapes so manifests stay deploy-time focused and safe to inspect.\n\nSee [src/Elsa.Platform.PackageManifest.Generator/README.md](src/Elsa.Platform.PackageManifest.Generator/README.md) and [src/Elsa.Platform.PackageManifests/README.md](src/Elsa.Platform.PackageManifests/README.md) for the package-authoring details.\n\n## Runtime And Deployment Flow\n\nThe long-term platform flow is:\n\n1. Runtime packages publish an `elsa-package.json` manifest.\n2. Package Catalog synchronizes package sources, validates manifests, records approvals, and exposes compatible package/version data.\n3. Runtime Builder creates saved runtime configurations and bundle artifacts from catalog selections.\n4. Artifact producers submit immutable artifacts to Elsa Platform. The first producer integration is Elsa Studio's **Submit to Platform** command for workflow snapshots.\n5. The artifact registry stores workspace-owned metadata, digests, inspection state, and payload references without storing raw workflow content, provider tokens, credentials, or secret values in catalog tables.\n6. Desired-state revisions reference artifacts plus environment-specific configuration, secret references, observability bindings, and target bindings.\n7. Promotion preview, validation, dry-run, deployment, rollback, and history operate on those platform-owned revisions.\n8. Deployment runs produce durable deployment commands for target runtimes or providers.\n9. Runtime/provider integrations consume commands, fetch or receive artifacts, verify digests and compatibility, apply supported artifact types, and report progress/results back to the deployment run.\n\nRuntime communication is transport-independent. The preferred default for customer-hosted runtimes is outbound runtime pull/sync, because it avoids requiring inbound network access from Elsa Platform. Webhooks are optional advisory notifications that tell a runtime to fetch authoritative commands. Direct platform push is available only for environments that explicitly support inbound connectivity and trust configuration.\n\nThe legacy in-process deployment queue worker is disabled by default with `Deployment:QueueWorker:Enabled=false`. When enabled, it performs stale-run recovery only; runtime/provider integrations remain responsible for claiming commands, applying artifacts, and reporting results.\n\n```text\nElsa Studio integration\n  Submit to Platform\n  -\u003e artifact submission\n\nElsa Platform\n  artifact registry\n  desired-state revision\n  deployment run\n  deployment command\n\nRuntime integration\n  pull/sync or webhook-triggered fetch\n  verify artifact digest and capability compatibility\n  apply artifact through runtime-specific logic\n  report status and safe diagnostics\n```\n\nElsa Platform stays agnostic about artifact internals. It owns identity, permissions, environment targeting, capabilities, validation lifecycle, run history, idempotency, and audit. Artifact producers and consumers own domain-specific packaging and application behavior.\n\nSeveral of these pieces are already implemented as contracts and services; others are represented by Spec Kit plans and roadmap affordances in the console until backend contracts are ready.\n\n## Documentation\n\n- [Package manifest contract](src/Elsa.Platform.PackageManifests/README.md)\n- [Manifest generator](src/Elsa.Platform.PackageManifest.Generator/README.md)\n- [Platform console](src/Elsa.Platform.Console/README.md)\n- [Active identity and workspace tenancy plan](specs/021-identity-tenancy/plan.md)\n- [Artifact-driven deployment execution plan](docs/platform-artifact-deployment-execution-plan.md)\n- [Platform artifact workflow E2E smoke](docs/platform-artifact-workflow-e2e-smoke.md)\n- [Spec Kit feature history](specs/)\n- [Platform integration packaging and host configuration](docs/platform-integration-packaging.md)\n- [Runtime transport trust policy](docs/runtime-transport-trust-policy.md)\n\nImplementation work is tracked through Spec Kit under `specs/`. Start with the current plan for active branch context before making architectural changes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felsa-workflows%2Felsa-platform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felsa-workflows%2Felsa-platform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felsa-workflows%2Felsa-platform/lists"}