35  How Sophea Automations Works

35.1 Overview

Status: This page is technical reference for the Automations 0.92.1 implementation. It does not claim customer availability; staging verification and production enablement are separate gates.

Sophea Automations is a dedicated workflow runtime whose UI is mounted in the Nous web app. Portal signs short-lived launch tokens through the Nous BFF; trusted Sophea actions use the Nous broker for knowledge and agent operations. This document describes the service boundaries, identity lifecycle, and scoped ACL propagation.

35.2 Architecture

Sophea Automations comprises a dedicated Activepieces service runtime and an embedded frontend mount:

  1. Automations runtime: dedicated API, workers, and flow engine with its own PostgreSQL and Redis resources.
  2. Embedded UI: the Nous web app mounts the Automations frontend runtime in a Shadow DOM at /app/automations; it is not running inside the Nous backend or served in an iframe.

Trusted Sophea pieces call Nous broker endpoints for Nous-backed operations. The runtime does not get direct access to the Nous database.

35.2.1 Identity and access lifecycle

The Automations account is bound to the member’s stable Portal user identity, not to an email address. Changing or reassigning an email therefore does not merge Automations accounts or transfer their access.

The Automations platform is provisioned by the platform operator before customer access is enabled. Opening Automations can create the member’s workspace project and project membership, but it cannot create the platform or grant platform-administrator authority.

For every user request to a workspace project, Automations checks the current effective workspace membership in Portal before applying its local project role. Removing a direct, Team-derived, or Organization-derived workspace grant blocks the member’s next request, including requests made with an existing Automations session. If Portal cannot confirm membership, access fails closed.

Browser
  -> Nous web app: `/app/automations`
     -> `AutomationsHost` mounts `mountNousAutomations` in a Shadow DOM
        -> same-origin BFF: `POST /api/automations/embed-token`
           -> Nous backend: `/automations/embed-token`
              -> Portal signer: `/api/internal/automations/embed-token`
                 (service-authenticated with `X-Client-ID`)
              <- short-lived signed launch token bound to Portal identity,
                 Workspace and Automations project
        -> dedicated Automations frontend/API runtime
           -> dedicated Activepieces API, workers and flow engine
              -> Automations PostgreSQL + Redis
              -> trusted Sophea pieces -> Automations API signer -> Nous broker
                 -> Nous RAG (signed ACL principals for knowledge search)
                 -> Agent Service
              -> Portal model proxy for Generate/Refine

35.3 The Broker Pattern

The broker is the trusted route for Nous-backed actions: Sophea piece calls use HMAC-signed HTTP endpoints on the Nous backend instead of direct access to the Nous database.

35.3.1 How it works

  1. A flow step executes in the Automations runtime.
  2. The Sophea piece sends a closed operation and business payload to the Automations API using its typed Engine token.
  3. The API verifies the token’s queue and active job, then derives the project, workspace, tenant, run, graph step and triggering member from server-owned records.
  4. The API computes the HMAC-SHA256 signature and sends the request to the configured Nous broker endpoint.
  5. Nous verifies the signature and workspace membership before executing the operation.

35.3.2 Why this matters

  • No direct database access: The Automations API never touches the Nous database directly
  • Tenant isolation enforced at the boundary: Every broker request carries workspace identity, verified on every call
  • Auditable: Broker identity carries workspace, run and step IDs; runtime execution actions also carry their attempt number.
  • Rate-limited: Broker endpoints can enforce per-workspace rate limits

35.3.3 HMAC signature

The HMAC signature is computed over:

${timestamp}.${sha256(body)}.${projectId}.${runId}.${stepId}.${attemptNo}

Property catalogs preserve run ID execute-property and the purpose-specific catalog step. Their payload omits attempt_no; signing uses attempt 0. Model execution operations retain attempt-aware operation IDs.

SOPHEA_AUTOMATIONS_BROKER_SECRET is shared by the Automations API and the Nous backend, not propagated to engine children or piece processes. The API sends the signature in Authorization as Bearer ${timestamp}.${signature}. The authenticated engine remains trusted for its runtime step and attempt assertions within its own active job and project; those assertions are not independent cryptographic attestation.

Additional headers: - X-Sophea-Automation-Project-ID - X-Sophea-Automation-Run-ID - X-Sophea-Automation-Step-ID - X-Sophea-Operation-ID - X-Sophea-Tenant-ID (if set) - X-Sophea-User-ID (if set)

35.4 Tenant Isolation

35.4.1 Workspace equals tenant

In Sophea, a workspace is a tenant. Every flow, run, and piece execution is scoped to a workspace. The workspace ID is propagated through:

  1. Server-owned project mapping: the Automations API resolves the workspace and tenant from the authenticated active job’s project.
  2. Broker requests: the API constructs workspace_id and identity fields; piece business payloads cannot override them.
  3. Database queries: The Nous backend opens a tenant-scoped database session for each broker call

35.4.2 Broker endpoint security

Every broker endpoint follows the same security pattern:

  1. _headers_match_body(): verifies that the HMAC signature was computed over the same body that was received
  2. verify_automation_broker_authorization(): verifies the HMAC signature and timestamp
  3. _verify_runtime_member(): checks that the requesting user is an active member of the workspace
  4. _tenant_id_from_member(): resolves the tenant ID from the workspace membership
  5. _execute_runtime_broker_call(): opens a tenant-scoped database session and executes the operation

35.4.3 Shell mode

Shell mode restricts the available pieces to a vetted allowlist. This prevents untrusted pieces from running in production environments. The allowlist is defined in nous-automations-shell.ts and includes only Sophea-approved pieces.

Shell mode also pins the code execution mode. Sophea deployment configuration uses AP_EXECUTION_MODE=SANDBOX_CODE_ONLY. Code steps run in a V8 isolate (isolated-vm) by default; a Code step with Deno enabled runs in a one-shot Deno subprocess, which is available only in SANDBOX_CODE_ONLY. { } template expressions always use V8 isolates.

V8 code receives copied inputs and has no Node built-ins. Deno runs with no network, environment, or subprocess permissions and can read the step directory. SANDBOX_CODE_ONLY disables npm package dependencies for Code steps.

Trusted Sophea piece code runs outside those user-code sandboxes in a Node child process. That child inherits the engine environment except for AP_SANDBOX_WS_TOKEN, so trusted piece code can use SOPHEA_AUTOMATIONS_BROKER_SECRET to sign broker calls. User Code steps do not receive this secret. If AP_EXECUTION_MODE is set to UNSANDBOXED while shell mode is enabled, the engine rejects the combination and fails closed, so a configuration error cannot silently restore in-process code execution.

UNSANDBOXED remains only for explicit trusted-operator development with shell mode off and is never a Sophea production option. V8 isolates are not kernel boundaries and run within the engine process. The child process for trusted pieces is for vetted code, not untrusted flow code.

35.5 ACL Propagation

35.5.1 Signed ACL principals

When a Nous knowledge action searches the knowledge base, the broker builds signed ACL principals for that request. The ACL includes:

  1. Public documents: PUBLIC_DOC_PAT.
  2. User-specific documents: the normalized user-email principal from prefix_user_email(email).
  3. External group documents: group principals resolved for the user’s email by fetch_external_group_ids_for_email.

The ACL is signed with NOUS_RAG_SERVICE_AUTH_KEY using HMAC-SHA256 and sent to the RAG service in X-Sophea-Principals. This describes authorization for knowledge search; it does not imply universal permissions for connectors or other external systems.

35.5.2 How it works

  1. The broker endpoint receives a knowledge-search request with workspace and user identity.
  2. _signed_principals_for_member() builds the ACL for the requesting user.
  3. The ACL is signed and sent to the RAG service.
  4. The RAG service verifies the signature and filters search results against those principals.

35.5.3 Cross-service headers

Sophea service calls have distinct contracts. This table describes broker and RAG headers only; webhook authentication is configured separately on each Catch Webhook trigger.

Header Scope and purpose
Authorization HMAC-signed Nous broker request
X-Sophea-Automation-Project-ID Automations project for a broker request
X-Sophea-Automation-Run-ID Flow run identifier
X-Sophea-Automation-Step-ID Flow step identifier
X-Sophea-Operation-ID Operation correlation identifier
X-Sophea-Tenant-ID Included when a tenant is resolved
X-Sophea-User-ID Included when an acting user is resolved
X-Sophea-Principals Signed ACL sent to the RAG service, not a general broker header