Security
What we do to keep your keys, your mail and your data safe, in plain terms. This page covers what you can rely on as a customer; it is not a description of our internal infrastructure.
API keys
- Keys are shown once, when you create them, and stored only as a SHA-256 hash. We cannot read a key back, and neither can anyone who reads our database.
- Live and test keys are separate. A test key (
av_test_) can never deliver mail, sees only test data, and cannot change the webhooks, templates, suppression list or account settings your live mail depends on, so a test key in a CI log is not a sending credential. See Test mode. - Revoke a key from the dashboard and it stops working on the next request. The dashboard shows when each key was last used.
- A key carries scopes; a send-only key cannot read the log or change the account. See Scopes.
- Only the account owner can give a key
account:settingsorkeys:manage, the scopes a key for an AI agent holds. Even that key cannot touch plans and payment, delete the account, manage the team or change how anyone signs in. A key it creates never has more access than its own, and it can revoke only the keys it created. Every change a key makes is listed, with the key's name, in the dashboard's Activity. - Every key is rate limited (between 10 and 50 requests a second per key depending on plan, see Plans and limits), and each account has a monthly sending allowance, so a leaked key cannot send unbounded volume.
Sending from your domain
- A domain sends only after it proves control of its DNS twice: an ownership TXT record unique to it, then DKIM. Each domain can be verified on one account only, and nobody can add a subdomain or a parent of a domain on another account.
- The sandbox sender delivers only to your own verified address and the simulator recipients, so a fresh account cannot send to strangers before verifying a domain.
- Addresses that hard-bounce or complain are added to your suppression list automatically, and further sends to them are refused until you remove the entry.
Webhook signing
Every delivery to your endpoint carries an Avelto-Signature header: t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256 over "<t>.<raw body>" with the endpoint's secret. The secret is shown once when you create the endpoint.
Verify every request before acting on it:
- Compute the HMAC over the exact raw body, not a re-serialised object.
- Compare it to
v1in constant time. - Reject requests whose
tis more than five minutes from now, which stops replays.
The Node SDK's verifyWebhookSignature(secret, rawBody, header) does all three. See Webhooks and Webhook events.
Endpoints must use HTTPS in production, and we never follow redirects from your endpoint.
Provider events
Delivery, bounce and complaint events reach us through Amazon SNS. We accept a notification only when its signature verifies against Amazon's signing certificate and it comes from the topic we own, and each message is accepted once. No one can inject a fake delivery or bounce into your log by posting to our endpoint.
Where your data lives
Your account data, email records and events are stored in the EU. Email is sent through Amazon SES in the EU (Stockholm) region. Requests to our website, dashboard and API reach us through Cloudflare's network, which handles each one at a location near whoever sent it, so a request from outside the EU passes through Cloudflare outside the EU on its way in. Cloudflare carries API requests through without storing them. This is the same for every plan; Enterprise contracts state it in writing.
Retention
Email bodies are kept for the retention period of your plan (see Pricing). After that the record and its events remain, with any quoted content removed, so ids and statuses keep resolving. Suppression lists and domain settings are kept until you remove them or delete the account.
Deleting your account removes every email, domain, key, webhook endpoint and suppression, and releases your domains from our sending provider.
Sessions
Dashboard sign-in uses single-use links that expire after 15 minutes. Sessions last 30 days. Settings lists every device you are signed in on, and you can end any one of them, or all of them at once.
Instead of waiting for an email, you can add other ways in from Settings, under Security: a passkey, a password, or an authenticator app. The emailed link always keeps working, whatever you add.
- Authenticator app. Any app that shows 6-digit codes (TOTP) works. Add one under Security, scan the QR code or type the key, and confirm with one code. On the login page, choose Use an authenticator app and enter your email and the code the app shows. The key is stored encrypted and never shown again; one app per login, and adding another replaces it. Each code works once, and after a few wrong codes for an address, codes for it are refused for a while: sign in with an emailed link instead.
- Adding a password, a passkey or an authenticator app needs a sign-in from the last 10 minutes (or your current password, for a passkey or an authenticator app), so a session left open somewhere is not enough to add a way in. Removing an authenticator app needs the same.
- Every password, passkey or authenticator app added to or removed from your login is emailed to you, with where the change came from. Setting a new password signs out every other session.
- If you think someone else had your session, sign in with an emailed link and use Sign out everywhere with Also remove my password, passkeys and authenticator app ticked. Anything they added goes with it; add back what you use.
- The session cookie is host-only and
__Host-prefixed, so no other site, and no other subdomain, can set one for the dashboard.
Team invitations
An invitation joins someone to your account only when they choose to. The link in the invitation email opens a page that shows who invited them, to which account and in which role; pressing Accept sends a sign-in link to the invited address, and following that link is what joins. Signing in the ordinary way never joins anyone to an account. Invitations expire after 7 days and work once.
Reporting a vulnerability
Found something? Email security@avelto.dev with the details and steps to reproduce. We reply within two working days, fix confirmed issues before public disclosure, and credit reporters who want it. Please do not test against other customers' accounts or send unsolicited email through the service.