## Summary Add OOMOL cloud OAuth as a provider authorization source. Users can save an encrypted project API key, select a cloud provider configuration, authorize named connections, and run their actions and proxy requests through SaaS. Existing connections retain their source when the provider default changes, and third-party credentials remain in SaaS. - Implement project discovery, OAuth request synchronization, remote execution, and persistent cleanup of disconnected cloud accounts. Add SQLite, PostgreSQL, and D1 migrations and storage support, with instance reset and maintenance tooling. - Add Console project and authorization settings, localized errors, disconnect notifications, and styled OAuth completion pages that close after successful authorization. Align local development callback origins and proxy routes. - Improve safe request diagnostics and retry transient project health-check failures once. Execution requests are not automatically replayed. - Group storage implementations by database backend, share guarded HTTP requests with Marketplace, update Zod to 4.6.5, and load provider icons from the public catalog. - Document setup, maintenance, and the manual acceptance checklist. ## Validation - `npm run fix-check` passed. - `npm run build:web` passed. - Latest focused regression run: 346 tests passed across 33 files covering Console, SaaS project/client/routes, OAuth completion, and guarded HTTP requests. - Earlier implementation validation included the broader runtime/storage suites and a real PostgreSQL integration run. Full deployed action/proxy, cleanup recovery, and D1 maintenance acceptance remain documented manual checks; they are not claimed as completed by the unit tests. ## Deployment notes Apply migrations `0014_saas_project` and `0015_saas_cleanup_runtime`, configure encryption and an explicit `OOMOL_CONNECT_ORIGIN`, and enable the relevant cleanup scheduling. The remote SaaS deployment must support the project OAuth and remote execution APIs described in `docs/saas-oauth.md`.
8.2 KiB
Cloudflare Deployment
OpenConnector supports Cloudflare Workers as a metadata and runtime-state deployment target. The Worker runtime uses:
- Workers for the HTTP runtime.
- D1 for connections, OAuth config/state, runtime tokens, run logs, and Action idempotency records.
- R2 or Workers KV for temporary transit files.
- Static Assets for the Web Console.
SaaS OAuth deployment
Set OOMOL_CONNECT_ORIGIN explicitly to the public Console origin and configure encrypted storage before saving a project key. The SaaS callback returns to that origin's completion page; the browser synchronization POST must carry the same origin. Reverse proxies must preserve it. Workers do not infer trusted SaaS origin from the incoming request.
Apply D1 migrations through 0015_saas_cleanup_runtime.sql, deploy the scheduled handler and copy the once-per-minute triggers.crons from the example configuration. Verify actual scheduled invocations and cleanup progress after deployment; HTTP traffic does not replace cron. See SaaS OAuth and D1 maintenance. The temporary reset Worker has automatic batch/retry coverage; real D1 reset remains a dedicated test-database acceptance step, not a claim established by local test adapters.
Prerequisites
- A Cloudflare account with Workers, D1, and either R2 or Workers KV access.
- Wrangler available through
npx wrangler. - Node.js 22 or newer.
Create Local Config
Install dependencies and copy the example Wrangler config:
npm install
cp wrangler.example.jsonc wrangler.local.jsonc
wrangler.local.jsonc is ignored by git. Fill it with your Cloudflare resource IDs before remote
deployment.
Log In With Wrangler
Skip this step if you are already logged in:
npx wrangler login
Create Cloudflare Resources
Create the D1 database:
npx wrangler d1 create open-connector
Then choose one transit-file backend. R2 is the default and supports files larger than 25 MiB:
npx wrangler r2 bucket create open-connector-transit-files
Alternatively, create a Workers KV namespace for lightweight deployments that do not need files larger than 25 MiB:
npx wrangler kv namespace create open-connector-transit-files
Put the returned D1 database_id and R2 bucket name or KV namespace id into
wrangler.local.jsonc. For KV, comment out the r2_buckets block, uncomment the
kv_namespaces block, and set TRANSIT_FILES_BACKEND to "kv" as shown in the example config.
Only one backend may use the TRANSIT_FILES binding. All Wrangler commands that read the Worker
config should use --config wrangler.local.jsonc.
Local Worker Preview
The local Worker preview stores its D1, R2, and KV data under the ignored .wrangler directory.
This data is separate from the remote Cloudflare resources.
Remote secrets set with wrangler secret put are not available to the local preview. To test local
admin authentication and encryption of credentials, OAuth client configuration, and completed
idempotent Action responses, add separate local values to the ignored .env file before starting
the Worker:
OOMOL_CONNECT_ADMIN_TOKEN=replace-with-a-local-admin-token
OOMOL_CONNECT_ENCRYPTION_KEY=replace-with-a-local-encryption-key
Apply the migrations to Wrangler's local D1 state, then start the Worker:
npx wrangler d1 migrations apply open-connector --local --config wrangler.local.jsonc
npm run dev:cloudflare
npm run dev:cloudflare generates the catalog, builds the Web Console, copies catalog assets, and
runs wrangler dev --config wrangler.local.jsonc. The local Worker preview uses the same generated
provider Action executor registry as the Node runtime.
Check the local Worker and open the Web Console at http://localhost:8787:
curl http://localhost:8787/health
The health endpoint should return {"ok":true}.
Remote Deployment
Apply all pending migrations to the remote D1 database before the initial deployment and every
upgrade. npm run deploy:cloudflare does not apply D1 migrations:
npx wrangler d1 migrations apply open-connector --remote --config wrangler.local.jsonc
Generate two independent random values by running this command twice:
openssl rand -base64 32
Store the encryption key in a password manager or another external secrets vault. If it is lost or replaced without first re-encrypting existing D1 records, encrypted credentials, OAuth client configuration, and completed idempotent Action responses cannot be recovered. Keep the admin token available to operators who need the Web Console or admin API.
Paste the generated values when Wrangler prompts for each secret:
npx wrangler secret put OOMOL_CONNECT_ADMIN_TOKEN --config wrangler.local.jsonc
npx wrangler secret put OOMOL_CONNECT_ENCRYPTION_KEY --config wrangler.local.jsonc
Deploy:
npm run deploy:cloudflare
npm run deploy:cloudflare generates the catalog, builds the Web Console, copies catalog assets,
and runs wrangler deploy --config wrangler.local.jsonc --minify. The copied
wrangler.local.jsonc already maps the built Web Console assets to the ASSETS binding used by
the Worker. --minify matters on Workers beyond the upload size limit: a heap snapshot of the
running isolate (taken through the wrangler dev inspector) shows the script source retained as one
string for as long as the isolate lives, so the 13.8 MiB minified script costs about half the
isolate memory of the 28.7 MiB unminified one, out of the 128 MB each Worker isolate gets.
Use the Worker URL printed by Wrangler to check the deployed runtime, then open the same URL in a browser and enter the admin token to access the Web Console:
curl https://open-connector.example.workers.dev/health
The health endpoint should return {"ok":true}. Replace the example URL with the deployed Worker
URL or your custom domain.
Runtime Behavior
The Cloudflare runtime serves catalog metadata, /api and /v1 metadata endpoints, connections,
runtime tokens, OAuth config/state, transit files backed by the configured R2 bucket or KV
namespace, and the generated provider Action executor registry.
Configure an R2 lifecycle rule for the transit bucket if you want unread expired transit files
cleaned up automatically. Workers KV applies the configured TTL when each file is written and
deletes it automatically. KV clamps OOMOL_CONNECT_TRANSIT_FILE_TTL_SECONDS to a minimum of 60
seconds and OOMOL_CONNECT_TRANSIT_FILE_MAX_BYTES to a maximum of 25 MiB.
Response Compression
Cloudflare negotiates and applies response compression on egress, so the Worker leaves compression
to the edge instead of running it in the application. Workers build responses with encodeBody set
to "automatic", which means the runtime encodes the body itself to satisfy the Content-Encoding
header; a body the application had already compressed would be encoded a second time and arrive
undecodable. Node deployments have no edge in front of them and keep compressing in the application.
Cloudflare's default compressible content types include application/json, so
eligible /api and /v1 metadata responses are compressed for clients that advertise support.
Eligibility also requires a 200 status and a body of at least 48 bytes for gzip or 50 bytes for
Brotli and Zstandard, so the smallest responses stay uncompressed whatever their content type. The
list has text/x-markdown but not text/markdown, which /api/actions/:actionId/agent.md returns,
so agent guides are served uncompressed. They are small — around 1.5 KiB for a typical action and
20 KiB for the largest one in the catalog — so this is usually not worth acting on. Add a
Compression Rule matching text/markdown if your deployment serves agent guides heavily.
Configuration
Cloudflare uses the same environment variable names for origin, auth tokens, action policy, transit
file limits, and credential encryption. PORT, HOST, OOMOL_CONNECT_DATA_DIR,
OOMOL_CONNECT_CATALOG_LAZY_SCHEMAS, and OOMOL_CONNECT_CATALOG_SCHEMA_CACHE_FILES are local
Node-only settings on Workers.
See configuration.md for all runtime environment variables.