Multi-Tenancy

Every Hyphen resource is scoped to an organization. Workflows, runs, actions, tables, OAuth credentials, and agent executions are all isolated per tenant.


Organization Identification

Every API call requires the X-Org-Id header:

bash
curl -X GET http://localhost:3009/workflows \
  -H "X-Org-Id: acme-corp"

The header determines which tenant's data is accessed. There is no cross-org data leakage — a request with X-Org-Id: acme-corp will never see workflows belonging to X-Org-Id: globex-inc.

:::api GET /workflows Returns only workflows belonging to the organization identified by X-Org-Id. :::


Encrypted Secret Storage (Org Config)

Each organization stores API keys, database connection strings, and other secrets in encrypted org config. Values are stored encrypted at rest and never returned in plaintext via API.

bash
# Store a secret
curl -X POST http://localhost:3009/org-config \
  -H "X-Org-Id: acme-corp" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "api:openai_key",
    "value": "sk-proj-abc123..."
  }'
bash
# List all config (values are masked)
curl -X GET http://localhost:3009/org-config \
  -H "X-Org-Id: acme-corp"
POST/org-config

Store or update an encrypted configuration key.

GET/org-config

List all configuration keys (values masked).

Key Naming Conventions

Prefix Purpose Example
api: Third-party API keys api:openai_key, api:salesforce_token
db: Database connection strings db:orders_pg, db:analytics_mongo
oauth: OAuth app credentials oauth:gmail_client_id

Referencing Secrets in Workflows

Use the orgconfig: prefix to reference encrypted values in workflow steps. The execution engine resolves these at runtime — the actual secret value never appears in the workflow definition.

json
{
  "action_name": "fetch_crm_data",
  "kind": "http",
  "url": "https://api.salesforce.com/query",
  "headers": {
    "Authorization": "Bearer orgconfig:api:salesforce_token"
  }
}
json
{
  "action_name": "query_warehouse",
  "kind": "db",
  "datasource": "orgconfig:db:warehouse_pg",
  "query": "SELECT * FROM orders WHERE status = $1"
}

The orgconfig: prefix works in action registration, workflow properties, and any string value that the execution engine resolves.


Data Isolation

Every data type is scoped per organization:

Resource Isolation
Workflows Definitions visible only to owning org
Runs Execution history, context, and status per org
Actions Registered actions scoped per org
Custom Tables Table definitions and data per org
OAuth Connections Tokens and credentials per org
Agent Runs Agent executions, traces, and memory per org
External Forms Form definitions and submissions per org
Org Config Encrypted secrets per org

Credential Scoping

OAuth tokens are scoped to both the organization and the specific connected account. When an agent uses gmail_send, it sends from the account that was authorized for that org — not a shared platform account.

json
{
  "type": "gmail_send",
  "properties": {
    "__oauth_account__": "[email protected]",
    "to": "@input.recipient",
    "subject": "Invoice Update"
  }
}

The __oauth_account__ property identifies which connected account to use. Each org connects their own accounts through the OAuth flow.


Multi-Tenant Embedding

Hyphen's multi-tenancy is designed for platform embedding. If you're building a product that offers workflow automation to your customers, each of your customers becomes a Hyphen organization:

text
Your Platform
  └── Customer A  →  X-Org-Id: customer-a
  └── Customer B  →  X-Org-Id: customer-b
  └── Customer C  →  X-Org-Id: customer-c

Each customer's workflows, data, credentials, and agent executions are fully isolated. Your platform makes API calls on behalf of your customers by setting the appropriate X-Org-Id header.

→ Next: Security