Security and data

This page is for the person who has to sign off on inletAP — a controller, an owner, or whoever in your company reads security questionnaires. It describes what the product enforces, what it keeps, and what it does not have. The marketing-level summary lives at /security; this is the version with the caveats left in.

Separation between customers

Tenant scoping is applied at the query layer. The workspace is taken from your session, never from a parameter in the request, and every read and write is bound to it before it reaches the database.

The distinction matters more than it reads. A product that filters by workspace in the interface is one forgotten filter away from showing you somebody else's invoices. A product that binds the workspace below the interface cannot answer a question about another workspace at all, however the request is phrased. An identifier belonging to another customer comes back as not found, which is also the honest answer: as far as your session is concerned, it does not exist.

Separation inside your workspace

Legal entities are modeled explicitly, not approximated with a naming convention on properties. This is what keeps an owner's books apart from a joint venture's when both run through the same AP queue and the same team. One caveat worth having before you sign off: creating and editing entities, and pointing an entity at a ledger company, is open to every internal role today rather than to Admins only. The edits are recorded — each one writes an audit row naming the person and the ledger company before and after — so the control is a record rather than a permission.

Roles separate the work rather than ranking the people, but be clear about what they do not do: editing an invoice is not restricted by role at all, so the roles on their own never stop the person who corrected a total from approving it. The control that does is separation of duties, a workspace setting that is off until an admin turns it on in Settings → Approval policy. With it on, a person who materially edited an invoice — the amount, subtotal, tax, currency, invoice date, due date, invoice number, the vendor, the property it is coded to, or its split — or who edited a printed line item, or who sent it for approval, cannot record an approval on it. Somebody else has to, admins included. It is decided per invoice from the audit trail at the moment of approval, and it sits on top of the amount bands, which already require that many distinct people. See roles and permissions for the matrix, and approval tiers for the amount bands layered on top.

Quarantine

Quarantine is a policy hold. A rule can quarantine a document — an unrecognized sender address, a keyword, a vendor, an amount, the property, or the intake mailbox it arrived at — and the document stops there instead of entering the coding pipeline. Those six are the whole condition vocabulary; there is no attachment-type condition today.

It is deliberately not the same thing as filtered. Filtering is a routine judgment that an email was not an invoice, and it is reversible with one action. Quarantine is an exception someone is expected to look at. Conflating a newsletter with a suspicious attachment would make both harder to reason about, and would train your team to clear the queue without reading it.

Quarantined documents are visible and searchable. Nothing is silently dropped, which is the failure mode that actually costs money in AP: an invoice that vanishes is worse than one that stops somewhere awkward.

Encryption and mail handling

Traffic is encrypted in transit, and stored documents and database contents are encrypted at rest using the cloud provider's managed keys. Connector credentials get a second layer: they are encrypted by the application before they are stored, with a key we hold separately.

Inbound mail is received by our own mail infrastructure rather than a third-party relay, so raw messages are not sitting with an intermediary before we store them. Accounting-connector credentials are held as ciphertext, never returned by the API and never written to logs; disconnecting a connector revokes the grant at the provider first and then clears the stored tokens.

Retention

DataKept for
Invoice documents, extracted fields, coding and audit recordsAs long as your workspace is active — they are your accounting record
Raw inbound email objects90 days. Your setting accepts 30 to 3,650 days, but storage removes the original message at 90 whatever you set — see below
A spreadsheet uploaded for an importUntil that import is committed or discarded, and never more than 7 days
Application logs30 days

The 90-day expiry on raw messages is worth understanding rather than skimming. The invoice document, its extracted text, its fields and its whole audit history survive; what ages out is the original MIME envelope in object storage. In practice that means you can always answer "what did this invoice say and who touched it", and after three months you can no longer re-download the exact bytes of the email that carried it.

The uploaded spreadsheet is the row worth a sentence of its own. An import previews before it writes, and the preview has to be correctable — you change which of your columns feeds which of our fields and the preview is rebuilt — so the file you uploaded is held, rather than asked for a second time. It is your data while it is there: supplier names, addresses and tax numbers. It is cleared the moment the import is committed or discarded, and a preview nobody ever finishes does not keep it either: seven days after the upload the preview expires and the file goes with it, swept hourly so the seven days is the worst case and not the typical one. The preview's own record survives — which file was uploaded, when, by whom, and what each row would have done — because that is the answer to "where did these three hundred buildings come from", and it holds nothing the workspace does not already hold. See importing your data.

The 90 days is two numbers that happen to agree, and only one of them is yours to move. The retention window for raw inbound email is a per-workspace setting under Data & privacy in the left-hand navigation: any value from 30 days to 3,650, and 90 until an admin changes it. The object-storage lifecycle is not a setting, and it removes the original message at 90 days whatever the window says. So shortening the window works exactly as it reads, and lengthening it keeps the record rather than the bytes — the caveat is printed beside the control rather than hidden here.

Getting your data out, and deleting the workspace

Both are self-service, on every plan including the free one, and neither needs a ticket.

The workspace archive. An admin asks for it under Data & privacy in the left-hand navigation and gets a ZIP containing, for every table we hold: data/<table>.ndjson and data/<table>.csv. Alongside them are the original invoice files, filed by vendor and date, a MANIFEST.json, a README.txt and a COVERAGE.md. The coverage report is the part worth knowing about: it counts what went in, names what was left out and why, and stamps the archive COMPLETE or INCOMPLETE. If records exist that nobody has classified yet, it says so and holds them back rather than guessing. Builds are throttled to five an hour and the download link is live for seven days; you can ask for another whenever you like.

Your own copy, whatever your role. A data-subject access request belongs to the person, not to the workspace, so every role can ask for their own archive from the same screen — including an outside approver who can see only one building. No capability gates it and no plan gates it.

Deleting the workspace. An admin types the workspace's name to confirm — a checkbox is too easy to click without reading which workspace is on screen — and the deletion is then scheduled with a seven-day grace period in which any admin can cancel it. It is refused with a conflict while an archive is still building, so a deletion cannot outrun the copy you asked for. After the grace period the rows, the stored files and the sign-in accounts go. Two things are kept and are named on the screen before you confirm: Stripe billing and tax records, for the six years Canadian tax law requires, and a record that the deletion happened, for 24 months, so that it can be proved to you or to a regulator.

If you have a specific retention obligation the window does not cover, tell us what it is and we will confirm in writing whether we can meet it.

Reliability, since it is a security question in disguise

An AP pipeline that loses a document quietly is a control failure, not an outage. The guarantees that matter here:

  • A job that fails repeatedly stops and is recorded as failed with its error, rather than being retried forever or dropped. The document keeps its status and stays visible in the queue it was in, so a stalled invoice is findable rather than lost.
  • Pipelines are idempotent: a retried job cannot produce a second document or a second bill.
  • A transient failure at the mail edge returns a temporary error so the sender retries, rather than accepting mail we cannot process.
  • Export items record the external identifier the ledger gave them, so a retry recognizes the bill that already exists and skips it instead of posting a second one.

What inletAP does not have

inletAP is an early product and does not hold third-party security certifications. There is no SOC 2 report, and we are not going to describe the position as "SOC 2 ready", because that phrase means nothing and is generally deployed by people who know it means nothing.

Also absent, and worth knowing before you buy:

  • No payment rails. inletAP produces approved, coded bills. Money moves wherever it moves today.
  • No native property management system connector, and none for AppFolio, Buildium, Yardi or Rent Manager. The CSV export is configurable enough to load into any of them, but you define the columns yourself — there is no ready-made template per destination.
  • No public API, no API keys and no outbound webhooks. Everything above is done from the app by a person; none of it can be scripted.
  • No dedicated audit-trail export. The trail is in the workspace archive, and the Audit Log screen exports the rows it has on screen, but there is no server-side "export the whole audit log" job.
  • No self-serve single sign-on. There is no SAML or OIDC federation you can configure yourself, and no screen for it: on Pro and Enterprise we set single sign-on up with you, by hand, per workspace. If it is a procurement requirement with a date attached, ask us before you buy rather than after.

What we will do is complete any security questionnaire honestly and tell you which controls are implemented and which are planned, without blurring the two. If an audit report is a procurement requirement for you, that is a real reason not to buy yet, and we would rather you found out on this page than in week three.

Where to go next

  • Audit trail — the append-only record behind most of the claims above.
  • Roles and permissions — the matrix, and the separation-of-duties setting the roles do not provide on their own.
  • Invoice statuses — where quarantined and filtered sit in the pipeline.
  • Plans and limits — allowances, held documents and what is counted.