Security

You're handing us the keys to your app. Here's how we guard them.

Last updated June 2, 2026

Ejector sits in a sensitive spot: it reads your code and, for managed-proxy users, holds the sessions that let agents act as your app — and, with Customer Connect, the sessions of each of your end-customers too. We designed the system so that even we can't casually read those secrets, and so a leaked API key can never unlock anyone else's. This page is the honest, technical account of how.

The short version
  • Secrets encrypted with AES-256-GCM, decrypted only in memory at the instant a proxied call runs — never logged, never sent back to the browser.
  • API keys are stored only as hashes. A key resolves credentials through a hash-scoped database routine, so it can only ever unlock the credentials it owns.
  • Capture is gated behind domain ownershipand every tenant is isolated by row-level security — you can only target apps you've proven you control.

01Architecture at a glance

The system is split so that each part has the least access it needs to do its job:

  • Web app & proxy — serves the dashboard, specs, MCP, and the public agent-facing proxy API.
  • Analysis worker — an isolated container that does the heavy work, including headless-browser network capture. It's reachable only with an internal shared secret, never directly by agents.
  • Data & auth — a managed database with row-level security plus managed authentication.

Agents only ever talk to the public proxy at ejector.dev. The worker and database are internal and aren't exposed to them.

02How we protect your secrets

Server-side credentials you add for the managed proxy are the most sensitive data we hold, and they get the strongest handling:

  • Encrypted at rest with AES-256-GCM. Ciphertext lives in the database; the encryption key does not.
  • Write-only from the UI. Once saved, a secret is never returned to your browser — the dashboard shows only whether it's set, never the value.
  • Decrypted only in memory, for the single proxied request that needs it, then discarded.
  • Never logged. Our request and metering logs record what endpoint ran and its status — never secret values or full payloads.

03API keys & tenant isolation

Your Ejector API keys are shown once, at creation, and then stored only as a hash — we can't recover the original. When an agent presents a key, the proxy resolves the right credentials through a hardened database routine keyed on that hash. The practical effect: a key can only ever unlock the credentials that belong to it, and a leaked key can never reach another customer's data. Underneath, row-level securityenforces that every query is scoped to its owner — isolation isn't left to application code.

04Your source code

We don't keep it. When you connect a repo, the worker pulls a temporary snapshot, runs the analysis, and deletes the snapshot — we retain only the generated spec. There's no long-lived checkout of your code on our infrastructure. Private repos are read with a scoped, encrypted token you can revoke at any time.

05Authorization: you can only eject what you own

Exposing a live app to agents is gated behind domain-ownership verification: you prove control of the domain via a DNS TXT record or a well-known file. This gate applies to network capture, registering a live app URL, and — most importantly — Customer Connect. It's a deliberate guardrail: it stops anyone from pointing Ejector at an app they don't control to harvest its users' logins.

06Customer Connect: your customers' sessions

With Customer Connect, each of your end-customers signs in (or signs up) with their own app login on a page you embed. We handle that the same careful way as your own session:

  • The password is used once — only to obtain a session at sign-in — and is never stored.
  • The session is stored encrypted (AES-256-GCM), bound to that customer's key, refreshed automatically, and decrypted only in memory for their own calls.
  • Strict per-customer isolation — one customer's key can only ever resolve their own session; no customer's agent can act as another. You can revoke any connection instantly.
  • Only on a verified domain — see above; you can only collect logins for an app you've proven you own.

07Capture credentials

If you capture an authenticated app by supplying a login, those credentials are used in memory only, for that one capture run, to drive the headless browser. They're never written to disk or stored in our database.

08Transport, auth & payments

  • TLS everywhere. All traffic to the dashboard, API, and proxy is encrypted in transit (HTTPS).
  • Managed authentication, with optional GitHub OAuth scoped to read access. We never store your password.
  • Payments run through a PCI-compliant payments provider. Card data goes straight to them — we never see or store it, which keeps card handling out of our systems entirely.

09Infrastructure

We build on reputable managed providers that maintain their own security programs and certifications, and we keep our own footprint minimal: the analysis worker is secret-gated and not publicly callable for analysis, internal service keys are scoped, and each component holds only the access it needs. Optional AI features — endpoint summaries during analysis and the page-read tool — send only the relevant text to an AI provider to generate the result; no stored secrets or credentials are ever sent.

10What you can do

  • Scope credentials tightly — give the proxy the narrowest API keys that still let your agents do their job.
  • Rotate or revoke Ejector API keys and connected tokens anytime from Settings.
  • Self-host for maximum control — run the proxy yourself or use the direct auth patch so no secrets ever leave your infrastructure.
  • Review activity — watch exactly what your agents called from your dashboard.

11Responsible disclosure

We welcome reports from security researchers. If you believe you've found a vulnerability, email contact@ejector.devwith steps to reproduce. Please give us a reasonable window to fix it before disclosing, and avoid accessing other users' data or degrading the service while testing — we won't pursue good-faith research that respects those bounds.