TALLWRIGHT - TECHNICAL AND ORGANISATIONAL MEASURES Version toms-1.0. In force from 2026-09-12. Replaces: nothing. This is the first version. The SHA-256 of this file, with CRLF normalised to LF, is published at https://tallwright.com/legal beside this version. Annex B to dpa-1.0, the Data Processing Agreement. English is authoritative, as clause 0.5 of the Terms provides; capitalised terms mean what terms-1.0 and dpa-1.0 say they mean. Kyoomee GmbH, Grazer Strasse 1/3, 8120 Peggau, Austria. FN 682788a, Landesgericht fuer Zivilrechtssachen Graz. Security reports: hello@tallwright.com 0. Scope 0.1 No measure beyond those listed is claimed. What is absent, partial, or in force on one host type and not another is stated in the same voice as the measures in force, under "Not in place" or in the clause it qualifies. A control we have not verified at a provider is neither claimed nor denied, and no absence says the missing measure is unnecessary. 0.2 Measures are stated per host type and per Edition. The file enforcing each is in the evidence pack (13.3), not here. 0.3 Host types. Witness Host: countersigns Archive heads. Fleet Host: records hosted Archives. Receiver Host: receives Managed reports; with the Fleet Host, the installed hosts. All three are Hetzner vServers, read from the provider's metadata service on 12 September 2026: Witness and Fleet separate machines in Falkenstein, Germany (fsn1-dc8), Receiver in Helsinki, Finland (hel1-dc2). The Backoffice is none of them: server code in Frankfurt (Vercel fra1), store in Neon Postgres in AWS Europe Central 1; for Vercel and Neon the legal entity and parent domicile are not verified by us. 0.4 Per Edition. Cloud: all of this is ours, but for 11.3. Managed: the Receiver and Witness Hosts are ours, one component of ours runs read-only on your machine (4.2, 5.1's last sentence), and 1, 5 but for that sentence, 7.1 to 7.3, 9.2, 10.1 and 12 are yours for the recording machine; 3.1 and 4.1 describe our Fleet Host and do not apply. Self-Hosted: the same sections are yours, nothing of ours runs on your machine, and the Witness Host - 1.2, 2.2, 5.1, 5.3, 7.4, 7.5, 8, 9.2, 10.2, 12.2 - stays ours. Witness: that host alone, in those clauses. Backoffice clauses apply where there is an account; a section naming no party for your Edition does not apply. 0.5 https://tallwright.com/legal lists this annex and the other three documents, each with its SHA-256 beside it, computed from the bytes served. The apply screen links the Terms and the Data Processing Agreement, shows both digests, and offers acceptance only through a control naming both, before anything is signed or sent; this annex is incorporated by name and URL rather than by digest (dpa-1.0 clause 0.6). The account-creation screen links the documents and says where acceptance happens; it records none. 1. Encryption at rest, and key handling 1.1 Where an Archive holds record content, payloads are encrypted with AES-256-GCM under a key per data subject, the plaintext's content address bound in as additional authenticated data; a ciphertext moved to another record does not open. 1.2 Key files are tightened to mode 0600 in a 0700 directory on every open, and the key database runs with secure delete on. The tightening is attempted, not enforced: where the host refuses it - a foreign-owned restore - the Archive still opens and the check reports the mode. The witness signing key is written 0400, never copied off the Witness Host, never backed up (10.2), held in no hardware security module. 1.3 The read and operate tokens we hold for your fleet are sealed with AES-256-GCM under a key held only in the deployment environment, never in the database. Fleet Host credentials are kept as SHA-256 hashes, compared in constant time. 1.4 Not in place: any hardware security module, key management service or full-disk encryption on any host, so per-subject keys sit unwrapped on the volume holding the ciphertext they open - which is why the content-holding hosted shape is not offered (11.2); a rotation path for the key sealing your credentials; and any claim over at-rest protection of the Backoffice store, its provider's measure, unverified by us. 2. Encryption in transit 2.1 Every public edge of an installed host terminates TLS, sends Strict Transport Security, a default-src 'none' content policy, nosniff and no-referrer, and strips the Server header. Certificates come over ACME from the configured issuers (Let's Encrypt, with ZeroSSL the fallback in its default chain), and no issuer is pinned. 2.2 The Witness Host's listener requires TLS 1.3 or better, with a chain self-signed on purpose. Fleet-to-witness traffic is pinned to the witness's public key, compared in constant time before the first request byte; authority and hostname validation are off there deliberately, so no public authority can authorise a substitute witness. 2.3 Not in place. The Backoffice sets X-Frame-Options DENY, no-referrer and nosniff, and no content policy or Strict Transport Security of its own. Whether TLS to its database is verified depends on the connection string. 3. Separation of one customer from another 3.1 On a Fleet Host the kernel separates customers in every process that serves them: one system user per customer, no login shell, an Archive directory created 0700 and owned by that user, each unit running as that user with writable paths limited to that directory under ProtectSystem=strict. 3.2 It does not reach the nightly backup, which runs as root across every customer's directory and writes all into one repository under one password (10.1). 3.3 Separation is checked on the running machine in both directions: every cross-customer request on all three credential doors refused, each customer reaching its own Archive. It is run by hand and needs two customers' credentials, so the first customer is told a host is ready before it can run. It gates no change; we run it again at each review (13.2). 3.4 In the Backoffice the database enforces it: row-level security enabled and forced on every table holding an account's data, policies comparing the row's account to a transaction-local setting, an unset setting resolving to nothing, so a forgotten scope reads no rows. Six tables belonging to no account deny every row and are reached through a privileged door, and so does a seventh that belongs to one, the applications table; the migrations table carries no policy. It rests on one enforcement point, since the role the application connects as may bypass the policy: not defence in depth. 4. Access control and least privilege 4.1 A hosted Archive is reached through four doors, four processes, four credentials: recording appends and cannot list; read has no write method; operate creates and closes Archives and reads no records; handover is a capability valid once, for fifteen minutes. Provisioning is the only path to root, through one sudoers line for one command. 4.2 There is no staff login, no impersonation and no cross-account surface in the Backoffice. The read door never returns a subject identifier: the subject lives in a key store it never reads. On Managed the component on your machine reads only - it cannot open an Archive and writes nothing. 4.3 Only an Owner appoints an Owner; no seat changes its own role; an Auditor is refused every write on the Archives door. The role is read from the membership row on every page, and removing a member revokes their sessions at once. 4.4 Not in place. An Auditor's scope - this Archive and nothing else - is stored on the seat, shown on the team screens, offered in the invitation, and enforced nowhere: a scoped Auditor sees the account's Archives. The two routes that provision this account's fleet and submit its signed application check only that a session exists, so any seat reaches them. 4.5 Administrative access, outside the four doors. Two natural persons hold SSH to the three hosts by named key, with the sudoers line in 4.1 the only path to root; the Backoffice database connection string, used by a build step for migrations; and the accounts at the hosting, database, payment, mail and DNS providers. That access is bound neither by 3.4 nor by 9.1's insert-only privilege. Not in place: change authorisation for host access, periodic review of these holders, key custody and rotation, and any claim about a second factor at those providers. 5. Host hardening 5.1 The four doors on a Fleet Host, its anchor timer, the two Receiver Host doors, the witness daemon and the admissions collector run in a systemd sandbox: no capabilities, no new privileges, ProtectSystem=strict, private tmp and devices, restricted namespaces, MemoryDenyWriteExecute, a system-call filter, umask 0077. The units outside that set are named here. The provisioning door bounds no capability, sets no NoNewPrivileges and runs under ProtectSystem=yes: the sudoers line in 4.1 is the privilege it exists to acquire. The backup units hold CAP_DAC_READ_SEARCH, the telemetry unit runs umask 0027, and neither they, the backup checks nor the Witness Host's alarm and clock-check units set MemoryDenyWriteExecute; all of those but the Fleet Host's backup unit also set no restricted namespaces and no system-call filter. The append-only applier holds CAP_LINUX_IMMUTABLE, and 7.7 says it is not installed on a hosted fleet. The reporter unit on your own machine sets all of that list but restricted namespaces, MemoryDenyWriteExecute and the system-call filter; it reaches no Archive path, writes nothing and opens no port. 5.2 On an installed host every application port binds to loopback and, where ufw is present, the firewall denies all inbound traffic except 22, 80 and 443; the recording port has no network access. An installer does not refuse a host without ufw, so there no firewall of ours is configured. The installers refuse two estates on one machine: the fleet installer beside a witness unit, the receiver beside either. 5.3 Not in place. The Witness Host's listener binds every interface on 8443, because the fleet must reach it, and no script of ours configures a firewall there. No host has patch automation and no installer hardens the SSH daemon, so port 22 carries the image's defaults. 6. Authentication and sessions 6.1 Production has two ways to sign in: a one-use link by e-mail, and a WebAuthn passkey. There is no password and no password store to breach. The code ships connectors for external identity providers; any we connect appears on the sign-in screen and in the sub-processor list. 6.2 Session cookies are signed with HMAC-SHA-256; every signed token declares its purpose and the verifier checks it before believing the payload, so a session cookie cannot be redeemed as a sign-in link. 6.3 Lifetimes: a session eight hours, a sign-in link ten minutes and single-use in the database, an invitation seven days, a provisioning claim five minutes. 6.4 Not in place. The rate limit on requesting a sign-in link is five in fifteen minutes per key, held in a map inside one process: no distributed rate limiting, no brute-force protection. 7. Integrity and tamper-evidence 7.1 Records are hash-chained: both lists written as one act, each record naming its predecessor's content address, so any later change to a recorded entry is detectable on verification. Appends are serialised across processes by a file lock. 7.2 The Archive remembers the greatest height it committed, in a file it only advances, so a shortened log is caught; the anchor command refuses a log shorter than one already countersigned. 7.3 A self-check runs over the two lists, the record chain, the access chain, the index, the payloads, the height mark, the anchors the witness says existed and recorded erasures; anchoring and export refuse on a finding. 7.4 Each customer's head is presented to the Witness Host fifteen minutes after the previous run for that Archive started, spread by up to two minutes, so a run never overlaps its predecessor; that is not a service level. The Witness Host is a machine we operate separately from the one that records: an organization other than yours, and on Cloud and Managed the same organization that runs the recording host (7.5, 13.4, 14.2). 7.5 The witness refuses a log declaring an operating organization equal to its own, at the door, at startup, when such an account is created, and in the admissions collector. It is a string comparison, which on Cloud compares your organization, not the fact that we run both machines. An exhibit in which we are both log operator and cosigner is never a demonstration of organizational separation. 7.6 Limits on use. A record of ours proves that the bytes named existed in this log at the height and time the witness signed, and no more: not who wrote them, not that they are true, not that anything outside the log happened. These limits are notified to you in advance for Article 13(2) eIDAS, by this clause and by the exhibit format specification, which we give on request. An exhibit does not carry them, and we claim no limitation of use against a third party who has not seen them. 7.7 Not in place. The kernel file flags that would make storage append-only are implemented and not deployed on hosted fleets: the applier unit is not installed, and no fleet sets the expectation that would make its absence visible. The account audit log (9.1) is append-only by privilege in our own database and is not countersigned by the witness. 8. Trusted time 8.1 The Witness Host's clock is chrony with NTS, authenticated, from four sources across Cloudflare, Netnod and the Physikalisch-Technische Bundesanstalt, verified with chronyc on the running host on 12 September 2026. An unauthenticated fallback is refused; the host serves time to nobody. A quarter-hourly check fails on a dead daemon, an unsynchronised clock or an unauthenticated source. 8.2 An anchor carries two times: the witness's own clock, inside the witness's signature; and an RFC 3161 token minted on the recording host itself, tagged as a local test authority, under a self-signed certificate created fresh on every run; that host's clock is covered by no measure here. 8.3 Kyoomee GmbH is a trust service provider within the meaning of Article 3(19) eIDAS and is not a qualified one. No legal presumption under eIDAS attaches to its time stamps, and a time stamp of ours does not meet the requirements of a qualified electronic time stamp. 8.4 Not in place. The Witness Host is provisioned from a written runbook, not an installer, so unlike the other two no script evidences its configuration. 9. Logging and monitoring 9.1 Logged. The proxy at each public edge of an installed host writes an access log to the journal. In the Backoffice an account audit log records what was done to an account, Archive, seat, passkey or payment, with the actor, and the role each request runs as may only select and insert, so no path can edit a row. Inside an Archive, search and query append a hash-chained entry before answering. 9.2 Not logged. The Witness Host's own port has no proxy: it learns the time a request arrives and the network address it arrives from, and records the address nowhere, its handler writing no request log. A direct read of records, a read of payload plaintext and the shipped disclosure command write no access entry, and a court export writes none, deliberately; in its place stands clause 8.4 of the Data Processing Agreement: we tell you of a demand unless the law binding on us forbids it, and then as soon as it permits. Access entries are unsigned, binding no actor to one. No application port on a Fleet Host writes its own request log; each door's credential travels in an Authorization header, and the proxy in front logs the request line without it. The one-use exhibit capability is the exception: it is the URL, so it reaches the journal for its fifteen minutes, nothing of ours bounds how long that line is kept, and only the holders in 4.5 read it. 9.3 Monitoring in place. Every unit declares an alarm unit on failure, which writes the failure to the journal at alert priority. The Backoffice polls every account's Archives every five minutes from outside the recording estate. 9.4 Notice to you goes out without undue delay and in stages and, where Article 19a eIDAS requires, to the supervisory body within 24 hours; both duties are in clause 21 of the Terms, and nothing technical holds either clock. 9.5 Not in place: paging, an on-call rotation, external uptime monitoring, a written incident procedure, and an alarm raised from outside the estate it watches. The alarm chain ends at a journal line and a mailbox, and every scheduler watchdog lives inside the thing it watches, so if the platform stops running both scheduled jobs no run reports anything. On Managed we detect silence, not a false report: the reported document is neither signed nor bound to the device. 10. Availability and resilience 10.1 Backups. On a Fleet Host every Archive on the host; on the Receiver Host only the Managed roster (per box, the hash of its key and the silence interval it is watched on), and never a receipt and never a telemetry document: a restored receipt would be a silence window the backup manufactured (10.3). Both go by restic to a storage service of Hetzner Online GmbH in Germany, reached over SFTP, encrypted on the host before they leave. A nightly run re-reads the snapshot list as proof, a daily check refuses on a newest backup 26 hours old, a weekly check reads five per cent back, and a run whose backup configuration is missing refuses rather than writing nothing quietly. We publish no evidence that a run has completed on either host. 10.2 Not in place. The repository is not append-only: the credential the host holds can delete what it wrote, and whether provider-side snapshots stand beneath it, under an account the host cannot reach, is part of provisioning the destination - nothing of ours verifies that they do, so none is asserted. Nothing of ours prunes snapshots. The Witness Host has no backup script, so its signing key and anti-equivocation state are never restored and no disaster-recovery commitment is made for it. The Backoffice database has no copy outside its provider - six hours of provider history, measured 11 September 2026. No restore has ever been rehearsed, on any host; a rehearsed restore, a copy of that store and a snapshot retention policy stand open in the project's register, undated here, and each one done is a correction under 15.2. 10.3 Three classes of state must never be restored as they stand: latched clocks, written once and never re-stamped; anti-equivocation state, which only moves forward, since a restore re-opens a closed window; and rows recording acts already taken, since restoring one undoes our knowledge of the act, not the act. 10.4 We restore only on your instruction or to recover from a failure, and we undertake to re-apply by hand an erasure you have already requested; there is no written procedure for that step, and a snapshot older than an erasure still holds the key it destroyed (10.2). Where the law requires it, or a court or an authority orders it, we may make an identified record inaccessible; we tell you what we did and why, and every proof over it stays intact. 10.5 No availability figure is given: no uptime percentage, no recovery time or point objective, no commitment to a time to restore. If the witness is unreachable, anchoring degrades rather than lying (a signed record of the attempt, every record retained, retried later), and no bound holds on how long a record stays unanchored. The one service-level figure is clause 3.7 of the Terms: for Managed, a reply within four hours, counted from when the Receiver Host recorded the report, on Styrian working days and hours. It applies once a box of yours is enrolled and reporting; the claim door on the deployed Receiver Host does not work yet, and no third party has enrolled a box. 11. Minimisation 11.1 The Backoffice stores no IP address and no location; the sessions table records neither, by a decision in the schema, and the caller's address serves only as a rate-limit key (6.4). It keeps the browser's user-agent string, up to 300 characters, so a person can tell their devices apart; no path deletes that row. An erasure record names content addresses, never the subject. These are measures of pseudonymisation and minimisation under Article 32(1)(a) GDPR; retention is in Annex A to that Agreement. 11.2 Custody is fixed when an Archive is created and no command changes it. Every Archive the product provisions holds hashes only and cannot be otherwise: the variable that would ask for a content-holding Archive is absent from the permitted environment of the provisioning door. Two Archives on the Fleet Host hold content, both ours, read off the host on 12 September 2026 (one holds Kyoomee's own records, one is an isolation probe), and your separation from them is the kernel separation in 3.1, with the exception in 3.2. 11.3 Not in place: anything that detects or removes personal data from what you record. In the tier-1 adapter the message fields and content-block types are an allowlist, so a provider's reasoning block does not reach the record; keys named as credential keys are replaced by a redaction marker in message content and tool-call arguments, with the path noted on the record; a tool result is sealed whole and filtered by nothing. The reasoning-key list is a default only in the HTTP adapter. What else a payload contains is your decision as controller; where an Archive holds content you declare what a subject identifier is, recorded without our verifying it. 12. Supply chain 12.1 On an installed host every third-party Python package installs against a committed lock file with hashes required, as in CI; our own packages install with no dependency resolution, no index and no build isolation, and the Node workspace installs frozen. 12.2 Not in place. On the Witness Host no shipped step installs third-party packages from a hash-pinned lock: its documented install places our own packages only. No continuous vulnerability scanning exists anywhere: no dependency-update bot, no audit, static-analysis or secret-scanning step in any workflow. 13. People, testing, and evaluation of effectiveness 13.1 Two natural persons are authorised to process personal data for you, both bound by the duty of data secrecy under Section 6 DSG, which needs no signature; that duty is clause 5.2 of dpa-1.0, and it is the answer to clause 5.1 today. 13.2 Before a change ships: an adversarial gate, a language gate, a supply-chain gate over the lock and the recorded advisory state (12.1), a check that every recorded mutation survivor still carries a triage reason, and a gate recomputing every published contract file's digest from the bytes served and holding the application's pinned list, the witness policy template and the notary runbook to the Terms' and the Agreement's digests, the two the witness pins; this annex is pinned by neither, being incorporated by name and URL. The sabotage run behind that record - tests required to fail when their code changes - is a nightly lane over the cryptographic core only and blocks no change. We review this annex yearly and on a material change of the processing or the risk. 13.3 On request: a completed security questionnaire, this annex, and for each measure the file enforcing it and, where one exists, the test holding it. A claim register grades 430 claims by what holds each (76 held by nothing, 57 stronger than their proof, 24 contradicted elsewhere), and what enters it is our judgement, derived by no gate. 13.4 Not in place: any third-party security audit (our internal report says in terms that it is not one), any penetration test, any certification against any standard, a signed confidentiality undertaking, background checks, security training, and the host-access items in 4.5. 14. Physical security 14.1 Physical and environmental security is relied on from the infrastructure providers: Hetzner Online GmbH for the three hosts and for the backup destination (10.1), and the Backoffice providers in Frankfurt. We hold no datacentre controls of our own, have inspected no facility and have read none of those providers' certificates or reports; 0.1 applies to them. 14.2 What is ours is separation: the Receiver Host is in another country, the Witness and Fleet Hosts separate machines in one datacentre - a separation of estates, not of sites. 15. Change control over this annex 15.1 The Data Processing Agreement governs which version of this annex is in force, and nothing published here varies that Agreement. A new version is a new file with a new name at its own address, naming the digest of the version it replaces; the bytes are the artefact. The pairs inside the bytes your own key signs when you apply are the Terms' and the Agreement's, not this annex's, and no acceptance row exists in any database of ours yet. 15.2 A change to this annex follows clause 6.3 of dpa-1.0: we notify the Owners and Admins at least thirty days in advance, clause by clause and in which direction each changed; you may object within fourteen days on data protection grounds; and a change lowering a measure lets you terminate the affected Service without penalty, notice period or reason, with a pro-rata refund of prepaid fees, by writing to hello@tallwright.com, effective on receipt, and no written-form requirement elsewhere applies to that notice. Corrections are published with their reason, in either direction: understating a measure is as wrong as overstating one.