Architecture

Security & Auth

How dataflows handles secrets, tokens, and permissions.

Token Management

Handling OAuth2 tokens is complex. dataflows abstracts this away completely.

The connections Table

Tokens are stored in the connections table.

  • Encryption: access_token and refresh_token are encrypted using AES-256-GCM before being written to the database.
  • Auto-Refresh: The engine automatically checks expires_at and refreshes the token before a workflow step runs.

Service Clients

We separate the "Application" (Service Client) from the "User" (Connection).

  • Service Client: Contains client_id and client_secret.
  • Connection: Contains the user's access_token.

Dependency Injection

Workflows never access secrets directly. They request a fetch instance that is pre-configured with the correct headers.

// ❌ BAD: Handling tokens manually
const token = await db.tokens.find(...)
await fetch('https://api.github.com', { headers: { Authorization: token } })

// ✅ GOOD: Dependency Injection
export async function getIssues(repo: string) {
  'use step'
  // The engine injects the authenticated fetch client
  return github.getIssues(repo, { fetch, apiToken: GITHUB_TOKEN })
}

Isolation

Each workflow execution runs in an isolated context.

  • Environment Variables: Secrets are injected as environment variables.
  • Network Isolation: Workflows can be restricted to specific egress domains.