Architecture

Security Model

Auth lanes, deployment authority, and execution guardrails

Overview

This guide covers the security model, authentication lanes, deployment authority, and guardrails that ensure safe remote execution.

Authentication Lanes

Workflow Studio uses distinct authentication scopes to separate concerns:

Public Lane Scopes

Used by client applications and external triggers:

  • trigger:write - Trigger new workflow runs
  • runs:read - Read run status and results
  • runs:write - Cancel or resume runs
  • deploy:read - Read deployment information
  • deploy:write - Create and activate deployments

World Proxy Lane

The world:proxy scope is for internal world operations forwarded from the app host to the remote worker. This includes:

  • POST /v1/world/events/create - Creating workflow events
  • POST /v1/world/queue/publish - Publishing queue messages
  • GET /v1/world/runs/* - Reading run data
  • GET /v1/world/steps/* - Reading step data
  • Stream operations

All /v1/world/* endpoints require the world:proxy scope.

Admin Scope

The admin scope grants access to all operations and bypasses other scope checks.

API Key Structure

API keys are stored with a secret_hash (SHA-256 of the secret) and a set of scopes. The secret is only shown once at creation time.

type ApiKey = {
  keyId: string;
  projectId: string;
  environment: string;
  scopes: ComputeScope[];
  secretHash: string;
  revokedAt?: string;
  createdAt: string;
};

Execution Guardrails

App-Host Guardrails

When remote execution is enabled, local app-host queue handlers should not process workflow messages. The world-remote adapter implements this guard:

createQueueHandler() {
  return async (req) => {
    // Record unexpected hit for diagnostics
    recordUnexpectedHit({ /* ... */ });
    
    return new Response(
      JSON.stringify({
        code: 'remote_execution_enabled',
        message: 'Workflow queue handlers are disabled on app host while remote execution is enabled.',
      }),
      { status: 409 }
    );
  };
}

Strict Remote Guard

In production (NODE_ENV=production or WORKFLOW_STRICT_REMOTE=1), the system enforces that WORKFLOW_TARGET_WORLD matches the expected remote target:

function enforceRemoteTargetGuard(env: NodeJS.ProcessEnv): void {
  const expectedTarget = 'workflow-studio/world-remote';
  const actualTarget = env.WORKFLOW_TARGET_WORLD;
  
  if (actualTarget !== expectedTarget) {
    throw new Error(
      `Remote execution guard failed: WORKFLOW_TARGET_WORLD must equal "${expectedTarget}" in strict mode; received "${actualTarget ?? '(unset)'}".`
    );
  }
}

This prevents accidental local execution when remote mode is configured.

Rate Limiting

All authenticated endpoints are rate-limited per API key (default: 120 requests/minute).

Security Checklist

  • Use separate API keys for world:proxy and public scopes
  • Set WORKFLOW_TARGET_WORLD=workflow-studio/world-remote in production
  • Configure WORKFLOW_STUDIO_DIAGNOSTICS_TOKEN for production diagnostics
  • Enable WORKFLOW_STRICT_REMOTE=1 for additional safety
  • Run validate-ownership --strict before production deployments
  • Monitor audit logs for unexpected lane values
  • Review active deployment pointer after rollbacks
  • Never expose WORKFLOW_COMPUTE_API_KEY in client-side code