Your API keys stay on the server.
A pane is code, and Dotpane treats all pane code as untrusted, including your own. This page explains what a pane can reach, where your secrets are kept and what happens on every API call.
The path of one API call
- 1
The pane asks
Pane code calls dash.fetch with a placeholder where the key should go. It never holds the key.
Bearer {{secrets.GITHUB_TOKEN}}
- 2
Dotpane checks
The host must be in the pane’s manifest and on the secret’s list of allowed hosts. If either check fails, the call is refused.
PROXY_SECRET_HOST_MISMATCH
- 3
The key is added
The secret is decrypted on the server for this one call and put into the request.
authorization: Bearer ghp_••••a1f4
- 4
The answer returns
A separate service makes the request. The response is checked for the secret’s value before it goes back to the pane.
200 OK · 184 ms
Where your secrets live
Secrets are stored encrypted and are only ever used on the server.
- Encrypted with AES-256-GCM. The key that protects your secrets is held by a separate key service, not in the database.
- Bound to your account. The encrypted value is tied to your account and its own record. Moved anywhere else, it cannot be decrypted.
- Never shown again. After you save a secret, no page and no API returns its value. You can replace it or delete it.
- Kept out of logs. Secret values are not written to logs, error messages or caches.
What a pane can do
Each pane runs in a locked-down frame, away from your session and from other panes.
- A sandboxed frame. Panes run with scripts allowed and nothing else: no access to the page around them, no pop-ups, no form posts.
- A separate domain. Panes are served from a different domain from the app, so they cannot read your session cookie.
- No network of its own. The frame’s content policy blocks direct connections. The only way out is dash.fetch.
- Checked messages. Every message a pane sends to the app is validated, size-limited and rate-limited before anything happens.
Rules for outbound calls
A call leaves Dotpane only when every rule passes.
- Only the hosts you allow. A secret is sent only to a host that is in the pane’s manifest and on the secret’s own list.
- Public addresses only. Calls to private, local or internal addresses are refused. The address is checked once and the connection goes to that address.
- No redirects. Redirects are never followed, so a response cannot send your key somewhere else.
- Hard limits. Ten seconds per call, 2 MB per response and 60 calls a minute for each account.
Your account
Sign in with an emailed link or with GitHub. There is no password to leak.
- Short-lived links. A sign-in link works once and expires after 15 minutes.
- Hashed sessions. Session tokens are stored as hashes, in a cookie that scripts cannot read.
- Your data only. Every request is scoped to the signed-in account. Another account’s canvases, panes and secrets do not exist as far as yours can tell.
What we log
Enough to show you your usage and to find faults.
- For each API call: the time, the pane, the method, the host, the status and how long it took.
- Not the contents. Request headers, query strings and bodies are not logged. Addresses appear with the placeholder, never the secret.
- Tested before every release. Each rule on this page has automated tests, and a release does not go out unless they pass.
What Dotpane is not
Dotpane is not a general-purpose proxy, VPN or anonymiser. It only makes calls for the panes of the signed-in owner, to hosts that pane's manifest lists.
Read the Acceptable Use PolicyFound a problem?
Email a description and the steps to reproduce it. We read every report and reply to each one.
security@dotpane.com