Security
How Embaro is built, in detail
Written for the person who has to sign off on it. Every mechanism below is implemented today — nothing here is a roadmap — and the section on what we don't have is as complete as the rest.
What we actually hold
The smallest useful answer first, because it determines everything else.
Embaro handles employment administration data: who is joining, leaving or changing role, and which systems they should be given or lose. In practice that is a name, a work email, a department, a job title, a manager, a start date, and a checklist of access.
It is not a medical system, a payroll system or a document store. We hold no patient records, no salary, no bank details, no government identifiers, and no card numbers. What your form asks for is entirely your choice — so what we hold is bounded by what you decide to collect.
The employees being onboarded never have accounts. They are records, not users. Only the people who sign in to file and process requests have credentials with us.
We also hold your support conversations — what you write to us from inside the product, and our replies. Those live in the console and nowhere else: the email that tells you a reply arrived carries no part of the message, only a link. That is on purpose. Mail gets forwarded, quoted and retained in ways a console message does not, and a thread can hold a message meant for one party and not another.
Encryption
Named precisely, because “bank-grade encryption” means nothing.
- In transit
- TLS on every connection, to the app and between us and every provider below. HTTP is redirected, never served.
- At rest (database)
- Full-disk encryption by our database provider, plus the field-level encryption below for the values that warrant it.
- Your users' passwords
- scrypt(N=65,536, r=8, p=2, 64-byte output, per-password random salt) — a deliberately slow, memory-hard hash on OWASP's recommended list. Passwords are hashed, never encrypted: there is no key that turns them back. We cannot read, recover or tell you a password, and neither can anyone who steals the database. Stored hashes are self-describing, so cost parameters can be raised and old hashes upgraded on next sign-in.
- Stored secrets
- AES-256-GCM with a 96-bit random IV, for the two secrets we must be able to use again: your outbound mail-server password (if you send from your own domain) and two-factor authenticator seeds. GCM is authenticated, so tampering is detected rather than silently decrypted.
- Session tokens
- 256 bits of CSPRNG entropy, stored only as a SHA-256 hash. A database leak yields no usable session.
- Card details
- Never touch our servers at all. Payment happens on Stripe-hosted pages; we receive an identifier and a subscription status. See the PCI note below.
Password handback: we cannot read it
The part most worth your scrutiny, because it is the part most products get wrong.
When your IT desk finishes setting someone up they have credentials to hand back — an email password, a computer login, a VPN account. The normal industry answer is to email them, or paste them into a one-time-link site. Both put the plaintext somewhere you do not control.
Embaro does it differently, and the difference is structural:
- The technician's browser generates a 256-bit AES-GCM key locally and encrypts the secret values before anything is transmitted.
- Our server receives only the ciphertext. The key is never sent to us, never stored by us, and never present in any log, backup or database we hold.
- The recipient opens it with the key, which travels in the URL fragment — the part of a link browsers never transmit to a server.
- It can be revealed once. Then the ciphertext is destroyed, leaving a tombstone recording when it was opened and from what address — so an interception is visible rather than silent.
- Unopened, it self-destructs on a timer you choose: 1, 3, 7, 14, 30 days (3 by default).
The ciphertext is bound to its own record, so a database write cannot move one handover's payload into another. Usernames and email addresses are deliberately not encrypted — they are not secrets, and encrypting them would hide them from the person who needs them.
The consequence, stated plainly: because we never hold the key, we cannot recover these values for you — not on request, not under subpoena, not after a mistake. That is the guarantee, and it is also the limitation. Retrieve them promptly and store them somewhere durable.
One thing worth knowing regardless of vendor: corporate mail scanners (Outlook Safe Links, Mimecast, Proofpoint) rewrite links in inbound mail, which can capture one-time-link URLs into their click logs. That is why Embaro can also require an Embaro sign-in to open a handover — a second lock that makes a leaked link useless on its own. It is on by default.
Sign-in and access control
- Sessions
- Opaque tokens held server-side, not JWTs. That is a deliberate trade: it costs a database read per request and buys instant revocation. Disabling a user, changing a password or locking an account takes effect on their very next request, not whenever a token happens to expire.
- Two-factor
- TOTP (authenticator app) available on every account and every plan, including when signing in through Google or Microsoft.
- Single sign-on
- Google and Microsoft via OpenID Connect with PKCE. Identity resolves on the provider's immutable subject identifier, never on the email address it sends — so an address that changes hands cannot inherit an account. The provider's token is read once to learn who is signing in and then discarded; it never becomes the session.
- Roles
- Members file requests; approvers approve; administrators configure. One owner per organization cannot be demoted or deactivated by their own administrators.
- Rate limiting
- On sign-in, password reset, signup and other sensitive endpoints. Counters are keyed by an irreversible digest, so no email address or IP is stored in that system.
- Password handling
- Nobody can see a password: they are hashed, and no code path reads one back. Embaro staff can never set one either — the only account-recovery tool we have sends a reset link to the account holder's own mailbox, which is why we cannot sign in as your users. Inside your own organization an administrator can set a member's password, deliberately: it is how you recover somebody who has lost access to their mailbox. Doing it requires the administrator to re-enter their own password, signs that member out everywhere, emails them that it happened, and is recorded in your activity log.
Tenant isolation
Every organization's data is scoped on the server. The identifier used to fetch your data is derived from your session, never from anything the browser sends — no URL, no form field, no header can widen it. A request for another organization's workspace returns a not-found page, and deliberately the same page whether or not that organization exists, since confirming existence is itself a leak.
There are exactly three sanctioned ways to reach data outside your own account:
- Your IT provider, if you are a client of one. Their staff act as your IT desk — that is the arrangement you bought — and access is granted by a database relationship, never by anything a client sends. Support you send from inside the product goes to them, and we cannot read it unless they forward it to us.
- Embaro support, and only while you leave support access switched on. It is on by default so help never waits, and any of your administrators can switch it off in one click — at which point our staff get the same not-found page as a stranger, on the very next request. Both directions are immediate and both are recorded in your own activity log. Even with it on, support cannot open a handed-back credential: there is no key on our side to open it with.
- The completion link sent to your IT desk, who have no account with us. It carries a server-minted token stored only as a hash, grants nothing but the ability to confirm that one request, and reveals no request contents on its own.
Auditing and monitoring
Every action that changes data writes an audit row: who did it, what they did, what they did it to, when, and from which IP. That log is visible to you in your own activity page on every plan — it is not a premium feature and not something you have to ask us for.
Sessions record their IP and browser so you can review and revoke active devices from your profile — Profile → Active sessions, where signing one out kills it on that device's next request rather than whenever its token happens to lapse. The audit log keeps 90 days; that window is set by us and applies to every account alike.
Infrastructure and subprocessors
Everyone who can touch data on our behalf, and exactly what they touch.
| Provider | Purpose | Data involved |
|---|---|---|
| Vercel | Application hosting and content delivery | Everything transiting the app, plus request logs and IP addresses |
| Neon | Managed PostgreSQL database | All account data and customer content stored by the service |
| Resend (using Amazon SES) | Transactional email — verification, invitations, password resets, and delivery of completed requests to your IT desk | Recipient addresses and the contents of those messages |
| Upstash | Rate limiting on sign-in and other sensitive endpoints | Counters only, keyed by an irreversible digest — no email address or IP is stored |
| OpenAI | Generating a draft request form from a description, when you use that feature | Only the description you type and your resource catalog names. No employee records or filed requests are ever sent |
| Stripe | Subscription billing | Billing contact and payment details, which are collected by Stripe directly — Embaro never receives card numbers |
Hosting and data storage are in the United States. If you are in the UK or EU, that is a transfer outside your region and we rely on standard contractual clauses with our providers. We do not sell data, we run no advertising trackers, and we set exactly one cookie — the one that keeps you signed in.
On the AI form builder: it is optional, and it receives only the description you type plus the names in your resource catalog. Employee records and filed requests are never sent to it, and nothing is used to train models. If you would rather not use it at all, simply don't — the form builder works entirely by hand.
Retention, deletion and export
While you are a customer, your data stays. When an account lapses — an unconverted 5-day trial, or a canceled subscription — it becomes read-only, and after 14 days (30 for IT-provider accounts, because deleting one affects their clients too) the organization and everything in it are permanently deleted. We email before each step.
Deletion is a real delete, cascading to users, requests, employee records, resources, forms and sessions — not a flag. You can also ask us to delete sooner at any time.
Three things delete themselves, on a daily schedule, with no human reviewing them first. Stated plainly because you should plan around them rather than discover them:
| What | When | Recoverable? |
|---|---|---|
| A lapsed organization, entirely | 14 days after it locks (30 for IT providers) | No |
| Audit log entries | Older than your retention window (90 days by default) | No |
| Expired sign-in sessions | Once past their 30-day life | Not applicable |
An unopened credential handover looks like a fourth but isn't: its ciphertext is destroyed on the timer while the record survives, so the request can still show that it was issued and never collected.
For IT providers, the first row cascades. Deleting an MSP account deletes every client organization inside it and all of their data. Those companies have no agreement with us, so keeping the account current is what protects their records. We email their administrators directly ahead of the date, but that is a courtesy, not a substitute.
None of this can be reversed or selectively restored from a backup on request. Backups exist for our own disaster recovery and age out on our providers' own cycles. Export before you lapse — and note that exporting still works during the read-only period, which is exactly what that period is for.
You can export your form, your resource catalog, your employee directory and every request you have filed from their own pages — the requests come out as one spreadsheet, and any single one also downloads as a PDF. Nothing is held hostage, and none of it is behind a paid plan.
Compliance: where we actually stand
Stated as facts, including the unflattering ones. Nothing below is aspirational.
- GDPR / UK GDPR
- Addressed. We act as your processor for the employee data you enter, and our Data Processing Agreement — structured on the Article 28(3) checklist — applies automatically to every customer and is binding on us as published. The page is the agreement; there is no separate copy to execute.
- PCI DSS
- Out of scope by design. Card details are entered on Stripe-hosted pages and never reach our servers, which is the SAQ-A model. Stripe is a PCI DSS Level 1 service provider.
- HIPAA
- Not a BAA-covered service. See the section below — the answer is more useful than a yes or no.
- SOC 2 / ISO 27001
- Not certified. We are a small, young company and have not undertaken either audit. If your procurement process requires one, we would rather tell you now than waste your time.
- Independent penetration test
- Not yet commissioned.
- Cyber insurance
- Not in place.
HIPAA, specifically
Asked often enough by healthcare employers to deserve its own answer.
The useful question is not “is this vendor HIPAA compliant?” but “does protected health information go into it?” For Embaro used as intended, it does not — and there is a specific reason.
HIPAA's definition of protected health information expressly excludes employment records held by a covered entity in its role as employer (45 CFR 160.103). A hospital using Embaro to onboard a nurse is processing employment data — name, work email, department, system access — not patient information. That falls outside PHI whether or not the employer is a covered entity.
So the honest position is: we do not offer a Business Associate Agreement, and you should not put PHI into Embaro. Don't paste patient details into a request note; don't build a form field that collects them. Used for what it is for, no BAA is required because no PHI is involved.
This page is our written position on it. It is deliberately specific so your compliance team can assess it directly, without a call.
What we do not have yet
Here so you can weigh it, not buried so you discover it later.
- No SOC 2 or ISO 27001 certification, and no third-party penetration test.
- No Business Associate Agreement, and no contractual uptime SLA. Neither is available on request — if you need a formal availability commitment, Embaro is not the right fit today.
- No customer-managed encryption keys, SCIM provisioning, SAML, or IP allow-listing. Single sign-on is Google and Microsoft via OIDC only.
- No data residency choice. Hosting is in the United States for all customers.
- No bug bounty program, though reports are welcome and taken seriously — see below.
If any of these is a hard requirement, we would rather lose the deal honestly than win it and disappoint your auditor.
Reporting a vulnerability
Email privacy@embaro.app with the details and we will acknowledge it. We will not pursue anyone who reports a genuine issue in good faith, gives us a reasonable chance to fix it, and does not access, alter or retain other customers' data while investigating.
If we discover a breach affecting personal data, we notify affected customers and any regulator we are required to notify, without undue delay.
This page is intended to be complete enough to answer a security review on its own. Related reading: the Privacy Policy, DPA and Terms.