Skip to main content
The SDK is built so that the most sensitive data in a formation never enters your systems, and so that nothing in the browser can change what you charge or what doola files.

Where data goes

The iframe is served from doola’s origin, so the browser’s same-origin policy keeps your page’s scripts out of it, and its scripts out of your page. The two sides only exchange a small set of validated messages, and each side checks where every message comes from before acting on it.

Sessions

  • Your secret key never reaches a browser. The loader refuses anything but a publishable key, and @doola/js/server refuses a publishable one.
  • A session acts as one customer only. The cs_ token can read and submit that customer’s formation through the SDK, and nothing else: no other customer, and no Partner API endpoint.
  • Sessions last 10 minutes and are renewed through your route while the SDK is mounted. When your user signs out, your route answers 401 and the SDK stops.
  • The token stays in memory. The SDK never puts it in a URL, a cookie or browser storage.

Trust nothing from the browser

onFormed hands your page a companyId and nothing else, on purpose. Anything that reaches your page’s JavaScript can be changed by the person using it. So your server:
  • reads the company with your secret key and checks it is AWAITING_PAYMENT;
  • checks it belongs to the signed-in customer;
  • prices it from what doola returns, never from a value sent by the browser.
See Take payment.

What is stored in the browser

The iframe stores two things in its own origin’s local storage, and nothing else:
  • The founder’s unfinished wizard, so they can resume. SSNs and ITINs are blanked before it is saved, and the founder types them again on return. It expires after 7 days and is deleted when they submit.
  • A short-lived marker that your checkout was opened, used only to decide when to show the founder a “Continue to payment” button. It expires after 10 minutes.
Browsers that block storage in iframes keep the draft in memory instead, so it lasts until the founder leaves the page.

Content Security Policy

If your site sends a CSP, allow the loader script and the iframe:
  • With test keys, also allow https://sdk.test.doola.com in frame-src.
  • With your own domain, allow that origin in frame-src instead.
  • No connect-src or style-src change is needed: the session request goes to your own route, and the loader sets its styles through the CSSOM.
If you enforce Trusted Types (require-trusted-types-for 'script'), also allow the doola-js policy. It accepts only the loader URL.
If you already send a trusted-types directive, add doola-js to its list.

Other headers

  • Cross-Origin-Opener-Policy: same-origin is fine. The SDK opens new tabs with plain links, so its fallbacks keep working under it.
  • X-Frame-Options and frame-ancestors on your own pages do not affect the SDK. They control who can frame you, not what you frame.
  • The iframe gets allow="clipboard-write" so founders can copy values, and no other permission.

The loader

@doola/js loads https://js.doola.com/v1/doola.js with crossorigin="anonymous". That loader is versioned by major (/v1) and updated in place by doola, so security fixes reach your site without a deploy. It never changes the shape of the options you pass, within a major version.

Report a vulnerability

Email security@doola.com. doola acknowledges reports within two business days. Please never report a vulnerability in a public issue.
Last modified on October 8, 2026