惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Threat Research - Cisco Blogs
P
Privacy & Cybersecurity Law Blog
The Hacker News
The Hacker News
H
Heimdal Security Blog
W
WeLiveSecurity
L
LINUX DO - 热门话题
Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
The Last Watchdog
The Last Watchdog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
D
DataBreaches.Net
I
Intezer
Webroot Blog
Webroot Blog
C
Cisco Blogs
AWS News Blog
AWS News Blog
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
V
Vulnerabilities – Threatpost
罗磊的独立博客
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
Schneier on Security
Schneier on Security
宝玉的分享
宝玉的分享
博客园 - 叶小钗
PCI Perspectives
PCI Perspectives
D
Docker
Scott Helme
Scott Helme
NISL@THU
NISL@THU
J
Java Code Geeks
B
Blog RSS Feed
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Exploit Database - CXSecurity.com
AI
AI
美团技术团队
Cloudbric
Cloudbric
月光博客
月光博客
P
Proofpoint News Feed
T
Tailwind CSS Blog
Google DeepMind News
Google DeepMind News
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
The Cloudflare Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
When to use Data API vs RPC API in Workflow Engine NEO: a .NET architect's guide
Optimajet Li · 2026-05-20 · via DEV Community

I am Mike Lukinov, co-founder of Optimajet. Since 2022, I have been closely involved in customer architecture and developer experience work around Workflow Engine by Optimajet. I sit in most customer architecture meetings where Workflow Engine NEO questions repeat. The pattern I see most often when teams adopt Workflow Engine NEO is this: an architect picks the RPC API for every integration because "the RPC API is the obvious API." Six months later that team has a BI dashboard, a mobile app, and a partner integration all calling the same RPC surface, and a security review is asking why a read-only analyst token can start and cancel processes. This is the article I wrote instead of answering each case from scratch.

Workflow Engine NEO ships two HTTP surfaces, the Data API and the RPC API; the choice between them is a security and blast-radius decision, not a syntax preference. Everything below is personal opinion, grounded in those customer conversations. Throughout I mark each block as Documented behavior, Architectural recommendation, or Risk if ignored, so you can separate Optimajet facts from opinion. The framing should hold even if you pick a different boundary.

Version note. The code examples below target Workflow Engine NEO v21.0.0 and later, where Web API authorization uses a compact WorkflowApiPermissions claim and the builder API. If you are on v20.x or earlier, check the matching documentation for the older per-operation claim format; do not copy v21 snippets into a v20 project.

What the Workflow Engine NEO Data API and RPC API actually do

Documented behavior. According to the Workflow Engine Web API setup documentation retrieved 2026-05-12, each surface has a one-sentence definition:

"RPC API: Remotely manage Workflow Engine Runtime instances in single-tenant or multi-tenant modes."
"RESTful Data API: Interact safely with the Workflow Engine database without disrupting internal processes."

The Web API Core is provided by OptimaJet.Workflow.Api for .NET 8.0, and Data access is added through a provider-specific package such as OptimaJet.Workflow.Api.Mssql, OptimaJet.Workflow.Api.Postgres, OptimaJet.Workflow.Api.Mysql, OptimaJet.Workflow.Api.Oracle, OptimaJet.Workflow.Api.Sqlite, or OptimaJet.Workflow.Api.Mongo. Workflow Engine NEO is a licensed feature set on top of base Workflow Engine starting from v19.0.0; the RPC API and Web API multitenancy were introduced in v19.0.0 per the 19.0.0 release notes. The two surfaces share the same multi-tenant header, Workflow-Api-Tenant-ID, the same WorkflowApiPermissions claim model, and are exposed through the same Workflow Engine Web API service with a generated OpenAPI specification. What differs is the operations branch each one exposes, and that difference is where the design intent lives.

The Web API requires a Workflow Engine license key with the API/NEO option enabled; without the key, the API does not start. The Data/RPC split is therefore a paid Workflow Engine NEO capability; base Workflow Engine and the free Workflow Engine Community Edition do not include either API, per the Workflow Engine pricing and editions page.

When to use the Workflow Engine NEO Data API

Architectural recommendation. Use the Data API as the default integration boundary for reporting, audit export, BI dashboards, and support tools that should observe workflow state without driving runtime behavior. The Data API is the right place to surface workflow data to consumers whose blast radius you want to keep small.

Documented behavior, important clarification. The Data API is not strictly read-only. The documented Data API surface includes create, update, and delete operations for several entities, among them global parameters, workflow schemes, process parameters, timers, transitions, approvals, and inbox entries. Calling the Data API does not move a process through state transitions the way an RPC command does, but the Data API can mutate the underlying data. Read-only consumers must therefore receive only the specific get and get-collection permissions for the entities they need, not a blanket allow over the Data API surface.

Architectural recommendation, with v21 code. A practical scope for a read-only analyst persona uses the v21 WorkflowApiPermissions builder API to deny everything by default, scope to a single tenant, and then explicitly allow concrete read operations:

var claim = permissions.BuildClaim(builder => builder
    .DenyAllOperations()
    .DenyAllTenantsExcept("TenantA")
    .Allow(
        "workflow-api.data.schemes.get",
        "workflow-api.data.schemes.get-collection",
        "workflow-api.data.processes.get",
        "workflow-api.data.processes.get-collection",
        "workflow-api.data.processes.parameters.get",
        "workflow-api.data.processes.parameters.get-collection",
        "workflow-api.data.processes.transitions.get",
        "workflow-api.data.processes.transitions.get-collection",
        "workflow-api.data.processes.approvals.get",
        "workflow-api.data.processes.approvals.get-collection",
        "workflow-api.data.processes.inbox-entries.get",
        "workflow-api.data.processes.inbox-entries.get-collection"
    ));

Enter fullscreen mode Exit fullscreen mode

This token reads schemes, process records, parameters, transitions, approvals, and inbox entries inside TenantA; it cannot mutate any Data entity or reach other tenants. For cross-tenant analyst access, replace DenyAllTenantsExcept("TenantA") with AllowAllTenants() as an explicit administrative decision.

Note on process history. Process-history operations (get-process-history, get-process-history-count) live under workflow-api.rpc.*, not the Data API. A reporting client that needs them should receive them as scoped read-only RPC exceptions.

When to use the Workflow Engine NEO RPC API

Architectural recommendation. Use the RPC API when the caller is meant to drive the runtime: start instances, execute commands, advance state. Bulk operations live exclusively on the RPC API, so any client that needs to start or progress many processes in one round-trip belongs here.

Documented behavior. The operations branch workflow-api.rpc covers, among others, workflow-api.rpc.bulk-create-instance, workflow-api.rpc.bulk-execute-command, workflow-api.rpc.bulk-get-process-instance, workflow-api.rpc.get-available-commands, workflow-api.rpc.delete-instance, and workflow-api.rpc.get-process-history, per the Workflow Engine documentation. Bulk operations, including both read-like bulk retrieval and runtime-changing operations, live under the RPC API branch.

The RPC API is the right surface for:

  • Polyglot integration. A Node.js worker, a Python ETL job, or a Java partner service that needs to start and progress Workflow Engine processes does so over plain HTTP using the RPC API. The host application stays on .NET, but the callers do not have to.
  • Front-end clients that drive workflows directly, such as a React or Angular UI that maps user actions onto workflow-api.rpc.execute-command or workflow-api.rpc.bulk-execute-command.
  • Backend microservices that orchestrate Workflow Engine state from outside the host process. Risk if ignored. Each RPC operation has a separate permission identifier. A token authorised for workflow-api.rpc.execute-command does not automatically gain access to workflow-api.rpc.delete-instance. In practice, however, teams tend to grant broad RPC allow lists to operational clients, which is where the real blast radius shows up. Keep execute-command, delete-instance, runtime control, and bulk operations in separate permission profiles, and only combine them inside dedicated admin tokens that you audit.

How WorkflowApiPermissions enforces the Data/RPC split at the claim level

Documented behavior. The Workflow Engine NEO permission model treats the Data/RPC split as a security primitive. Each operation has a concrete identifier under either workflow-api.data.* or workflow-api.rpc.*, and tokens are issued by passing concrete identifiers to the WorkflowApiPermissions builder. The Workflow Engine documentation states verbatim: "Operations are hierarchical. More specific rule wins on conflict."

Architectural recommendation. Build claims from concrete operation identifiers. The pattern works for both Data API and RPC API personas:

Persona Builder pattern What the token can do
BI analyst, Data API only Deny all operations, allow concrete Data API operations ending with .get or .get-collection Read schemes, process records, parameters, transitions, approvals, and inbox entries; cannot create, update, or delete
Workflow operator, RPC without destructive ops Deny all operations, allow concrete RPC operations except delete-instance Start instances, execute commands, read; cannot delete
Admin excluding one tenant Allow all operations, then AllowAllTenantsExcept("TenantX") Full admin access except the excluded tenant
Tenant-scoped admin Allow all operations, then DenyAllTenantsExcept("TenantA") Full admin access inside one tenant only

Recipe table compiled from the v21 WorkflowApiPermissions builder examples in the Workflow Engine documentation, retrieved 2026-05-12.

Risk if ignored. The same compact format describes tenant access. A note on multi-tenancy from the Workflow Engine documentation: "The tenant header selects the tenant context only. It is not an authorization source. When security services are enabled, the current WorkflowApiPermissions claim must also allow the selected tenant. If the tenant permission is missing... the request is rejected with 403 Forbidden." Architects who treat the Workflow-Api-Tenant-ID header as an authorization signal will eventually ship a tenant-cross-bleed bug. The header is routing; the claim is authorization.

A note for v21.0.0 readers: IWorkflowApiPermissions was redesigned in v21.0.0 and the synchronous API was removed across both the Data API and the RPC API, per the Workflow Engine release notes retrieved 2026-05-12. Earlier per-operation claim helpers such as AllowAll, AllowList, DenyAll, DenyList, GetAllPermissions, and ValidatePermissions were removed; use the compact WorkflowApiPermissions claim and the BuildClaim builder API from v21.0.0 onward.

Note: some public security pages still show pre-v21 helpers like AllowList(...). Follow the v21 release notes; treat older snippets as v20.x reference.

A decision table: which Workflow Engine NEO API does my caller need?

Architectural recommendation. The table below is the one I draw on whiteboards in support calls.

Use case Prefer Why Permission style
BI dashboard Data API Reads process records, parameters, transitions, approvals, and related Data API entities without runtime commands Only concrete get and get-collection permissions
Read-only support panel Data API Lower operational blast radius No create, update, or delete permissions
Audit and evidence export Data API Snapshot of state without affecting running work Read-only Data API allow list
External service starts workflows RPC API Requires runtime command execution Only create-instance, execute-command, possibly get-available-commands
Front-end UI executes commands RPC API Maps user actions onto runtime transitions Per-user token scoped by tenant and command set
Admin runtime control RPC API Requires start, stop, delete, status operations Separate privileged token, audited

Data API vs RPC API decision canvas

Decision canvas compiled by the author from the Workflow Engine NEO operation branches, 2026-05-12.

Risk if ignored. In multi-tenant deployments, avoid relying on an implicit default tenant for external clients. Prefer requiring every caller to send Workflow-Api-Tenant-ID, and ensure the token's WorkflowApiPermissions claim also allows that tenant. Default-deny on the operation tree, allow only the concrete operations the caller's job needs, deny destructive operations explicitly, per the Workflow API core services documentation.

Take this to your team

If you are the architect deciding how to surface Workflow Engine NEO to the rest of your organisation, here is the short version to bring to a design review.

Decision rule. Pick the Data API for any caller whose job description does not include changing runtime state. Pick the RPC API when the caller must drive the runtime, accepting that the token will carry a larger blast radius. Scope every token, on both APIs, from concrete operation identifiers via the v21 builder API; do not rely on conceptual branch names, and do not rely on the absence of UI affordances. The Data API is safer as an integration boundary, but only with a narrow allow list of read permissions. The API itself is not automatically read-only.

Candidate filter. With one trusted caller and no audit, BI, or analyst workload on the horizon, you can put everything behind the RPC API for now. With more than one consumer of workflow state, such as an analyst tool, a mobile app, or a partner service, split early. Retrofitting permission boundaries after the first quarter in production is expensive.

Cost of getting it wrong. A single RPC token with a broad allow list that lands in a BI tool can move workflow state in ways the audit log records but nobody watches. The same is true of a Data API token granted at branch level when the consumer needs only reads. I have seen both patterns in customer support conversations. The fix is organisational, not code: revoke the token, audit downstream callers, and explain to compliance why a read tool had write access for an unknown window.

Anticipated pushbacks.

  • "REST is simpler than two surfaces." Both APIs are REST/HTTP and share an OpenAPI document; one generator produces one client. The operation tree is what you scope against, so the choice adds a permission boundary, not a protocol.
  • "We can just gate on roles in the host app." Role checks in the host app hold only until somebody calls Workflow Engine NEO directly with a valid token. WorkflowApiPermissions enforces the boundary at the runtime, regardless of caller.
  • "We do not have multi-tenancy, so the security model is overkill." The Data/RPC split is independent of multi-tenancy. A single-tenant deployment still benefits from a read-only Data API token for analytics and a separate privileged profile for destructive RPC operations.

A personal note from the author

Thank you for reading. If you have shipped Workflow Engine NEO and you split your Data and RPC clients differently from how I described, or chose not to split at all, I would like to hear about it. The support conversations I draw from are biased toward teams who are already debating the trade-off, and there are deployment patterns I will not see from where I sit.

The Data API and the RPC API are part of the licensed Workflow Engine NEO tier and I have a commercial interest in your choice. Treat the framing above as a starting point, not the end. If you disagree with the decision rule, please leave a comment below or push back on LinkedIn; that feedback will make the next article in this series sharper.

If you would rather walk through your own architecture, book a demo at workflowengine.io. Come with a concrete task and constraints, and we will help you scope a free POC against Workflow Engine NEO so you can validate the Data/RPC split on your real data before committing.