Legal

Security & Trust

Last updated: 2026-08-15

This page explains the security measures Notavia operates, what the evidence for each one actually is, and which measures are still intentions rather than operating controls. It is not a certification, audit report, penetration-test report, or guarantee.

Two words are used deliberately throughout. Source-evidenced means the control is implemented in the reviewed application source; it says nothing about whether it is running in production. Deployment-evidenced means the control was measured on the production deployment and the measurement is recorded. Everything else is stated as an open gate, with what would have to be produced to close it.

For Customers whose processing is covered by our Data Processing Agreement, the binding technical and organisational measures are the separately versioned measures in DPA Schedule 2. This page does not silently amend an accepted DPA.

Deployment Status

Notavia is deployed. The managed service runs on a dedicated Hetzner server in Falkenstein, Germany, and the application, its PostgreSQL database, the administrative console and the log store all run on that single host.

The managed service is not yet publicly reachable, and there are no Customers. This website and the documentation site are served from that same host and are now reachable from the public internet. The service itself is not: the application, its API, the preference centre, the tracking endpoints and the operator consoles are refused at the edge unless the request arrives over our private network, and the connection is closed without a response rather than answered with an error.

One exception is deliberate, and it is the only one. A single payment-provider webhook path is answerable from the public internet, because the payment provider has to be able to deliver to it from its own infrastructure. Nothing else on that hostname is. That endpoint authenticates every request by signature and fails closed on each path: an unconfigured signing secret is refused rather than trusted, an absent or invalid signature is rejected, and a timestamp check bounds replay. It carries no Customer Personal Data today because no Customer exists.

Making the rest of the service publicly reachable is a separate, deliberate act that has not been taken. The operator consoles are additionally held at the socket level, bound to the private address rather than to all interfaces, so that a mistake in the edge rule alone does not expose them.

Two consequences follow, and both matter when reading the rest of this page. First, controls that can only be evidenced against real traffic, real Customers, or a public attack surface are not evidenced, and are stated below as gates. Second, no Customer Personal Data has ever been processed by this deployment, so no Customer has relied on any measure described here.

What is Operating

Hosting and location

Deployment-evidenced. The production host is in Falkenstein, Germany, inside the European Union. The database is not a managed third-party service; it runs on the same host as the application.

Transport security

Deployment-evidenced. Public certificates are issued automatically over ACME using DNS-01 validation, and issuance was verified from an independent machine over public DNS with default certificate verification — that is, the whole chain from name resolution to certificate validation, not the server's own opinion of itself. The edge terminates TLS. The database, the administrative console and the log store publish no public port.

The application source emits content-security, anti-framing, content-type, referrer, permissions, cross-origin-opener, and HTTPS-only HSTS headers. That is source-evidenced and covered by tests. Equivalent content-security and frame-ancestors policies are configured for the non-application hostnames at the edge, but we have not verified that they are being served there, and a policy that is fully wired and silently inert is a failure mode this project has already met more than once — so it is listed here as configured, not as operating. A response-header check against each hostname is what would close it.

Outbound mail transport

Deployment-evidenced, including its limit. Mail sent through the managed sender uses opportunistic STARTTLS: the connection to the receiving server is encrypted where that server offers encryption, and delivery is not refused where it does not. That is a deliberate setting rather than an oversight. Enforcing TLS would convert a receiving mail server's outdated configuration into a bounce, and bounces feed suppression, so enforcement would silently and permanently block legitimate recipients whose own providers are behind. TLS is hop-by-hop in any case, so no configuration of ours can promise encryption on every hop to a Recipient.

Sender authentication is verified rather than assumed: SPF, DKIM and DMARC all pass and both align, read from a receiving server's own message headers rather than from a sending console. That measurement was taken on live messages sent through the production system-email credentials. Both sending identities carry the same DKIM signing and the same custom envelope domain, so the result applies to the managed sender too — but it was not separately measured on a managed send, and the distinction is recorded rather than smoothed over.

Identity, authentication, and authorization

Source-evidenced. Account passwords are handled by ASP.NET Core Identity. The application does not store plaintext passwords and exposes no function that recovers an existing password. Users can enable authenticator-app TOTP multi-factor authentication; MFA is not mandatory for every Customer or operational account.

Sign in with Google is available on the production login page. Where a Customer's user signs in that way, the identity rests on the verified email address the provider asserts, which means the security of that Google account becomes part of the security of the Notavia account.

Application access uses organization roles. API keys are generated from cryptographic randomness, stored as SHA-256 hashes, scoped by environment and permission, and revocable.

Tenant isolation

Source-evidenced and test-evidenced, not production-exercised. The application applies organization and, where relevant, environment query filters to tenant-owned data. Tenant-context checks fail when required tenant context is absent, and focused isolation tests cover representative cross-tenant routes. These are application-layer controls. They are not an independently audited isolation boundary, and because the deployment has never held more than one organization's real data, no production isolation exercise has been performed.

Logs, monitoring, and alerting

Deployment-evidenced, with stated limits. Application logs and traces are collected to a log store that runs on the production host and is reachable only over the private network. They are not exported to a third-party log processor, which was chosen deliberately: application logs carry organization identifiers and Recipient addresses, and exporting them would place a third party in the processing chain. Log retention is configured — 30 days for application logs, with a shorter 3-day window for high-volume database-polling noise.

The application also emits metrics, but no production metrics backend is configured, which is why operator alerting evaluates database state directly instead of metrics.

Four operator signals run every five minutes in production — failed sends, webhook delivery backlog, permanent webhook failures, and past-due subscriptions. They were confirmed to be reaching an operator by observing the delivery response, not by the absence of complaints.

A separate outbound heartbeat is intended as a dead man's switch: it is sent as the last step of a successful alerting run, so if the process, the container, the scheduler or the database fails, the pings stop. What is evidenced is the sending of that heartbeat, not the alarm. Whether the external check receiving it is currently armed is operator-maintained state that we have not independently verified, and a paused check never alerts — so this page does not claim that the absence of a heartbeat currently raises an alarm. Confirming the check is active, with its period and grace recorded, is what would close that.

The limits are as important as the controls. These are service-health signals, not security detection: there are no security-event detection rules. There is no external uptime monitoring, because that requires a publicly reachable service. No staffed on-call rota exists. One alert route shares fate with the email channel it may need to report on. Audit data is not append-only or tamper-evident, and direct administrative reads of the database are not comprehensively captured in product audit logs.

Backups and restore

Deployment-evidenced. A scheduled nightly job dumps the entire production database, compresses it, validates the artifact itself rather than the exit status of the command that produced it, and uploads it off-site to object storage. A failed run alerts an operator rather than passing silently.

The off-site bucket was created with a European location hint. That hint is best-effort and is not a residency guarantee; no storage jurisdiction is contractually verified, and the credentials the production host holds cannot read the bucket's own settings to confirm where the objects sit. We state the hint because it is what was requested, not because it is proof.

Two of the three unverified facts on this page name the check that would close them, and this one did not. It does now, and it takes two steps because one is not enough. An account-scoped read of the bucket's own settings, which the production host's object-scoped credentials cannot perform, recorded as evidence of what the provider's account reports. Then a contractual data-location commitment from the provider for that bucket. The read alone narrows the uncertainty without closing it — a hint read back from an account is still a hint — so it is the commitment that closes this, and until both exist the sentence above stands as written.

A restore has been rehearsed from the off-site copy — the copy that survives losing the host — into a scratch database, with the real production image booted against the restored data and every outbound credential blanked. Blanking is not a formality: a restored dump contains queued work, so an application booted against it believes that work is still pending and is one scheduler tick from re-sending real messages.

A dump is never edited. Deleting a record from the live database therefore has no effect on a dump that already exists; the record leaves the backup set when that dump ages out. Each copy is kept at least 14 days, by a different mechanism. The copy on the production host is pruned by age by the backup script, on the first nightly run at which a dump is more than 14 whole days old, so in practice on its fifteenth day. The off-site copy is not pruned by the production host at all: a bucket-level retention lock with a 14-day age, combined with a 14-day lifecycle rule, refuses both deletion and overwrite of an object and then expires it, and that expiry is carried out by the storage provider at a moment we do not control.

The production host consequently cannot delete or overwrite an off-site backup. That immutability is a deliberate control against ransomware and against a compromised host, and its cost is stated rather than hidden: a deletion cannot be reached into a backup and applied early.

Fourteen days is the floor on how long we keep a backup, not a deadline by which a deletion clears one. A record deleted from the live database is absent from the whole backup set only once every dump containing it has aged out, which is about 15 to 16 days after the deletion, and longer if a nightly run is missed or the provider's expiry lags. We do not publish a shorter figure.

Two limits remain, and they are stated as limits.

  • No restore has ever been performed into production, as opposed to into a scratch database.
  • No deletion has ever been replayed through a restore. There is no evidence that a restored copy would be returned to a state consistent with deletions made after the backup was taken.

No recovery point objective and no recovery time objective are published. Backups are nightly, and because no restore into production has been performed, no recovery time has been measured. A published objective that has never been rehearsed would be a number, not a commitment.

What is Not Operating

Each item below is a gate. It states what is missing and what would close it.

Encryption at rest

Connected-provider secrets supported by the reviewed code are protected at the application field level using ASP.NET Core Data Protection. Deployment configuration supplies other application secrets. Beyond that, this page does not claim encryption at rest. No full-disk, database-level, or Tessora-controlled object encryption has been evidenced for the production host or for backup artifacts, and the source does not establish who controls a production data-protection key, how it is backed up, or how it is rotated. Closing this requires a recorded encryption configuration for the host volume, the database and the backup objects, plus a key-control, rotation and recovery record.

Privileged access

Administrative access to production is standing rather than just-in-time, and it is manually granted. Administrative interfaces are not reachable from the public internet and require an operator privilege that no ordinary account holds, and denial was verified before the privilege was granted rather than only after. But no least-privilege review, approval record, expiry, revocation record, enforced operational MFA, or comprehensive privileged-read log exists. Closing this requires an approved access model with grant, read, export and revocation records, and a periodic review.

Vulnerability scanning and patching

The current CI workflow contains a blocking known-vulnerability check for direct and transitive NuGet dependencies in the shipped application project, followed by project-scoped automated tests. There is no equivalent evidence for container images, base images, operating-system packages, the production host, dynamic application scanning, or infrastructure scanning, and no production patch cadence or emergency-patching record has been produced. Closing this requires scanning coverage for each of those layers together with a risk-based remediation record.

Incident operation

The classification, assessment and communication procedure below is written and was table-topped against the source, the configuration and the deployment. What has not happened is an exercise against a running service: no security incident, personal data breach notice, administrator-access request or restore into production has been carried out. There is no restricted immutable case store, no evidence of private-notice delivery, and no staffed rota. Closing this requires an exercised end-to-end incident, with the case record and delivery evidence retained.

Independent assurance

Notavia has not commissioned or supplied a Tessora SOC report, ISO 27001 certificate, independent security audit, or independent penetration-test report. No such work has been performed at all, so there is no report to withhold. Vendor certifications certify those vendors; they do not certify Tessora or Notavia. Closing this requires commissioning the work and publishing that it happened.

Incident and Breach Communications

A service incident is an availability or performance event. A security incident is an event that may affect confidentiality, integrity, or availability. A personal data breach is a security incident involving accidental or unlawful destruction, loss, alteration, unauthorized disclosure of, or access to personal data. One event can fall into more than one category.

Generic availability information may be posted to the status page. The status page will not identify a Customer, affected person, confidential investigation detail, exploit path, or personal data. It is not the contractual channel for a security incident or personal data breach.

For a confirmed personal data breach affecting Customer Personal Data, Tessora will notify affected Customer organization Owners and Administrators through a private security route without undue delay and in any event within 72 hours of confirming the breach, and provide available information in phases. That bound is contractual: it is DPA section 10.

No acknowledgment clock is promised, and that remains deliberate rather than an omission. The distinction is worth being precise about. A notification bound is a commitment about something Tessora controls once it knows — writing to the affected Customers. An acknowledgment clock would be a commitment about how fast a person answers, and no rota is staffed to keep one, so publishing it would be publishing a number we would miss. Customers remain responsible for their own controller notifications; where GDPR or UK GDPR applies, a controller may need to notify its competent supervisory authority within 72 hours after awareness where the breach is likely to risk individuals' rights and freedoms, and affected individuals without undue delay where high risk is likely. Tessora separately assesses any duty it has as controller for its own processing.

Every suspected personal data breach must be recorded with the known facts, effects, assessment, decisions, notices, evidence, and remedial action, including a documented reason when a regulator or individual is not notified. The current procedure is documented in the internal security evidence register. Operator alerting for selected service-health conditions now runs in production and reaches a person, but private-notice delivery, evidence capture, breach-register operation and post-incident review have not been exercised against a running service.

Reporting a Vulnerability

Report a suspected vulnerability to security@saas-infrastructure.com. Include the affected service or URL, a concise impact description, reproducible steps, and any supporting evidence that can be shared lawfully. Do not include unnecessary personal data, access other Customers' data, disrupt the service, use denial-of-service testing, or publicly disclose an unresolved issue in a way that increases harm.

Reports are triaged according to the evidence and potential impact. We may ask for more information and will coordinate remediation and disclosure where practicable, but we do not promise an acknowledgment or remediation time that is not staffed and measured. We do not currently publish a /.well-known/security.txt file or offer an encrypted submission channel. No paid bug-bounty program is offered.

What This Page Does Not Claim

Stated together so that a reader does not have to infer a claim from a silence:

  • no certification, independent audit, or penetration test — none has been performed;
  • no encryption at rest below the application field level;
  • no off-site backup residency guarantee. A European location hint was specified; it is best-effort, it is not a guarantee, and no storage jurisdiction is contractually verified;
  • no dead-man's-switch alarm. The heartbeat is sent; the external check's armed state is not independently verified;
  • no verification that the edge content-security policies are live on the non-application hostnames;
  • no verification of Customer-selected connected-provider transport routes;
  • no acknowledgment, response, or remediation clock. A breach-notification bound does exist — 72 hours from confirmation, in DPA section 10 — and is the one clock on this page;
  • no staffed on-call coverage and no security-event detection;
  • no recovery point objective and no recovery time objective;
  • no restore into production and no deletion replayed through a restore;
  • no independently audited or production-exercised tenant-isolation boundary;
  • no scanning coverage beyond the dependency gate described above;
  • no public general availability of the managed service at the time of writing;
  • no representation that a measure evidenced on a non-public deployment will behave identically once the service carries public traffic.

Governance and Contact

The role-based Owner approved this evidence-bounded page and accepted the current unavailability of qualified legal review as a launch risk. Qualified counsel has not approved it. Tessora has not appointed a Data Protection Officer, an EU representative, or a UK representative.

Security incidents and vulnerabilities: security@saas-infrastructure.com

Privacy and data-protection questions: support@saas-infrastructure.com

See also the Privacy Notice, DPA, Data Transfer Addendum, and Subprocessor and Third-Party Service List.